Refactor function rproc_boot() to properly deal with scenarios
where the remoteproc core needs to attach with a remote
processor that has already been booted by an external entity.

Signed-off-by: Mathieu Poirier <mathieu.poir...@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.anders...@linaro.org>
Tested-by: Arnaud Pouliquen <arnaud.pouliq...@st.com>
---
 drivers/remoteproc/remoteproc_core.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index ad500c291d5f..caea920ce4b8 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1494,7 +1494,7 @@ static int rproc_fw_boot(struct rproc *rproc, const 
struct firmware *fw)
  * Attach to remote processor - similar to rproc_fw_boot() but without
  * the steps that deal with the firmware image.
  */
-static int __maybe_unused rproc_actuate(struct rproc *rproc)
+static int rproc_actuate(struct rproc *rproc)
 {
        struct device *dev = &rproc->dev;
        int ret;
@@ -1905,24 +1905,30 @@ int rproc_boot(struct rproc *rproc)
                goto unlock_mutex;
        }
 
-       /* skip the boot process if rproc is already powered up */
+       /* skip the boot or attach process if rproc is already powered up */
        if (atomic_inc_return(&rproc->power) > 1) {
                ret = 0;
                goto unlock_mutex;
        }
 
-       dev_info(dev, "powering up %s\n", rproc->name);
+       if (rproc->state == RPROC_DETACHED) {
+               dev_info(dev, "attaching to %s\n", rproc->name);
 
-       /* load firmware */
-       ret = request_firmware(&firmware_p, rproc->firmware, dev);
-       if (ret < 0) {
-               dev_err(dev, "request_firmware failed: %d\n", ret);
-               goto downref_rproc;
-       }
+               ret = rproc_actuate(rproc);
+       } else {
+               dev_info(dev, "powering up %s\n", rproc->name);
 
-       ret = rproc_fw_boot(rproc, firmware_p);
+               /* load firmware */
+               ret = request_firmware(&firmware_p, rproc->firmware, dev);
+               if (ret < 0) {
+                       dev_err(dev, "request_firmware failed: %d\n", ret);
+                       goto downref_rproc;
+               }
 
-       release_firmware(firmware_p);
+               ret = rproc_fw_boot(rproc, firmware_p);
+
+               release_firmware(firmware_p);
+       }
 
 downref_rproc:
        if (ret)
-- 
2.25.1

Reply via email to