diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-09 14:34:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-09 14:34:38 -0700 |
commit | 7151202b64c8c5eb163e41fa0adcb8239eea64aa (patch) | |
tree | 00a8d47c830e1c47405808b4a3714fe41f3eea0d /drivers/remoteproc | |
parent | d7efc352abb8903ccb8600e1148f59dd9164317e (diff) | |
parent | ed43d098f9020d6669a00bd26fac807d5c19e202 (diff) |
Merge tag 'rpmsg-v4.14' of git://github.com/andersson/remoteproc
Pull rpmsg updates from Bjorn Andersson:
"This extends the Qualcomm GLINK implementation to support the
additional features used for communicating with modem and DSP
coprocessors in modern Qualcomm platforms.
In addition to this there's support for placing virtio RPMSG buffers
in non-System RAM"
* tag 'rpmsg-v4.14' of git://github.com/andersson/remoteproc: (29 commits)
rpmsg: glink: initialize ret to zero to ensure error status check is correct
rpmsg: glink: fix null pointer dereference on a null intent
dt-bindings: soc: qcom: Extend GLINK to cover SMEM
remoteproc: qcom: adsp: Allow defining GLINK edge
rpmsg: glink: Export symbols from common code
rpmsg: glink: Release idr lock before returning on error
rpmsg: glink: Handle remote rx done command
rpmsg: glink: Request for intents when unavailable
rpmsg: glink: Use the intents passed by remote
rpmsg: glink: Receive and store the remote intent buffers
rpmsg: glink: Add announce_create ops and preallocate intents
rpmsg: glink: Add rx done command
rpmsg: glink: Make RX FIFO peak accessor to take an offset
rpmsg: glink: Use the local intents when receiving data
rpmsg: glink: Add support for TX intents
rpmsg: glink: Fix idr_lock from mutex to spinlock
rpmsg: glink: Add support for transport version negotiation
rpmsg: glink: Introduce glink smem based transport
rpmsg: glink: Do a mbox_free_channel in remove
rpmsg: glink: Return -EAGAIN when there is no FIFO space
...
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r-- | drivers/remoteproc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/remoteproc/qcom_adsp_pil.c | 3 | ||||
-rw-r--r-- | drivers/remoteproc/qcom_common.c | 49 | ||||
-rw-r--r-- | drivers/remoteproc/qcom_common.h | 11 |
4 files changed, 64 insertions, 0 deletions
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 79f903af6504..df63e44526ac 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -92,6 +92,7 @@ config QCOM_ADSP_PIL depends on OF && ARCH_QCOM depends on QCOM_SMEM depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n) + depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n select MFD_SYSCON select QCOM_MDT_LOADER select QCOM_RPROC_COMMON diff --git a/drivers/remoteproc/qcom_adsp_pil.c b/drivers/remoteproc/qcom_adsp_pil.c index d01a8daf948a..3f6af54dbc96 100644 --- a/drivers/remoteproc/qcom_adsp_pil.c +++ b/drivers/remoteproc/qcom_adsp_pil.c @@ -72,6 +72,7 @@ struct qcom_adsp { void *mem_region; size_t mem_size; + struct qcom_rproc_glink glink_subdev; struct qcom_rproc_subdev smd_subdev; struct qcom_rproc_ssr ssr_subdev; }; @@ -400,6 +401,7 @@ static int adsp_probe(struct platform_device *pdev) goto free_rproc; } + qcom_add_glink_subdev(rproc, &adsp->glink_subdev); qcom_add_smd_subdev(rproc, &adsp->smd_subdev); qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name); @@ -422,6 +424,7 @@ static int adsp_remove(struct platform_device *pdev) qcom_smem_state_put(adsp->state); rproc_del(adsp->rproc); + qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev); qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev); qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); rproc_free(adsp->rproc); diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 257680f82b27..d487040b528b 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -20,11 +20,13 @@ #include <linux/module.h> #include <linux/notifier.h> #include <linux/remoteproc.h> +#include <linux/rpmsg/qcom_glink.h> #include <linux/rpmsg/qcom_smd.h> #include "remoteproc_internal.h" #include "qcom_common.h" +#define to_glink_subdev(d) container_of(d, struct qcom_rproc_glink, subdev) #define to_smd_subdev(d) container_of(d, struct qcom_rproc_subdev, subdev) #define to_ssr_subdev(d) container_of(d, struct qcom_rproc_ssr, subdev) @@ -49,6 +51,53 @@ struct resource_table *qcom_mdt_find_rsc_table(struct rproc *rproc, } EXPORT_SYMBOL_GPL(qcom_mdt_find_rsc_table); +static int glink_subdev_probe(struct rproc_subdev *subdev) +{ + struct qcom_rproc_glink *glink = to_glink_subdev(subdev); + + glink->edge = qcom_glink_smem_register(glink->dev, glink->node); + + return IS_ERR(glink->edge) ? PTR_ERR(glink->edge) : 0; +} + +static void glink_subdev_remove(struct rproc_subdev *subdev) +{ + struct qcom_rproc_glink *glink = to_glink_subdev(subdev); + + qcom_glink_smem_unregister(glink->edge); + glink->edge = NULL; +} + +/** + * qcom_add_glink_subdev() - try to add a GLINK subdevice to rproc + * @rproc: rproc handle to parent the subdevice + * @glink: reference to a GLINK subdev context + */ +void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink) +{ + struct device *dev = &rproc->dev; + + glink->node = of_get_child_by_name(dev->parent->of_node, "glink-edge"); + if (!glink->node) + return; + + glink->dev = dev; + rproc_add_subdev(rproc, &glink->subdev, glink_subdev_probe, glink_subdev_remove); +} +EXPORT_SYMBOL_GPL(qcom_add_glink_subdev); + +/** + * qcom_remove_glink_subdev() - remove a GLINK subdevice from rproc + * @rproc: rproc handle + * @glink: reference to a GLINK subdev context + */ +void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink) +{ + rproc_remove_subdev(rproc, &glink->subdev); + of_node_put(glink->node); +} +EXPORT_SYMBOL_GPL(qcom_remove_glink_subdev); + static int smd_subdev_probe(struct rproc_subdev *subdev) { struct qcom_rproc_subdev *smd = to_smd_subdev(subdev); diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index fab28b64b8ea..4f8bc168473c 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -4,6 +4,14 @@ #include <linux/remoteproc.h> #include "remoteproc_internal.h" +struct qcom_rproc_glink { + struct rproc_subdev subdev; + + struct device *dev; + struct device_node *node; + struct qcom_glink *edge; +}; + struct qcom_rproc_subdev { struct rproc_subdev subdev; @@ -22,6 +30,9 @@ struct resource_table *qcom_mdt_find_rsc_table(struct rproc *rproc, const struct firmware *fw, int *tablesz); +void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); +void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); + void qcom_add_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); |