diff mbox series

[6/7] remoteproc: modify vring allocation to support preallocated region

Message ID 1509108254-22296-7-git-send-email-loic.pallardy@st.com
State Superseded
Headers show
Series remoteproc: add fixed memory region support | expand

Commit Message

Loic Pallardy Oct. 27, 2017, 12:44 p.m. UTC
Current version of rproc_alloc_vring function supports only dynamic vring
allocation.
This patch extends rproc_alloc_vring to verify if requested vring DA is
already part or not of a registered carveout. If true, nothing to do, else
just allocate vring as before.

Signed-off-by: Loic Pallardy <loic.pallardy@st.com>

---
 drivers/remoteproc/remoteproc_core.c | 50 +++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 18 deletions(-)

-- 
1.9.1
diff mbox series

Patch

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 515a17a..e1dbe65 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -263,21 +263,41 @@  int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	struct device *dev = &rproc->dev;
 	struct rproc_vring *rvring = &rvdev->vring[i];
 	struct fw_rsc_vdev *rsc;
-	dma_addr_t dma;
+	dma_addr_t dma = 0;
 	void *va;
 	int ret, size, notifyid;
 
 	/* actual size of vring (in bytes) */
 	size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
 
-	/*
-	 * Allocate non-cacheable memory for the vring. In the future
-	 * this call will also configure the IOMMU for us
-	 */
-	va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
-	if (!va) {
-		dev_err(dev->parent, "dma_alloc_coherent failed\n");
-		return -EINVAL;
+	/* get vring resource table pointer */
+	rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
+
+	if (rsc->vring[i].da != FW_RSC_ADDR_ANY) {
+		va = rproc_find_carveout_by_da(rproc, rsc->vring[i].da, size);
+
+		if (!va) {
+			/* No region not found */
+			dev_err(dev->parent, "Pre-allocated vring not found\n");
+			return -ENOMEM;
+		}
+	} else {
+		/*
+		 * Allocate non-cacheable memory for the vring. In the future
+		 * this call will also configure the IOMMU for us
+		 */
+		va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
+		if (!va) {
+			dev_err(dev->parent, "dma_alloc_coherent failed\n");
+			return -EINVAL;
+		}
+		/*
+		 * Let the rproc know the da of this vring.
+		 * Not all platforms use dma_alloc_coherent to automatically
+		 * set up the iommu. In this case the device address (da) will
+		 * hold the physical address and not the device address.
+		 */
+		rsc->vring[i].da = dma;
 	}
 
 	/*
@@ -304,14 +324,7 @@  int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 	rvring->dma = dma;
 	rvring->notifyid = notifyid;
 
-	/*
-	 * Let the rproc know the notifyid and da of this vring.
-	 * Not all platforms use dma_alloc_coherent to automatically
-	 * set up the iommu. In this case the device address (da) will
-	 * hold the physical address and not the device address.
-	 */
-	rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
-	rsc->vring[i].da = dma;
+	/* Let the rproc know the notifyid of this vring. */
 	rsc->vring[i].notifyid = notifyid;
 	return 0;
 }
@@ -348,7 +361,8 @@  void rproc_free_vring(struct rproc_vring *rvring)
 	int idx = rvring->rvdev->vring - rvring;
 	struct fw_rsc_vdev *rsc;
 
-	dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
+	if (rvring->dma)
+		dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
 	idr_remove(&rproc->notifyids, rvring->notifyid);
 
 	/* reset resource entry info */