mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
video: rockchip: mpp: Improve the exit process of the av1
Signed-off-by: Yandong Lin <yandong.lin@rock-chips.com> Change-Id: Idbb73bf2b08dc879a7776180420060b9b740a31e Signed-off-by: Simon Xue <xxm@rock-chips.com>
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "mpp_av1dec: " fmt
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk/clk-conf.h>
|
||||
@@ -16,8 +18,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/clk/clk-conf.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/regmap.h>
|
||||
@@ -28,7 +31,7 @@
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_iommu.h"
|
||||
|
||||
#define AV1DEC_DRIVER_NAME "mpp_av1dec"
|
||||
#define AV1DEC_DRIVER_NAME "mpp_av1dec"
|
||||
|
||||
#define AV1DEC_SESSION_MAX_BUFFERS 40
|
||||
|
||||
@@ -1098,7 +1101,7 @@ static int av1_of_device_add(struct platform_device *ofdev)
|
||||
return device_add(&ofdev->dev);
|
||||
}
|
||||
|
||||
struct platform_device *av1dec_device_create(void)
|
||||
static struct platform_device *av1dec_device_create(void)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
struct device_node *root, *child;
|
||||
@@ -1134,6 +1137,35 @@ struct platform_device *av1dec_device_create(void)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void av1dec_device_destory(void)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device_by_name(&av1dec_bus, NULL, "av1d-master");
|
||||
pdev = dev ? to_platform_device(dev) : NULL;
|
||||
if (!pdev) {
|
||||
pr_err("cannot find platform device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("destroy device %s\n", dev_name(&pdev->dev));
|
||||
platform_device_del(pdev);
|
||||
platform_device_put(pdev);
|
||||
}
|
||||
|
||||
void av1dec_driver_unregister(struct platform_driver *drv)
|
||||
{
|
||||
/* 1. unregister av1 driver */
|
||||
driver_unregister(&drv->driver);
|
||||
/* 2. release device */
|
||||
av1dec_device_destory();
|
||||
/* 3. unregister iommu driver */
|
||||
platform_driver_unregister(&rockchip_av1_iommu_driver);
|
||||
/* 4. unregister bus */
|
||||
bus_unregister(&av1dec_bus);
|
||||
}
|
||||
|
||||
int av1dec_driver_register(struct platform_driver *drv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -837,8 +837,8 @@ extern struct platform_driver rockchip_rkvenc2_driver;
|
||||
extern struct platform_driver rockchip_av1dec_driver;
|
||||
extern struct platform_driver rockchip_av1_iommu_driver;
|
||||
|
||||
extern struct platform_device *av1dec_device_create(void);
|
||||
extern int av1dec_driver_register(struct platform_driver *drv);
|
||||
extern void av1dec_driver_unregister(struct platform_driver *drv);
|
||||
extern struct bus_type av1dec_bus;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -713,6 +713,10 @@ static struct iommu_device *av1_iommu_probe_device(struct device *dev)
|
||||
pr_info("%s,%d, consumer : %s, supplier : %s\n",
|
||||
__func__, __LINE__, dev_name(dev), dev_name(iommu->dev));
|
||||
|
||||
/*
|
||||
* link will free by platform_device_del(master) via
|
||||
* BUS_NOTIFY_REMOVED_DEVICE
|
||||
*/
|
||||
data->link = device_link_add(dev, iommu->dev,
|
||||
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
|
||||
|
||||
@@ -729,9 +733,10 @@ static struct iommu_device *av1_iommu_probe_device(struct device *dev)
|
||||
|
||||
static void av1_iommu_release_device(struct device *dev)
|
||||
{
|
||||
struct av1_iommudata *data = dev_iommu_priv_get(dev);
|
||||
const struct iommu_ops *ops = dev->bus->iommu_ops;
|
||||
|
||||
device_link_del(data->link);
|
||||
/* hack for rmmod */
|
||||
__module_get(ops->owner);
|
||||
}
|
||||
|
||||
static struct iommu_group *av1_iommu_device_group(struct device *dev)
|
||||
@@ -765,6 +770,14 @@ static int av1_iommu_of_xlate(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void av1_iommu_probe_finalize(struct device *dev)
|
||||
{
|
||||
const struct iommu_ops *ops = dev->bus->iommu_ops;
|
||||
|
||||
/* hack for rmmod */
|
||||
module_put(ops->owner);
|
||||
}
|
||||
|
||||
static struct iommu_ops av1_iommu_ops = {
|
||||
.domain_alloc = av1_iommu_domain_alloc,
|
||||
.domain_free = av1_iommu_domain_free,
|
||||
@@ -780,6 +793,7 @@ static struct iommu_ops av1_iommu_ops = {
|
||||
.device_group = av1_iommu_device_group,
|
||||
.pgsize_bitmap = AV1_IOMMU_PGSIZE_BITMAP,
|
||||
.of_xlate = av1_iommu_of_xlate,
|
||||
.probe_finalize = av1_iommu_probe_finalize,
|
||||
};
|
||||
|
||||
static const struct of_device_id av1_iommu_dt_ids[] = {
|
||||
@@ -891,6 +905,17 @@ err_unprepare_clocks:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int av1_iommu_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct av1_iommu *iommu = platform_get_drvdata(pdev);
|
||||
|
||||
iommu_device_unregister(&iommu->iommu);
|
||||
iommu_device_sysfs_remove(&iommu->iommu);
|
||||
pm_runtime_disable(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void av1_iommu_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct av1_iommu *iommu = platform_get_drvdata(pdev);
|
||||
@@ -934,6 +959,7 @@ static const struct dev_pm_ops av1_iommu_pm_ops = {
|
||||
|
||||
struct platform_driver rockchip_av1_iommu_driver = {
|
||||
.probe = av1_iommu_probe,
|
||||
.remove = av1_iommu_remove,
|
||||
.shutdown = av1_iommu_shutdown,
|
||||
.driver = {
|
||||
.name = "av1_iommu",
|
||||
|
||||
@@ -113,8 +113,14 @@ static int mpp_add_driver(struct mpp_service *srv,
|
||||
static int mpp_remove_driver(struct mpp_service *srv, int i)
|
||||
{
|
||||
if (srv && srv->sub_drivers[i]) {
|
||||
mpp_set_grf(&srv->grf_infos[i]);
|
||||
platform_driver_unregister(srv->sub_drivers[i]);
|
||||
if (i != MPP_DRIVER_AV1DEC) {
|
||||
mpp_set_grf(&srv->grf_infos[i]);
|
||||
platform_driver_unregister(srv->sub_drivers[i]);
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_ROCKCHIP_MPP_AV1DEC)
|
||||
else
|
||||
av1dec_driver_unregister(srv->sub_drivers[i]);
|
||||
#endif
|
||||
srv->sub_drivers[i] = NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user