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>
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 @@
 	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 @@
 {
 	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 @@
 		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;