aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-03-08 07:29:15 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-25 10:17:14 -0400
commit49ac3695d08698c19d2b23af6bd0dd1dfd1a10af (patch)
tree3197927571e2f3ed3de6aeb88114de73377d9fa3 /drivers/media/platform
parentb8d642826d031c8700ff1ad601fedf1ebe351033 (diff)
[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: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.c37
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.h4
2 files changed, 23 insertions, 18 deletions
diff --git a/drivers/media/platform/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c
index 479d348bb510..4a271c7a2cf5 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)
173 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue); 173 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
174 struct isp_video *video = vfh->video; 174 struct isp_video *video = vfh->video;
175 enum dma_data_direction direction; 175 enum dma_data_direction direction;
176 DEFINE_DMA_ATTRS(attrs);
176 unsigned int i; 177 unsigned int i;
177 178
178 if (buf->dma) { 179 if (buf->dma) {
@@ -181,11 +182,14 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
181 buf->dma = 0; 182 buf->dma = 0;
182 } 183 }
183 184
184 if (!(buf->vm_flags & VM_PFNMAP)) { 185 if (buf->vbuf.memory == V4L2_MEMORY_USERPTR) {
186 if (buf->skip_cache)
187 dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
188
185 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE 189 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
186 ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 190 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
187 dma_unmap_sg(buf->queue->dev, buf->sgt.sgl, buf->sgt.orig_nents, 191 dma_unmap_sg_attrs(buf->queue->dev, buf->sgt.sgl,
188 direction); 192 buf->sgt.orig_nents, direction, &attrs);
189 } 193 }
190 194
191 sg_free_table(&buf->sgt); 195 sg_free_table(&buf->sgt);
@@ -345,10 +349,6 @@ unlock:
345 349
346 for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) { 350 for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) {
347 sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset); 351 sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset);
348 /* PFNMAP buffers will not get DMA-mapped, set the DMA address
349 * manually.
350 */
351 sg_dma_address(sg) = (pfn << PAGE_SHIFT) + offset;
352 sg = sg_next(sg); 352 sg = sg_next(sg);
353 offset = 0; 353 offset = 0;
354 } 354 }
@@ -434,12 +434,15 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
434 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue); 434 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
435 struct isp_video *video = vfh->video; 435 struct isp_video *video = vfh->video;
436 enum dma_data_direction direction; 436 enum dma_data_direction direction;
437 DEFINE_DMA_ATTRS(attrs);
437 unsigned long addr; 438 unsigned long addr;
438 int ret; 439 int ret;
439 440
440 switch (buf->vbuf.memory) { 441 switch (buf->vbuf.memory) {
441 case V4L2_MEMORY_MMAP: 442 case V4L2_MEMORY_MMAP:
442 ret = isp_video_buffer_prepare_kernel(buf); 443 ret = isp_video_buffer_prepare_kernel(buf);
444 if (ret < 0)
445 goto done;
443 break; 446 break;
444 447
445 case V4L2_MEMORY_USERPTR: 448 case V4L2_MEMORY_USERPTR:
@@ -451,24 +454,26 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
451 ret = isp_video_buffer_prepare_pfnmap(buf); 454 ret = isp_video_buffer_prepare_pfnmap(buf);
452 else 455 else
453 ret = isp_video_buffer_prepare_user(buf); 456 ret = isp_video_buffer_prepare_user(buf);
454 break;
455 457
456 default: 458 if (ret < 0)
457 return -EINVAL; 459 goto done;
458 }
459 460
460 if (ret < 0) 461 if (buf->skip_cache)
461 goto done; 462 dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
462 463
463 if (!(buf->vm_flags & VM_PFNMAP)) {
464 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE 464 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
465 ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 465 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
466 ret = dma_map_sg(buf->queue->dev, buf->sgt.sgl, 466 ret = dma_map_sg_attrs(buf->queue->dev, buf->sgt.sgl,
467 buf->sgt.orig_nents, direction); 467 buf->sgt.orig_nents, direction, &attrs);
468 if (ret <= 0) { 468 if (ret <= 0) {
469 ret = -EFAULT; 469 ret = -EFAULT;
470 goto done; 470 goto done;
471 } 471 }
472
473 break;
474
475 default:
476 return -EINVAL;
472 } 477 }
473 478
474 addr = omap_iommu_vmap(video->isp->domain, video->isp->dev, 0, 479 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 e03af74ded28..d580f581c209 100644
--- a/drivers/media/platform/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
@@ -72,7 +72,7 @@ enum isp_video_buffer_state {
72 * @vm_flags: Buffer VMA flags (for userspace buffers) 72 * @vm_flags: Buffer VMA flags (for userspace buffers)
73 * @npages: Number of pages (for userspace buffers) 73 * @npages: Number of pages (for userspace buffers)
74 * @pages: Pages table (for userspace non-VM_PFNMAP buffers) 74 * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
75 * @sgt: Scatter gather table (for non-VM_PFNMAP buffers) 75 * @sgt: Scatter gather table
76 * @vbuf: V4L2 buffer 76 * @vbuf: V4L2 buffer
77 * @irqlist: List head for insertion into IRQ queue 77 * @irqlist: List head for insertion into IRQ queue
78 * @state: Current buffer state 78 * @state: Current buffer state
@@ -94,7 +94,7 @@ struct isp_video_buffer {
94 unsigned int npages; 94 unsigned int npages;
95 struct page **pages; 95 struct page **pages;
96 96
97 /* For all buffers except VM_PFNMAP. */ 97 /* For all buffers. */
98 struct sg_table sgt; 98 struct sg_table sgt;
99 99
100 /* Touched by the interrupt handler. */ 100 /* Touched by the interrupt handler. */