diff options
author | Dave Gerlach <d-gerlach@ti.com> | 2015-05-22 16:45:27 -0400 |
---|---|---|
committer | Ohad Ben-Cohen <ohad@wizery.com> | 2015-06-16 14:12:52 -0400 |
commit | fec47d863587c272d6fbf4e50066209c953d5e60 (patch) | |
tree | 69d0df993b81d611cb3f878c66c8cb8a21ae8a1a /drivers/remoteproc | |
parent | 172e6ab1caffcd2dd2910b44d88d096f2c6985fa (diff) |
remoteproc: introduce rproc_get_by_phandle API
Allow users of remoteproc the ability to get a handle to an rproc by
passing a phandle supplied in the user's device tree node. This is
useful in situations that require manual booting of the rproc.
This patch uses the code removed by commit 40e575b1d0b3 ("remoteproc:
remove the get_by_name/put API") for the ref counting but is modified
to use a simple list and locking mechanism and has rproc_get_by_name
replaced with an rproc_get_by_phandle API.
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
[fix order of Signed-off-by tags]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index e991512e04ed..e1a6d693b8bb 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -44,6 +44,9 @@ | |||
44 | 44 | ||
45 | #include "remoteproc_internal.h" | 45 | #include "remoteproc_internal.h" |
46 | 46 | ||
47 | static DEFINE_MUTEX(rproc_list_mutex); | ||
48 | static LIST_HEAD(rproc_list); | ||
49 | |||
47 | typedef int (*rproc_handle_resources_t)(struct rproc *rproc, | 50 | typedef int (*rproc_handle_resources_t)(struct rproc *rproc, |
48 | struct resource_table *table, int len); | 51 | struct resource_table *table, int len); |
49 | typedef int (*rproc_handle_resource_t)(struct rproc *rproc, | 52 | typedef int (*rproc_handle_resource_t)(struct rproc *rproc, |
@@ -1145,6 +1148,43 @@ out: | |||
1145 | EXPORT_SYMBOL(rproc_shutdown); | 1148 | EXPORT_SYMBOL(rproc_shutdown); |
1146 | 1149 | ||
1147 | /** | 1150 | /** |
1151 | * rproc_get_by_phandle() - find a remote processor by phandle | ||
1152 | * @phandle: phandle to the rproc | ||
1153 | * | ||
1154 | * Finds an rproc handle using the remote processor's phandle, and then | ||
1155 | * return a handle to the rproc. | ||
1156 | * | ||
1157 | * This function increments the remote processor's refcount, so always | ||
1158 | * use rproc_put() to decrement it back once rproc isn't needed anymore. | ||
1159 | * | ||
1160 | * Returns the rproc handle on success, and NULL on failure. | ||
1161 | */ | ||
1162 | struct rproc *rproc_get_by_phandle(phandle phandle) | ||
1163 | { | ||
1164 | struct rproc *rproc = NULL, *r; | ||
1165 | struct device_node *np; | ||
1166 | |||
1167 | np = of_find_node_by_phandle(phandle); | ||
1168 | if (!np) | ||
1169 | return NULL; | ||
1170 | |||
1171 | mutex_lock(&rproc_list_mutex); | ||
1172 | list_for_each_entry(r, &rproc_list, node) { | ||
1173 | if (r->dev.parent && r->dev.parent->of_node == np) { | ||
1174 | rproc = r; | ||
1175 | get_device(&rproc->dev); | ||
1176 | break; | ||
1177 | } | ||
1178 | } | ||
1179 | mutex_unlock(&rproc_list_mutex); | ||
1180 | |||
1181 | of_node_put(np); | ||
1182 | |||
1183 | return rproc; | ||
1184 | } | ||
1185 | EXPORT_SYMBOL(rproc_get_by_phandle); | ||
1186 | |||
1187 | /** | ||
1148 | * rproc_add() - register a remote processor | 1188 | * rproc_add() - register a remote processor |
1149 | * @rproc: the remote processor handle to register | 1189 | * @rproc: the remote processor handle to register |
1150 | * | 1190 | * |
@@ -1173,6 +1213,11 @@ int rproc_add(struct rproc *rproc) | |||
1173 | if (ret < 0) | 1213 | if (ret < 0) |
1174 | return ret; | 1214 | return ret; |
1175 | 1215 | ||
1216 | /* expose to rproc_get_by_phandle users */ | ||
1217 | mutex_lock(&rproc_list_mutex); | ||
1218 | list_add(&rproc->node, &rproc_list); | ||
1219 | mutex_unlock(&rproc_list_mutex); | ||
1220 | |||
1176 | dev_info(dev, "%s is available\n", rproc->name); | 1221 | dev_info(dev, "%s is available\n", rproc->name); |
1177 | 1222 | ||
1178 | dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n"); | 1223 | dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n"); |
@@ -1360,6 +1405,11 @@ int rproc_del(struct rproc *rproc) | |||
1360 | /* Free the copy of the resource table */ | 1405 | /* Free the copy of the resource table */ |
1361 | kfree(rproc->cached_table); | 1406 | kfree(rproc->cached_table); |
1362 | 1407 | ||
1408 | /* the rproc is downref'ed as soon as it's removed from the klist */ | ||
1409 | mutex_lock(&rproc_list_mutex); | ||
1410 | list_del(&rproc->node); | ||
1411 | mutex_unlock(&rproc_list_mutex); | ||
1412 | |||
1363 | device_del(&rproc->dev); | 1413 | device_del(&rproc->dev); |
1364 | 1414 | ||
1365 | return 0; | 1415 | return 0; |