Skip to content

Commit a876a3a

Browse files
hiagofrancoUlf Hansson
authored andcommitted
remoteproc: imx_rproc: detect and attach to pre-booted remote cores
When the Cortex-M remote core is started and already running before Linux boots (typically by the Cortex-A bootloader using a command like bootaux), the current driver is unable to attach to it. This is because the driver only checks for remote cores running in different SCU partitions. However in this case, the M-core is in the same partition as Linux and is already powered up and running by the bootloader. This patch adds a check using dev_pm_genpd_is_on() to verify whether the M-core's power domains are already on. If all power domain devices are on, the driver assumes the M-core is running and proceed to attach to it. To accomplish this, we need to avoid passing any attach_data or flags to dev_pm_domain_attach_list(), allowing the platform device become a consumer of the power domain provider without changing its current state. During probe, also enable and sync the device runtime PM to make sure the power domains are correctly managed when the core is controlled by the kernel. Suggested-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Peng Fan <peng.fan@nxp.com> Signed-off-by: Hiago De Franco <hiago.franco@toradex.com> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> Link: https://lore.kernel.org/r/20250716194638.113115-1-hiagofranco@gmail.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 496deec commit a876a3a

1 file changed

Lines changed: 35 additions & 6 deletions

File tree

drivers/remoteproc/imx_rproc.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/of_reserved_mem.h>
1919
#include <linux/platform_device.h>
2020
#include <linux/pm_domain.h>
21+
#include <linux/pm_runtime.h>
2122
#include <linux/reboot.h>
2223
#include <linux/regmap.h>
2324
#include <linux/remoteproc.h>
@@ -890,10 +891,8 @@ static int imx_rproc_partition_notify(struct notifier_block *nb,
890891
static int imx_rproc_attach_pd(struct imx_rproc *priv)
891892
{
892893
struct device *dev = priv->dev;
893-
int ret;
894-
struct dev_pm_domain_attach_data pd_data = {
895-
.pd_flags = PD_FLAG_DEV_LINK_ON,
896-
};
894+
int ret, i;
895+
bool detached = true;
897896

898897
/*
899898
* If there is only one power-domain entry, the platform driver framework
@@ -902,8 +901,25 @@ static int imx_rproc_attach_pd(struct imx_rproc *priv)
902901
if (dev->pm_domain)
903902
return 0;
904903

905-
ret = dev_pm_domain_attach_list(dev, &pd_data, &priv->pd_list);
906-
return ret < 0 ? ret : 0;
904+
ret = dev_pm_domain_attach_list(dev, NULL, &priv->pd_list);
905+
if (ret < 0)
906+
return ret;
907+
/*
908+
* If all the power domain devices are already turned on, the remote
909+
* core is already powered up and running when the kernel booted (e.g.,
910+
* started by U-Boot's bootaux command). In this case attach to it.
911+
*/
912+
for (i = 0; i < ret; i++) {
913+
if (!dev_pm_genpd_is_on(priv->pd_list->pd_devs[i])) {
914+
detached = false;
915+
break;
916+
}
917+
}
918+
919+
if (detached)
920+
priv->rproc->state = RPROC_DETACHED;
921+
922+
return 0;
907923
}
908924

909925
static int imx_rproc_detect_mode(struct imx_rproc *priv)
@@ -1146,6 +1162,15 @@ static int imx_rproc_probe(struct platform_device *pdev)
11461162
}
11471163
}
11481164

1165+
if (dcfg->method == IMX_RPROC_SCU_API) {
1166+
pm_runtime_enable(dev);
1167+
ret = pm_runtime_resume_and_get(dev);
1168+
if (ret) {
1169+
dev_err(dev, "pm_runtime get failed: %d\n", ret);
1170+
goto err_put_clk;
1171+
}
1172+
}
1173+
11491174
ret = rproc_add(rproc);
11501175
if (ret) {
11511176
dev_err(dev, "rproc_add failed\n");
@@ -1171,6 +1196,10 @@ static void imx_rproc_remove(struct platform_device *pdev)
11711196
struct rproc *rproc = platform_get_drvdata(pdev);
11721197
struct imx_rproc *priv = rproc->priv;
11731198

1199+
if (priv->dcfg->method == IMX_RPROC_SCU_API) {
1200+
pm_runtime_disable(priv->dev);
1201+
pm_runtime_put(priv->dev);
1202+
}
11741203
clk_disable_unprepare(priv->clk);
11751204
rproc_del(rproc);
11761205
imx_rproc_put_scu(rproc);

0 commit comments

Comments
 (0)