[PATCH v3 1/3] misc: fastrpc: iterate CB nodes manually instead of of_platform_populate
Vinayak Katoch <[email protected]>
| Newsgroups | org.freedesktop.lists.dri-devel,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
of_platform_populate() only guarantees that child devices are registered, not that their probes have completed before it returns. This creates a window where fastrpc_cb_init() may not have run for all context bank nodes, leaving the channel context partially initialised. Iterate over the child device tree nodes directly, initialising each qcom,fastrpc-compute-cb device synchronously. This ensures all context banks are fully initialised before fastrpc_rpmsg_probe() returns. Since fastrpc_cb_driver is no longer needed as an independent platform driver, remove it along with its match table and remove callback. Set OF_POPULATED_BUS on the rpmsg node so that of_platform_depopulate() correctly removes the manually created CB devices on teardown. Signed-off-by: Vinayak Katoch <[email protected]> --- drivers/misc/fastrpc.c | 82 ++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 53 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 1080f9acf70a..fe127bb0c115 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2190,7 +2190,7 @@ static const struct file_operations fastrpc_fops = { .compat_ioctl = fastrpc_device_ioctl, }; -static int fastrpc_cb_probe(struct platform_device *pdev) +static int fastrpc_cb_init(struct platform_device *pdev) { struct fastrpc_channel_ctx *cctx; struct fastrpc_session_ctx *sess; @@ -2208,7 +2208,7 @@ static int fastrpc_cb_probe(struct platform_device *pdev) spin_lock_irqsave(&cctx->lock, flags); if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) { - dev_err(&pdev->dev, "too many sessions\n"); + dev_err(dev, "too many sessions\n"); spin_unlock_irqrestore(&cctx->lock, flags); return -ENOSPC; } @@ -2245,37 +2245,6 @@ static int fastrpc_cb_probe(struct platform_device *pdev) return 0; } -static void fastrpc_cb_remove(struct platform_device *pdev) -{ - struct fastrpc_channel_ctx *cctx = dev_get_drvdata(pdev->dev.parent); - struct fastrpc_session_ctx *sess = dev_get_drvdata(&pdev->dev); - unsigned long flags; - int i; - - spin_lock_irqsave(&cctx->lock, flags); - for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) { - if (cctx->session[i].sid == sess->sid) { - cctx->session[i].valid = false; - cctx->sesscount--; - } - } - spin_unlock_irqrestore(&cctx->lock, flags); -} - -static const struct of_device_id fastrpc_match_table[] = { - { .compatible = "qcom,fastrpc-compute-cb", }, - {} -}; - -static struct platform_driver fastrpc_cb_driver = { - .probe = fastrpc_cb_probe, - .remove = fastrpc_cb_remove, - .driver = { - .name = "qcom,fastrpc-cb", - .of_match_table = fastrpc_match_table, - .suppress_bind_attrs = true, - }, -}; static int fastrpc_device_register(struct device *dev, struct fastrpc_channel_ctx *cctx, bool is_secured, const char *domain) @@ -2441,12 +2410,29 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) data->domain_id = domain_id; data->rpdev = rpdev; - err = of_platform_populate(rdev->of_node, NULL, NULL, rdev); - if (err) - goto err_deregister_fdev; + of_node_set_flag(rdev->of_node, OF_POPULATED_BUS); + + for_each_available_child_of_node_scoped(rdev->of_node, np) { + struct platform_device *pdev; + + if (!of_device_is_compatible(np, "qcom,fastrpc-compute-cb")) + continue; + + pdev = of_platform_device_create(np, NULL, rdev); + if (!pdev) { + err = -EINVAL; + goto err_depopulate; + } + + err = fastrpc_cb_init(pdev); + if (err) + goto err_depopulate; + } return 0; +err_depopulate: + of_platform_depopulate(rdev); err_deregister_fdev: if (data->fdevice) misc_deregister(&data->fdevice->miscdev); @@ -2476,6 +2462,7 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) struct fastrpc_buf *buf, *b; struct fastrpc_user *user; unsigned long flags; + int i; /* No invocations past this point */ spin_lock_irqsave(&cctx->lock, flags); @@ -2496,6 +2483,11 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) if (cctx->remote_heap) fastrpc_buf_free(cctx->remote_heap); + spin_lock_irqsave(&cctx->lock, flags); + for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) + cctx->session[i].valid = false; + spin_unlock_irqrestore(&cctx->lock, flags); + of_platform_depopulate(&rpdev->dev); fastrpc_channel_ctx_put(cctx); @@ -2556,28 +2548,12 @@ static struct rpmsg_driver fastrpc_driver = { static int fastrpc_init(void) { - int ret; - - ret = platform_driver_register(&fastrpc_cb_driver); - if (ret < 0) { - pr_err("fastrpc: failed to register cb driver\n"); - return ret; - } - - ret = register_rpmsg_driver(&fastrpc_driver); - if (ret < 0) { - pr_err("fastrpc: failed to register rpmsg driver\n"); - platform_driver_unregister(&fastrpc_cb_driver); - return ret; - } - - return 0; + return register_rpmsg_driver(&fastrpc_driver); } module_init(fastrpc_init); static void fastrpc_exit(void) { - platform_driver_unregister(&fastrpc_cb_driver); unregister_rpmsg_driver(&fastrpc_driver); } module_exit(fastrpc_exit); -- 2.34.1