remoteproc: Make rproc_get_by_phandle() work for clusters
Multi-cluster remoteproc designs typically have the following DT declaration: remoteproc-cluster { compatible = "soc,remoteproc-cluster"; core0: core0 { compatible = "soc,remoteproc-core" memory-region; sram; }; core1: core1 { compatible = "soc,remoteproc-core" memory-region; sram; } }; A driver exists for the cluster rather than the individual cores themselves so that operation mode and HW specific configurations applicable to the cluster can be made. Because the driver exists at the cluster level and not the individual core level, function rproc_get_by_phandle() fails to return the remoteproc associated with the phandled it is called for. This patch enhances rproc_get_by_phandle() by looking for the cluster's driver when the driver for the immediate remoteproc's parent is not found. Reported-by: Ben Levinsky <ben.levinsky@xilinx.com> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Co-developed-by: Tarak Reddy <tarak.reddy@amd.com> Signed-off-by: Tarak Reddy <tarak.reddy@amd.com> Co-developed-by: Tanmay Shah <tanmay.shah@amd.com> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com> Link: https://lore.kernel.org/r/20240130154849.1018666-1-tanmay.shah@amd.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
This commit is contained in:
parent
a3dd84d308
commit
8b46dc5cfa
@ -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)
|
||||
{
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user