Commit fbb6aacb authored by Bjorn Andersson's avatar Bjorn Andersson

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: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 433c0e04
...@@ -1035,13 +1035,6 @@ static int __rproc_boot(struct rproc *rproc, bool wait) ...@@ -1035,13 +1035,6 @@ static int __rproc_boot(struct rproc *rproc, bool wait)
return ret; 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 */ /* skip the boot process if rproc is already powered up */
if (atomic_inc_return(&rproc->power) > 1) { if (atomic_inc_return(&rproc->power) > 1) {
ret = 0; ret = 0;
...@@ -1066,10 +1059,8 @@ static int __rproc_boot(struct rproc *rproc, bool wait) ...@@ -1066,10 +1059,8 @@ static int __rproc_boot(struct rproc *rproc, bool wait)
release_firmware(firmware_p); release_firmware(firmware_p);
downref_rproc: downref_rproc:
if (ret) { if (ret)
module_put(dev->parent->driver->owner);
atomic_dec(&rproc->power); atomic_dec(&rproc->power);
}
unlock_mutex: unlock_mutex:
mutex_unlock(&rproc->lock); mutex_unlock(&rproc->lock);
return ret; return ret;
...@@ -1158,8 +1149,6 @@ void rproc_shutdown(struct rproc *rproc) ...@@ -1158,8 +1149,6 @@ void rproc_shutdown(struct rproc *rproc)
out: out:
mutex_unlock(&rproc->lock); mutex_unlock(&rproc->lock);
if (!ret)
module_put(dev->parent->driver->owner);
} }
EXPORT_SYMBOL(rproc_shutdown); EXPORT_SYMBOL(rproc_shutdown);
...@@ -1188,6 +1177,12 @@ struct rproc *rproc_get_by_phandle(phandle phandle) ...@@ -1188,6 +1177,12 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
mutex_lock(&rproc_list_mutex); mutex_lock(&rproc_list_mutex);
list_for_each_entry(r, &rproc_list, node) { list_for_each_entry(r, &rproc_list, node) {
if (r->dev.parent && r->dev.parent->of_node == np) { 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; rproc = r;
get_device(&rproc->dev); get_device(&rproc->dev);
break; break;
...@@ -1411,6 +1406,7 @@ EXPORT_SYMBOL(rproc_free); ...@@ -1411,6 +1406,7 @@ EXPORT_SYMBOL(rproc_free);
*/ */
void rproc_put(struct rproc *rproc) void rproc_put(struct rproc *rproc)
{ {
module_put(rproc->dev.parent->driver->owner);
put_device(&rproc->dev); put_device(&rproc->dev);
} }
EXPORT_SYMBOL(rproc_put); EXPORT_SYMBOL(rproc_put);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment