summaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc/st_remoteproc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 17:00:06 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 17:00:06 +0100
commit2f194646fecaa9fd4607b670ee9ef84d9ed04566 (patch)
tree5012f3fc7232f509102ee6a3007997043e987390 /drivers/remoteproc/st_remoteproc.c
parentMerge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cl... (diff)
parentremoteproc: fix for "dma-mapping: remove the DMA_MEMORY_EXCLUSIVE flag" (diff)
downloadlinux-2f194646fecaa9fd4607b670ee9ef84d9ed04566.tar.xz
linux-2f194646fecaa9fd4607b670ee9ef84d9ed04566.zip
Merge tag 'rproc-v5.1' of git://github.com/andersson/remoteproc
Pull remoteproc updates from Bjorn Andersson: "This contains the last patches in Loic's remoteproc resource table handling changes, a number of updates to documentation, support for invoking the crash handler (for testing purposes), a fix for the handling of virtio devices during recovery, performance state votes in Qualcomm modem driver, support for specifying board specific firmware path for Qualcomm modem driver and improved support for graceful shutdown of Qualcomm remoteprocs" * tag 'rproc-v5.1' of git://github.com/andersson/remoteproc: (33 commits) remoteproc: fix for "dma-mapping: remove the DMA_MEMORY_EXCLUSIVE flag" remoteproc: fix rproc_check_carveout_da() returned error and comments remoteproc: fix trace buffer va initialization remoteproc: fix rproc_alloc_carveout() for rproc with iommu domain remoteproc: add warning on resource table cast remoteproc: fix rproc_alloc_carveout() bad variable cast remoteproc: fix rproc_da_to_va in case of unallocated carveout remoteproc: correct rproc_mem_entry_init() comments remoteproc: fix recovery procedure rpmsg: virtio: change header file sort style rpmsg: virtio: allocate buffer from parent remoteproc: st: add reserved memory support remoteproc: create vdev subdevice with specific dma memory pool remoteproc: q6v5_adsp: Remove voting for lpass_aon clock dt-binding: remoteproc: Remove lpass_aon clock from adsp pil clock list remoteproc: q6v5-mss: Active powerdomain for SDM845 remoteproc: q6v5-mss: Vote for rpmh power domains remoteproc: qcom: Add support for parsing fw dt bindings remoteproc: qcom_q6v5: don't auto boot remote processor remoteproc: qcom: Wait for shutdown-ack/ind on sysmon shutdown ...
Diffstat (limited to 'drivers/remoteproc/st_remoteproc.c')
-rw-r--r--drivers/remoteproc/st_remoteproc.c91
1 files changed, 80 insertions, 11 deletions
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
index aacef0ea3b90..51049d17b1e5 100644
--- a/drivers/remoteproc/st_remoteproc.c
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -19,6 +19,7 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
@@ -91,6 +92,77 @@ static void st_rproc_kick(struct rproc *rproc, int vqid)
dev_err(dev, "failed to send message via mbox: %d\n", ret);
}
+static int st_rproc_mem_alloc(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ struct device *dev = rproc->dev.parent;
+ void *va;
+
+ va = ioremap_wc(mem->dma, mem->len);
+ if (!va) {
+ dev_err(dev, "Unable to map memory region: %pa+%zx\n",
+ &mem->dma, mem->len);
+ return -ENOMEM;
+ }
+
+ /* Update memory entry va */
+ mem->va = va;
+
+ return 0;
+}
+
+static int st_rproc_mem_release(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ iounmap(mem->va);
+
+ return 0;
+}
+
+static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
+{
+ struct device *dev = rproc->dev.parent;
+ struct device_node *np = dev->of_node;
+ struct rproc_mem_entry *mem;
+ struct reserved_mem *rmem;
+ struct of_phandle_iterator it;
+ int index = 0;
+
+ of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
+ while (of_phandle_iterator_next(&it) == 0) {
+ rmem = of_reserved_mem_lookup(it.node);
+ if (!rmem) {
+ dev_err(dev, "unable to acquire memory-region\n");
+ return -EINVAL;
+ }
+
+ /* No need to map vdev buffer */
+ if (strcmp(it.node->name, "vdev0buffer")) {
+ /* Register memory region */
+ mem = rproc_mem_entry_init(dev, NULL,
+ (dma_addr_t)rmem->base,
+ rmem->size, rmem->base,
+ st_rproc_mem_alloc,
+ st_rproc_mem_release,
+ it.node->name);
+ } else {
+ /* Register reserved memory for vdev buffer allocation */
+ mem = rproc_of_resm_mem_entry_init(dev, index,
+ rmem->size,
+ rmem->base,
+ it.node->name);
+ }
+
+ if (!mem)
+ return -ENOMEM;
+
+ rproc_add_carveout(rproc, mem);
+ index++;
+ }
+
+ return rproc_elf_load_rsc_table(rproc, fw);
+}
+
static int st_rproc_start(struct rproc *rproc)
{
struct st_rproc *ddata = rproc->priv;
@@ -158,9 +230,14 @@ static int st_rproc_stop(struct rproc *rproc)
}
static const struct rproc_ops st_rproc_ops = {
- .kick = st_rproc_kick,
- .start = st_rproc_start,
- .stop = st_rproc_stop,
+ .kick = st_rproc_kick,
+ .start = st_rproc_start,
+ .stop = st_rproc_stop,
+ .parse_fw = st_rproc_parse_fw,
+ .load = rproc_elf_load_segments,
+ .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
+ .sanity_check = rproc_elf_sanity_check,
+ .get_boot_addr = rproc_elf_get_boot_addr,
};
/*
@@ -254,12 +331,6 @@ static int st_rproc_parse_dt(struct platform_device *pdev)
return -EINVAL;
}
- err = of_reserved_mem_device_init(dev);
- if (err) {
- dev_err(dev, "Failed to obtain shared memory\n");
- return err;
- }
-
err = clk_prepare(ddata->clk);
if (err)
dev_err(dev, "failed to get clock\n");
@@ -387,8 +458,6 @@ static int st_rproc_remove(struct platform_device *pdev)
clk_disable_unprepare(ddata->clk);
- of_reserved_mem_device_release(&pdev->dev);
-
for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++)
mbox_free_channel(ddata->mbox_chan[i]);