diff options
author | Mikael Olsson <mikael.olsson@arm.com> | 2023-11-10 15:15:34 +0100 |
---|---|---|
committer | Mikael Olsson <mikael.olsson@arm.com> | 2023-11-14 14:22:08 +0100 |
commit | 9f176ba0e99b131b790038948af51c62c2d46b8c (patch) | |
tree | 42b50f191c9b226a16eb9299aa95ee911fe10f97 | |
parent | 9fdbf1e084ce0a2994c2637f506dbde84e9f228c (diff) | |
download | ethos-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.c | 44 |
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; |