diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-21 10:37:39 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-21 10:37:39 -0700 |
commit | 0e875ee5e897db13104faab93bb1ab2b95da9ab9 (patch) | |
tree | 2b869ada9730cd5a3584ef9d7f3f8bf22e0e9c70 /drivers/remoteproc/remoteproc_core.c | |
parent | ebc9bee8814d12ec247de117aa2f7fd39ff11127 (diff) | |
parent | 62210f7509e13a2caa7b080722a45229b8f17a0a (diff) | |
download | linux-0e875ee5e897db13104faab93bb1ab2b95da9ab9.tar.gz |
Merge tag 'rproc-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux
Pull remoteproc updates from Bjorn Andersson:
"Qualcomm SM8650 audio, compute and modem remoteproc are added.
Qualcomm X1 Elite audio and compute remoteprocs are added, after
support for shutting down the bootloader-loaded firmware loaded into
the audio DSP..
A dozen drivers in the subsystem are transitioned to use devres
helpers for remoteproc and memory allocations - this makes it possible
to acquire in-kernel handle to individual remoteproc instances in a
cluster.
The release of DMA memory for remoteproc virtio is corrected to ensure
that restarting due to a watchdog bite doesn't attempt to allocate the
memory again without first freeing it.
Last, but not least, a couple of DeviceTree binding cleanups"
* tag 'rproc-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (30 commits)
remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP
remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP
dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & cDSP
remoteproc: qcom_wcnss: Use devm_rproc_alloc() helper
remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc() helper
remoteproc: qcom_q6v5_pas: Use devm_rproc_alloc() helper
remoteproc: qcom_q6v5_mss: Use devm_rproc_alloc() helper
remoteproc: qcom_q6v5_adsp: Use devm_rproc_alloc() helper
dt-bindings: remoteproc: do not override firmware-name $ref
dt-bindings: remoteproc: qcom,glink-rpm-edge: drop redundant type from label
remoteproc: qcom: pas: correct data indentation
remoteproc: Make rproc_get_by_phandle() work for clusters
remoteproc: qcom: pas: Add SM8650 remoteproc support
remoteproc: qcom: pas: make region assign more generic
dt-bindings: remoteproc: qcom,sm8550-pas: document the SM8650 PAS
remoteproc: k3-dsp: Use devm_rproc_add() helper
remoteproc: k3-dsp: Use devm_ioremap_wc() helper
remoteproc: k3-dsp: Add devm action to release tsp
remoteproc: k3-dsp: Use devm_kzalloc() helper
remoteproc: k3-dsp: Use devm_ti_sci_get_by_phandle() helper
...
Diffstat (limited to 'drivers/remoteproc/remoteproc_core.c')
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 29 |
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); |