video: rockchip: mpp: Fix panic when mpp service is omit or disabled

[    4.239358] Unable to handle kernel NULL pointer dereference at virtual address 00000050
[    4.263110] pgd = (ptrval)
[    4.269464] [00000050] *pgd=00000000
[    4.285610] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[    4.291283] Modules linked in:
[    4.294795] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.111 #1960
[    4.301399] Hardware name: Generic DT based system
[    4.306660] PC is at mpp_set_grf+0x8/0x3c
[    4.311054] LR is at mpp_add_driver+0x24/0x44
[    4.315713] pc : [<b03d7b44>]    lr : [<b03d50d8>]    psr: 20000153
[    4.322250] sp : bf039ee8  ip : 00000d8c  fp : bf7ffd80
[    4.327740] r10: b0b3003c  r9 : 00000007  r8 : 00000000
[    4.333260] r7 : b0b15914  r6 : b0f21788  r5 : 00000006  r4 : b1022a2c
[    4.340094] r3 : 00000048  r2 : bf5d1e24  r1 : b0f21788  r0 : 00000048
[    4.346947] Flags: nzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment user
[    4.354487] Control: 10c5387d  Table: 6000406a  DAC: 00000055

Change-Id: Idad72d462da59a8af53fd038ceda973da1f4139d
Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Sugar Zhang
2020-06-27 18:29:35 +08:00
committed by Tao Huang
parent 2fa88ab89a
commit cee61f3e32
5 changed files with 58 additions and 87 deletions

View File

@@ -768,15 +768,13 @@ static int mpp_attach_service(struct mpp_dev *mpp, struct device *dev)
goto err_put_pdev;
}
device_lock(&pdev->dev);
/* register current device to mpp service */
mpp->srv->sub_devices[mpp->var->device_type] = mpp;
/* set taskqueue which set in dtsi */
mpp->queue = mpp->srv->task_queues[taskqueue_node];
/* set resetgroup which set in dtsi */
mpp->reset_group = mpp->srv->reset_groups[reset_group_node];
mpp->srv->hw_support |= BIT(mpp->var->device_type);
device_unlock(&pdev->dev);
set_bit(mpp->var->device_type, &mpp->srv->hw_support);
return 0;

View File

