summaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2016-10-03 02:46:39 +0200
committerBjorn Andersson <bjorn.andersson@linaro.org>2016-10-03 07:50:22 +0200
commitfbb6aacb078285f88e4a4a20399c6af8d61e0000 (patch)
treebdec6ae8cb1d4d1c786c84335df7bb8760494dc8 /drivers/remoteproc
parentremoteproc: Split driver and consumer dereferencing (diff)
downloadlinux-fbb6aacb078285f88e4a4a20399c6af8d61e0000.tar.xz
linux-fbb6aacb078285f88e4a4a20399c6af8d61e0000.zip
remoteproc: Refactor rproc module locking
Lock the implementation as we hand out references to client drivers rather than when they try to boot the remote processor. This allows auto-booting remote processors to be shut down by unloading their module, in addition to first unbinding them. Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r--drivers/remoteproc/remoteproc_core.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index ede3af14b9d0..c6bfb3496684 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1035,13 +1035,6 @@ static int __rproc_boot(struct rproc *rproc, bool wait)
return ret;
}
- /* prevent underlying implementation from being removed */
- if (!try_module_get(dev->parent->driver->owner)) {
- dev_err(dev, "%s: can't get owner\n", __func__);
- ret = -EINVAL;
- goto unlock_mutex;
- }
-
/* skip the boot process if rproc is already powered up */
if (atomic_inc_return(&rproc->power) > 1) {
ret = 0;
@@ -1066,10 +1059,8 @@ static int __rproc_boot(struct rproc *rproc, bool wait)
release_firmware(firmware_p);
downref_rproc:
- if (ret) {
- module_put(dev->parent->driver->owner);
+ if (ret)
atomic_dec(&rproc->power);
- }
unlock_mutex:
mutex_unlock(&rproc->lock);
return ret;
@@ -1158,8 +1149,6 @@ void rproc_shutdown(struct rproc *rproc)
out:
mutex_unlock(&rproc->lock);
- if (!ret)
- module_put(dev->parent->driver->owner);
}
EXPORT_SYMBOL(rproc_shutdown);
@@ -1188,6 +1177,12 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
mutex_lock(&rproc_list_mutex);
list_for_each_entry(r, &rproc_list, node) {
if (r->dev.parent && r->dev.parent->of_node == np) {
+ /* prevent underlying implementation from being removed */
+ if (!try_module_get(r->dev.parent->driver->owner)) {
+ dev_err(&r->dev, "can't get owner\n");
+ break;
+ }
+
rproc = r;
get_device(&rproc->dev);
break;
@@ -1411,6 +1406,7 @@ EXPORT_SYMBOL(rproc_free);
*/
void rproc_put(struct rproc *rproc)
{
+ module_put(rproc->dev.parent->driver->owner);
put_device(&rproc->dev);
}
EXPORT_SYMBOL(rproc_put);