rproc_shutdown() rejects a remoteproc in RPROC_CRASHED state, and
rproc_del() ignores that error. The result of these two decisions is
that a user cannot stop a remoteproc that with recovery disabled that
has entered a crash state, and removal of an associated remoteproc
driver will release resources without first stopping the remoteproc.

Allow rproc_shutdown() to stop crashed processors. Propagate the crash
state to subdevice teardown, to allow subdevices to dismantle things
appropriately.

Assisted-by: OpenCode:GPT-5.5
Fixes: 5e6a0e05270e ("remoteproc: core: Move state checking to remoteproc_core")
Signed-off-by: Bjorn Andersson <[email protected]>
---
 drivers/remoteproc/remoteproc_core.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c 
b/drivers/remoteproc/remoteproc_core.c
index 0583d3a56212..3cd4570513c2 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -2002,6 +2002,7 @@ EXPORT_SYMBOL(rproc_boot);
 int rproc_shutdown(struct rproc *rproc)
 {
        struct device *dev = &rproc->dev;
+       bool crashed;
        int ret;
 
        ret = mutex_lock_interruptible(&rproc->lock);
@@ -2011,16 +2012,18 @@ int rproc_shutdown(struct rproc *rproc)
        }
 
        if (rproc->state != RPROC_RUNNING &&
-           rproc->state != RPROC_ATTACHED) {
+           rproc->state != RPROC_ATTACHED &&
+           rproc->state != RPROC_CRASHED) {
                ret = -EINVAL;
                goto out;
        }
+       crashed = rproc->state == RPROC_CRASHED;
 
        /* if the remote proc is still needed, bail out */
        if (!atomic_dec_and_test(&rproc->power))
                goto out;
 
-       ret = rproc_stop(rproc, false);
+       ret = rproc_stop(rproc, crashed);
        if (ret) {
                atomic_inc(&rproc->power);
                goto out;

-- 
2.53.0


Reply via email to