aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc/remoteproc_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/remoteproc/remoteproc_core.c')
-rw-r--r--drivers/remoteproc/remoteproc_core.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 695cce218e8c64..f276956f2c5cec 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -33,6 +33,7 @@
#include <linux/idr.h>
#include <linux/elf.h>
#include <linux/crc32.h>
+#include <linux/of_platform.h>
#include <linux/of_reserved_mem.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_ring.h>
@@ -2112,6 +2113,7 @@ EXPORT_SYMBOL(rproc_detach);
struct rproc *rproc_get_by_phandle(phandle phandle)
{
struct rproc *rproc = NULL, *r;
+ struct device_driver *driver;
struct device_node *np;
np = of_find_node_by_phandle(phandle);
@@ -2122,7 +2124,26 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
list_for_each_entry_rcu(r, &rproc_list, node) {
if (r->dev.parent && device_match_of_node(r->dev.parent, np)) {
/* prevent underlying implementation from being removed */
- if (!try_module_get(r->dev.parent->driver->owner)) {
+
+ /*
+ * If the remoteproc's parent has a driver, the
+ * remoteproc is not part of a cluster and we can use
+ * that driver.
+ */
+ driver = r->dev.parent->driver;
+
+ /*
+ * If the remoteproc's parent does not have a driver,
+ * look for the driver associated with the cluster.
+ */
+ if (!driver) {
+ if (r->dev.parent->parent)
+ driver = r->dev.parent->parent->driver;
+ if (!driver)
+ break;
+ }
+
+ if (!try_module_get(driver->owner)) {
dev_err(&r->dev, "can't get owner\n");
break;
}
@@ -2533,7 +2554,11 @@ EXPORT_SYMBOL(rproc_free);
*/
void rproc_put(struct rproc *rproc)
{
- module_put(rproc->dev.parent->driver->owner);
+ if (rproc->dev.parent->driver)
+ module_put(rproc->dev.parent->driver->owner);
+ else
+ module_put(rproc->dev.parent->parent->driver->owner);
+
put_device(&rproc->dev);
}
EXPORT_SYMBOL(rproc_put);