SCP core 1 driver probing must finish before start loading SCP core 1 image. Add a simple flag checking mechanism when preparing SCP core 1 subdevice. Signed-off-by: Tinghan Shen <tinghan.shen@xxxxxxxxxxxx> --- drivers/remoteproc/mtk_common.h | 1 + drivers/remoteproc/mtk_scp_dual.c | 2 ++ drivers/remoteproc/mtk_scp_subdev.c | 35 ++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h index a5c26e56277d..464d013ed6b2 100644 --- a/drivers/remoteproc/mtk_common.h +++ b/drivers/remoteproc/mtk_common.h @@ -153,6 +153,7 @@ struct mtk_scp { struct rproc_subdev *rpmsg_subdev; struct rproc_subdev *dual_subdev; + int dual_probe_done; }; /** diff --git a/drivers/remoteproc/mtk_scp_dual.c b/drivers/remoteproc/mtk_scp_dual.c index 90c49716dd39..ab62ab54175c 100644 --- a/drivers/remoteproc/mtk_scp_dual.c +++ b/drivers/remoteproc/mtk_scp_dual.c @@ -266,6 +266,8 @@ static int scp_dual_probe(struct platform_device *pdev) if (ret) goto remove_ipi; + scp->dual_probe_done = 1; + return 0; remove_ipi: diff --git a/drivers/remoteproc/mtk_scp_subdev.c b/drivers/remoteproc/mtk_scp_subdev.c index 197fb207c756..71dc6fcad61a 100644 --- a/drivers/remoteproc/mtk_scp_subdev.c +++ b/drivers/remoteproc/mtk_scp_subdev.c @@ -20,6 +20,7 @@ static struct mtk_scp *scp_dual_get(struct mtk_scp *scp) struct device *dev = scp->dev; struct device_node *np; struct platform_device *dual_pdev; + struct mtk_scp *scp_dual; np = of_parse_phandle(dev->of_node, "mediatek,scp-core", SCP_DTS_CORE_REF); dual_pdev = of_find_device_by_node(np); @@ -30,7 +31,11 @@ static struct mtk_scp *scp_dual_get(struct mtk_scp *scp) return NULL; } - return platform_get_drvdata(dual_pdev); + scp_dual = platform_get_drvdata(dual_pdev); + if (!scp_dual) + put_device(&dual_pdev->dev); + + return scp_dual; } static void scp_dual_put(struct mtk_scp *scp) @@ -38,6 +43,33 @@ static void scp_dual_put(struct mtk_scp *scp) put_device(scp->dev); } +static int scp_dual_rproc_prepare(struct rproc_subdev *subdev) +{ + struct scp_subdev_core *subdev_core = to_subdev_core(subdev); + struct mtk_scp *scp = subdev_core->main_scp; + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(100); + while (1) { + struct mtk_scp *scp_dual = scp_dual_get(scp); + + if (scp_dual && scp_dual->dual_probe_done) { + scp_dual_put(scp_dual); + break; + } + + if (scp_dual && !scp_dual->dual_probe_done) + scp_dual_put(scp_dual); + + if (time_after(jiffies, timeout)) { + dev_err(scp->dev, "scp-dual probe timeout\n"); + return -ETIMEDOUT; + } + } + + return 0; +} + static int scp_dual_rproc_start(struct rproc_subdev *subdev) { struct scp_subdev_core *subdev_core = to_subdev_core(subdev); @@ -111,6 +143,7 @@ struct rproc_subdev *scp_dual_create_subdev(struct mtk_scp *scp) subdev_core->main_scp = scp; subdev_core->scp_dual_wdt_timeout = scp_dual_wdt_handler; + subdev_core->subdev.prepare = scp_dual_rproc_prepare; subdev_core->subdev.start = scp_dual_rproc_start; subdev_core->subdev.stop = scp_dual_rproc_stop; -- 2.18.0