aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Olsson <mikael.olsson@arm.com>2023-11-10 15:15:34 +0100
committerMikael Olsson <mikael.olsson@arm.com>2023-11-14 14:22:08 +0100
commit9f176ba0e99b131b790038948af51c62c2d46b8c (patch)
tree42b50f191c9b226a16eb9299aa95ee911fe10f97
parent9fdbf1e084ce0a2994c2637f506dbde84e9f228c (diff)
downloadethos-u-linux-driver-stack-9f176ba0e99b131b790038948af51c62c2d46b8c.tar.gz
Fix iomem pointer usage with rproc_mem_entry_init
The carveout memory is being mapped with one of the ioremap functions that returns a iomem pointer and should normally only be passed to functions that request iomem pointers because they shouldn't be dereferenced. Currently, the iomem pointer is passed to rproc_mem_entry_init that is expecting a normal pointer and Sparse is generating a warnings about this. However, rproc_mem_entry_init won't dereference the pointer and can handle any pointer type so the iomem attribute is cast away when setting up the mem entry and the io_mem flag is set to indicate a iomem pointer. To ensure that the mapping is correctly managed, the mapping and unmapping is now handled with the callback functions for rproc_mem_entry_init instead of holding onto the mapping forever. Change-Id: I511a9a16f110a23490141dd3db943244e0f978e2 Signed-off-by: Mikael Olsson <mikael.olsson@arm.com>
-rw-r--r--remoteproc/ethosu_remoteproc.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/remoteproc/ethosu_remoteproc.c b/remoteproc/ethosu_remoteproc.c
index c6d7735..344627d 100644
--- a/remoteproc/ethosu_remoteproc.c
+++ b/remoteproc/ethosu_remoteproc.c
@@ -122,6 +122,38 @@ static void ethosu_mbox_top(struct mbox_client *client,
queue_work(erproc->wq, &erproc->work);
}
+static int ethosu_mem_alloc(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ struct device *dev = rproc->dev.parent;
+ void *va;
+
+ va = (__force void *)devm_ioremap_wc(dev, mem->dma, mem->len);
+ if (IS_ERR_OR_NULL(va)) {
+ dev_err(dev, "Failed to remap address. pa=%pa, len=%zu",
+ &mem->dma,
+ mem->len);
+
+ return -ENOMEM;
+ }
+
+ mem->va = va;
+ mem->is_iomem = true;
+
+ return 0;
+}
+
+static int ethosu_mem_release(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ struct device *dev = rproc->dev.parent;
+
+ if (mem->va)
+ devm_iounmap(dev, (__force __iomem void *)mem->va);
+
+ return 0;
+}
+
static int ethosu_add_carveout(struct rproc *rproc,
const phys_addr_t pa,
const size_t size,
@@ -129,7 +161,6 @@ static int ethosu_add_carveout(struct rproc *rproc,
{
struct device *dev = rproc->dev.parent;
dma_addr_t da;
- void __iomem *va;
struct rproc_mem_entry *mem;
da = translate_phys_to_dma(dev, pa);
@@ -141,15 +172,8 @@ static int ethosu_add_carveout(struct rproc *rproc,
return -ENOMEM;
}
- va = devm_ioremap_wc(dev, pa, size);
- if (!va) {
- dev_err(dev, "Failed to remap address. pa=%pa, len=%zu", &pa,
- size);
-
- return -ENOMEM;
- }
-
- mem = rproc_mem_entry_init(dev, va, pa, size, da, NULL, NULL, name);
+ mem = rproc_mem_entry_init(dev, NULL, pa, size, da, ethosu_mem_alloc,
+ ethosu_mem_release, name);
if (!mem)
return -ENOMEM;