diff options
author | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-10-02 20:46:39 -0400 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-10-03 01:50:22 -0400 |
commit | fbb6aacb078285f88e4a4a20399c6af8d61e0000 (patch) | |
tree | bdec6ae8cb1d4d1c786c84335df7bb8760494dc8 | |
parent | 433c0e04bc06da6d049c691a9ef238d61edb841c (diff) |
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>
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 20 |
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) | |||
1035 | return ret; | 1035 | return ret; |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | /* prevent underlying implementation from being removed */ | ||
1039 | if (!try_module_get(dev->parent->driver->owner)) { | ||
1040 | dev_err(dev, "%s: can't get owner\n", __func__); | ||
1041 | ret = -EINVAL; | ||
1042 | goto unlock_mutex; | ||
1043 | } | ||
1044 | |||
1045 | /* skip the boot process if rproc is already powered up */ | 1038 | /* skip the boot process if rproc is already powered up */ |
1046 | if (atomic_inc_return(&rproc->power) > 1) { | 1039 | if (atomic_inc_return(&rproc->power) > 1) { |
1047 | ret = 0; | 1040 | ret = 0; |
@@ -1066,10 +1059,8 @@ static int __rproc_boot(struct rproc *rproc, bool wait) | |||
1066 | release_firmware(firmware_p); | 1059 | release_firmware(firmware_p); |
1067 | 1060 | ||
1068 | downref_rproc: | 1061 | downref_rproc: |
1069 | if (ret) { | 1062 | if (ret) |
1070 | module_put(dev->parent->driver->owner); | ||
1071 | atomic_dec(&rproc->power); | 1063 | atomic_dec(&rproc->power); |
1072 | } | ||
1073 | unlock_mutex: | 1064 | unlock_mutex: |
1074 | mutex_unlock(&rproc->lock); | 1065 | mutex_unlock(&rproc->lock); |
1075 | return ret; | 1066 | return ret; |
@@ -1158,8 +1149,6 @@ void rproc_shutdown(struct rproc *rproc) | |||
1158 | 1149 | ||
1159 | out: | 1150 | out: |
1160 | mutex_unlock(&rproc->lock); | 1151 | mutex_unlock(&rproc->lock); |
1161 | if (!ret) | ||
1162 | module_put(dev->parent->driver->owner); | ||
1163 | } | 1152 | } |
1164 | EXPORT_SYMBOL(rproc_shutdown); | 1153 | EXPORT_SYMBOL(rproc_shutdown); |
1165 | 1154 | ||
@@ -1188,6 +1177,12 @@ struct rproc *rproc_get_by_phandle(phandle phandle) | |||
1188 | mutex_lock(&rproc_list_mutex); | 1177 | mutex_lock(&rproc_list_mutex); |
1189 | list_for_each_entry(r, &rproc_list, node) { | 1178 | list_for_each_entry(r, &rproc_list, node) { |
1190 | if (r->dev.parent && r->dev.parent->of_node == np) { | 1179 | if (r->dev.parent && r->dev.parent->of_node == np) { |
1180 | /* prevent underlying implementation from being removed */ | ||
1181 | if (!try_module_get(r->dev.parent->driver->owner)) { | ||
1182 | dev_err(&r->dev, "can't get owner\n"); | ||
1183 | break; | ||
1184 | } | ||
1185 | |||
1191 | rproc = r; | 1186 | rproc = r; |
1192 | get_device(&rproc->dev); | 1187 | get_device(&rproc->dev); |
1193 | break; | 1188 | break; |
@@ -1411,6 +1406,7 @@ EXPORT_SYMBOL(rproc_free); | |||
1411 | */ | 1406 | */ |
1412 | void rproc_put(struct rproc *rproc) | 1407 | void rproc_put(struct rproc *rproc) |
1413 | { | 1408 | { |
1409 | module_put(rproc->dev.parent->driver->owner); | ||
1414 | put_device(&rproc->dev); | 1410 | put_device(&rproc->dev); |
1415 | } | 1411 | } |
1416 | EXPORT_SYMBOL(rproc_put); | 1412 | EXPORT_SYMBOL(rproc_put); |