@@ -342,7 +342,7 @@ struct mpp_service {
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 hw_support;
unsigned long hw_support;
atomic_t shutdown_request;
/* follows for device probe */
struct mpp_grf_info grf_infos[MPP_DRIVER_BUTT];

View File

@@ -25,26 +25,18 @@
#define MPP_CLASS_NAME "mpp_class"
#define MPP_SERVICE_NAME "mpp_service"
#define MPP_REGISTER_GRF(np, X, x) {\
#define MPP_REGISTER_DRIVER(srv, X, x) {\
if (IS_ENABLED(CONFIG_ROCKCHIP_MPP_##X))\
mpp_init_grf(np, &srv->grf_infos[MPP_DRIVER_##X], x);\
}
#define MPP_REGISTER_DRIVER(X, x) {\
if (IS_ENABLED(CONFIG_ROCKCHIP_MPP_##X))\
mpp_add_driver(MPP_DRIVER_##X, &rockchip_##x##_driver);\
mpp_add_driver(srv, MPP_DRIVER_##X, &rockchip_##x##_driver, "grf_"#x);\
}
unsigned int mpp_dev_debug;
module_param(mpp_dev_debug, uint, 0644);
MODULE_PARM_DESC(mpp_dev_debug, "bit switch for mpp debug information");
static struct mpp_grf_info *mpp_grf_infos;
static struct platform_driver **mpp_sub_drivers;
static int mpp_init_grf(struct device_node *np,
struct mpp_grf_info *grf_info,
const char *name)
const char *grf_name)
{
int ret;
int index;
@@ -60,7 +52,7 @@ static int mpp_init_grf(struct device_node *np,
if (ret)
return -ENODATA;
index = of_property_match_string(np, "rockchip,grf-names", name);
index = of_property_match_string(np, "rockchip,grf-names", grf_name);
if (index < 0)
return -ENODATA;
@@ -73,6 +65,39 @@ static int mpp_init_grf(struct device_node *np,
grf_info->offset = grf_offset;
grf_info->val = grf_value;
mpp_set_grf(grf_info);
return 0;
}
static int mpp_add_driver(struct mpp_service *srv,
enum MPP_DRIVER_TYPE type,
struct platform_driver *driver,
const char *grf_name)
{
int ret;
mpp_init_grf(srv->dev->of_node,
&srv->grf_infos[type],
grf_name);
ret = platform_driver_register(driver);
if (ret)
return ret;
srv->sub_drivers[type] = driver;
return 0;
}
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]);
srv->sub_drivers[i] = NULL;
}
return 0;
}
@@ -208,23 +233,24 @@ static int mpp_service_probe(struct platform_device *pdev)
srv->reset_groups[i] = group;
}
}
MPP_REGISTER_GRF(np, RKVDEC, "grf_rkvdec");
MPP_REGISTER_GRF(np, RKVENC, "grf_rkvenc");
MPP_REGISTER_GRF(np, VEPU1, "grf_vepu1");
MPP_REGISTER_GRF(np, VDPU1, "grf_vdpu1");
MPP_REGISTER_GRF(np, VEPU2, "grf_vepu2");
MPP_REGISTER_GRF(np, VDPU2, "grf_vdpu2");
MPP_REGISTER_GRF(np, VEPU22, "grf_vepu22");
mpp_grf_infos = srv->grf_infos;
ret = mpp_register_service(srv, MPP_SERVICE_NAME);
if (ret) {
dev_err(dev, "register %s device\n", MPP_SERVICE_NAME);
goto fail_register;
}
mpp_sub_drivers = srv->sub_drivers;
mpp_debugfs_init(srv);
/* register sub drivers */
MPP_REGISTER_DRIVER(srv, RKVDEC, rkvdec);
MPP_REGISTER_DRIVER(srv, RKVENC, rkvenc);
MPP_REGISTER_DRIVER(srv, VDPU1, vdpu1);
MPP_REGISTER_DRIVER(srv, VEPU1, vepu1);
MPP_REGISTER_DRIVER(srv, VDPU2, vdpu2);
MPP_REGISTER_DRIVER(srv, VEPU2, vepu2);
MPP_REGISTER_DRIVER(srv, VEPU22, vepu22);
MPP_REGISTER_DRIVER(srv, IEP2, iep2);
dev_info(dev, "probe success\n");
return 0;
@@ -239,9 +265,14 @@ static int mpp_service_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mpp_service *srv = platform_get_drvdata(pdev);
int i;
dev_info(dev, "remove device\n");
/* remove sub drivers */
for (i = 0; i < MPP_DRIVER_BUTT; i++)
mpp_remove_driver(srv, i);
mpp_remove_service(srv);
class_destroy(srv->cls);
mpp_debugfs_remove(srv);
@@ -265,65 +296,7 @@ static struct platform_driver mpp_service_driver = {
},
};
static int mpp_add_driver(enum MPP_DRIVER_TYPE type,
struct platform_driver *driver)
{
int ret;
mpp_set_grf(&mpp_grf_infos[type]);
ret = platform_driver_register(driver);
if (ret)
return ret;
mpp_sub_drivers[type] = driver;
return 0;
}
static int mpp_remove_driver(int i, struct platform_driver *driver)
{
if (driver) {
mpp_set_grf(&mpp_grf_infos[i]);
platform_driver_unregister(driver);
}
return 0;
}
static int __init mpp_service_init(void)
{
int ret;
ret = platform_driver_register(&mpp_service_driver);
if (ret) {
pr_err("Mpp service device register failed (%d).\n", ret);
return ret;
}
MPP_REGISTER_DRIVER(RKVDEC, rkvdec);
MPP_REGISTER_DRIVER(RKVENC, rkvenc);
MPP_REGISTER_DRIVER(VDPU1, vdpu1);
MPP_REGISTER_DRIVER(VEPU1, vepu1);
MPP_REGISTER_DRIVER(VDPU2, vdpu2);
MPP_REGISTER_DRIVER(VEPU2, vepu2);
MPP_REGISTER_DRIVER(VEPU22, vepu22);
MPP_REGISTER_DRIVER(IEP2, iep2);
return 0;
}
static void __exit mpp_service_exit(void)
{
int i;
for (i = 0; i < MPP_DRIVER_BUTT; i++)
mpp_remove_driver(i, mpp_sub_drivers[i]);
platform_driver_unregister(&mpp_service_driver);
}
module_init(mpp_service_init);
module_exit(mpp_service_exit);
module_platform_driver(mpp_service_driver);
MODULE_LICENSE("Dual MIT/GPL");
MODULE_VERSION("1.0.build.201911131848");

View File

@@ -825,7 +825,7 @@ static int vdpu_probe(struct platform_device *pdev)
if (mpp->var->device_type == MPP_DEVICE_VDPU1) {
mpp->srv->sub_devices[MPP_DEVICE_VDPU1_PP] = mpp;
mpp->srv->hw_support |= BIT(MPP_DEVICE_VDPU1_PP);
set_bit(MPP_DEVICE_VDPU1_PP, &mpp->srv->hw_support);
}
mpp->session_max_buffers = VDPU1_SESSION_MAX_BUFFERS;

View File

@@ -723,7 +723,7 @@ static int vdpu_probe(struct platform_device *pdev)
if (mpp->var->device_type == MPP_DEVICE_VDPU2) {
mpp->srv->sub_devices[MPP_DEVICE_VDPU2_PP] = mpp;
mpp->srv->hw_support |= BIT(MPP_DEVICE_VDPU2_PP);
set_bit(MPP_DEVICE_VDPU2_PP, &mpp->srv->hw_support);
}
mpp->session_max_buffers = VDPU2_SESSION_MAX_BUFFERS;