Message ID | 20201126210642.897302-12-mathieu.poirier@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | remoteproc: Add support for detaching from rproc | expand |
On 11/26/20 10:06 PM, Mathieu Poirier wrote: > Add a return value to function rproc_shutdown() in order to > properly deal with error conditions that may occur. > > Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> > Reviewed-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Arnaud Pouliquen <arnaud.pouliquen@st.com> Thanks, Arnaud > --- > drivers/remoteproc/remoteproc_core.c | 19 ++++++++++++++----- > include/linux/remoteproc.h | 2 +- > 2 files changed, 15 insertions(+), 6 deletions(-) > > diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c > index b54f60cc3cbd..51275107eb1f 100644 > --- a/drivers/remoteproc/remoteproc_core.c > +++ b/drivers/remoteproc/remoteproc_core.c > @@ -1869,7 +1869,7 @@ EXPORT_SYMBOL(rproc_boot); > * returns, and users can still use it with a subsequent rproc_boot(), if > * needed. > */ > -void rproc_shutdown(struct rproc *rproc) > +int rproc_shutdown(struct rproc *rproc) > { > struct device *dev = &rproc->dev; > int ret; > @@ -1877,15 +1877,19 @@ void rproc_shutdown(struct rproc *rproc) > ret = mutex_lock_interruptible(&rproc->lock); > if (ret) { > dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); > - return; > + return ret; > } > > - if (rproc->state != RPROC_RUNNING) > + if (rproc->state != RPROC_RUNNING) { > + ret = -EPERM; > goto out; > + } > > /* if the remote proc is still needed, bail out */ > - if (!atomic_dec_and_test(&rproc->power)) > + if (!atomic_dec_and_test(&rproc->power)) { > + ret = -EBUSY; > goto out; > + } > > ret = rproc_stop(rproc, false); > if (ret) { > @@ -1897,7 +1901,11 @@ void rproc_shutdown(struct rproc *rproc) > rproc_resource_cleanup(rproc); > > /* release HW resources if needed */ > - rproc_unprepare_device(rproc); > + ret = rproc_unprepare_device(rproc); > + if (ret) { > + atomic_inc(&rproc->power); > + goto out; > + } > > rproc_disable_iommu(rproc); > > @@ -1907,6 +1915,7 @@ void rproc_shutdown(struct rproc *rproc) > rproc->table_ptr = NULL; > out: > mutex_unlock(&rproc->lock); > + return ret; > } > EXPORT_SYMBOL(rproc_shutdown); > > diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h > index 329c1c071dcf..02312096d59f 100644 > --- a/include/linux/remoteproc.h > +++ b/include/linux/remoteproc.h > @@ -655,7 +655,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, > u32 da, const char *name, ...); > > int rproc_boot(struct rproc *rproc); > -void rproc_shutdown(struct rproc *rproc); > +int rproc_shutdown(struct rproc *rproc); > int rproc_detach(struct rproc *rproc); > int rproc_set_firmware(struct rproc *rproc, const char *fw_name); > void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); >
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index b54f60cc3cbd..51275107eb1f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1869,7 +1869,7 @@ EXPORT_SYMBOL(rproc_boot); * returns, and users can still use it with a subsequent rproc_boot(), if * needed. */ -void rproc_shutdown(struct rproc *rproc) +int rproc_shutdown(struct rproc *rproc) { struct device *dev = &rproc->dev; int ret; @@ -1877,15 +1877,19 @@ void rproc_shutdown(struct rproc *rproc) ret = mutex_lock_interruptible(&rproc->lock); if (ret) { dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); - return; + return ret; } - if (rproc->state != RPROC_RUNNING) + if (rproc->state != RPROC_RUNNING) { + ret = -EPERM; goto out; + } /* if the remote proc is still needed, bail out */ - if (!atomic_dec_and_test(&rproc->power)) + if (!atomic_dec_and_test(&rproc->power)) { + ret = -EBUSY; goto out; + } ret = rproc_stop(rproc, false); if (ret) { @@ -1897,7 +1901,11 @@ void rproc_shutdown(struct rproc *rproc) rproc_resource_cleanup(rproc); /* release HW resources if needed */ - rproc_unprepare_device(rproc); + ret = rproc_unprepare_device(rproc); + if (ret) { + atomic_inc(&rproc->power); + goto out; + } rproc_disable_iommu(rproc); @@ -1907,6 +1915,7 @@ void rproc_shutdown(struct rproc *rproc) rproc->table_ptr = NULL; out: mutex_unlock(&rproc->lock); + return ret; } EXPORT_SYMBOL(rproc_shutdown); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 329c1c071dcf..02312096d59f 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -655,7 +655,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, u32 da, const char *name, ...); int rproc_boot(struct rproc *rproc); -void rproc_shutdown(struct rproc *rproc); +int rproc_shutdown(struct rproc *rproc); int rproc_detach(struct rproc *rproc); int rproc_set_firmware(struct rproc *rproc, const char *fw_name); void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);