[PATCH v2 16/26] omap3isp: queue: Map PFNMAP buffers to device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Userspace PFNMAP buffers need to be mapped to the device like the
userspace non-PFNMAP buffers in order for the DMA mapping implementation
to create IOMMU mappings when we'll switch to the IOMMU-aware DMA
mapping backend.

Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
---
 drivers/media/platform/omap3isp/ispqueue.c | 37 +++++++++++++++++-------------
 drivers/media/platform/omap3isp/ispqueue.h |  4 ++--
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c
index 479d348..4a271c7 100644
--- a/drivers/media/platform/omap3isp/ispqueue.c
+++ b/drivers/media/platform/omap3isp/ispqueue.c
@@ -173,6 +173,7 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
 	struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
 	struct isp_video *video = vfh->video;
 	enum dma_data_direction direction;
+	DEFINE_DMA_ATTRS(attrs);
 	unsigned int i;
 
 	if (buf->dma) {
@@ -181,11 +182,14 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
 		buf->dma = 0;
 	}
 
-	if (!(buf->vm_flags & VM_PFNMAP)) {
+	if (buf->vbuf.memory == V4L2_MEMORY_USERPTR) {
+		if (buf->skip_cache)
+			dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
+
 		direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
 			  ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-		dma_unmap_sg(buf->queue->dev, buf->sgt.sgl, buf->sgt.orig_nents,
-			     direction);
+		dma_unmap_sg_attrs(buf->queue->dev, buf->sgt.sgl,
+				   buf->sgt.orig_nents, direction, &attrs);
 	}
 
 	sg_free_table(&buf->sgt);
@@ -345,10 +349,6 @@ unlock:
 
 	for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) {
 		sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset);
-		/* PFNMAP buffers will not get DMA-mapped, set the DMA address
-		 * manually.
-		 */
-		sg_dma_address(sg) = (pfn << PAGE_SHIFT) + offset;
 		sg = sg_next(sg);
 		offset = 0;
 	}
@@ -434,12 +434,15 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
 	struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
 	struct isp_video *video = vfh->video;
 	enum dma_data_direction direction;
+	DEFINE_DMA_ATTRS(attrs);
 	unsigned long addr;
 	int ret;
 
 	switch (buf->vbuf.memory) {
 	case V4L2_MEMORY_MMAP:
 		ret = isp_video_buffer_prepare_kernel(buf);
+		if (ret < 0)
+			goto done;
 		break;
 
 	case V4L2_MEMORY_USERPTR:
@@ -451,24 +454,26 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
 			ret = isp_video_buffer_prepare_pfnmap(buf);
 		else
 			ret = isp_video_buffer_prepare_user(buf);
-		break;
 
-	default:
-		return -EINVAL;
-	}
+		if (ret < 0)
+			goto done;
 
-	if (ret < 0)
-		goto done;
+		if (buf->skip_cache)
+			dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
 
-	if (!(buf->vm_flags & VM_PFNMAP)) {
 		direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
 			  ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-		ret = dma_map_sg(buf->queue->dev, buf->sgt.sgl,
-				 buf->sgt.orig_nents, direction);
+		ret = dma_map_sg_attrs(buf->queue->dev, buf->sgt.sgl,
+				       buf->sgt.orig_nents, direction, &attrs);
 		if (ret <= 0) {
 			ret = -EFAULT;
 			goto done;
 		}
+
+		break;
+
+	default:
+		return -EINVAL;
 	}
 
 	addr = omap_iommu_vmap(video->isp->domain, video->isp->dev, 0,
diff --git a/drivers/media/platform/omap3isp/ispqueue.h b/drivers/media/platform/omap3isp/ispqueue.h
index e03af74..d580f58 100644
--- a/drivers/media/platform/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
@@ -72,7 +72,7 @@ enum isp_video_buffer_state {
  * @vm_flags: Buffer VMA flags (for userspace buffers)
  * @npages: Number of pages (for userspace buffers)
  * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
- * @sgt: Scatter gather table (for non-VM_PFNMAP buffers)
+ * @sgt: Scatter gather table
  * @vbuf: V4L2 buffer
  * @irqlist: List head for insertion into IRQ queue
  * @state: Current buffer state
@@ -94,7 +94,7 @@ struct isp_video_buffer {
 	unsigned int npages;
 	struct page **pages;
 
-	/* For all buffers except VM_PFNMAP. */
+	/* For all buffers. */
 	struct sg_table sgt;
 
 	/* Touched by the interrupt handler. */
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux