Commit 49ac3695 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[media] omap3isp: queue: Map PFNMAP buffers to device



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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: default avatarSakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent b8d64282
Loading
Loading
Loading
Loading
+21 −16
Original line number Diff line number Diff line
@@ -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 (!(buf->vm_flags & VM_PFNMAP)) {
		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;
		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,
+2 −2
Original line number Diff line number Diff line
@@ -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. */