aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/omap3isp/ispqueue.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-01-02 18:06:08 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-25 10:18:42 -0400
commit2a0a5472af5caa0d0df334abb9975dc496f045da (patch)
treee6981f7cc0127340febff0021f398b7300345c47 /drivers/media/platform/omap3isp/ispqueue.c
parent9a8c7fffa2293417d0245fb9f618564d7dee04a6 (diff)
[media] omap3isp: Use the ARM DMA IOMMU-aware operations
Attach an ARM DMA I/O virtual address space to the ISP device. This switches to the IOMMU-aware ARM DMA backend, we can thus remove the explicit calls to the OMAP IOMMU map and unmap functions. 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/omap3isp/ispqueue.c')
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.c34
1 files changed, 7 insertions, 27 deletions
diff --git a/drivers/media/platform/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c
index cee1b5d29cfa..9c90fb081404 100644
--- a/drivers/media/platform/omap3isp/ispqueue.c
+++ b/drivers/media/platform/omap3isp/ispqueue.c
@@ -26,7 +26,6 @@
26#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
27#include <linux/dma-mapping.h> 27#include <linux/dma-mapping.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/omap-iommu.h>
30#include <linux/pagemap.h> 29#include <linux/pagemap.h>
31#include <linux/poll.h> 30#include <linux/poll.h>
32#include <linux/scatterlist.h> 31#include <linux/scatterlist.h>
@@ -159,7 +158,7 @@ static int isp_video_buffer_prepare_kernel(struct isp_video_buffer *buf)
159 struct isp_video *video = vfh->video; 158 struct isp_video *video = vfh->video;
160 159
161 return dma_get_sgtable(video->isp->dev, &buf->sgt, buf->vaddr, 160 return dma_get_sgtable(video->isp->dev, &buf->sgt, buf->vaddr,
162 buf->paddr, PAGE_ALIGN(buf->vbuf.length)); 161 buf->dma, PAGE_ALIGN(buf->vbuf.length));
163} 162}
164 163
165/* 164/*
@@ -170,18 +169,10 @@ static int isp_video_buffer_prepare_kernel(struct isp_video_buffer *buf)
170 */ 169 */
171static void isp_video_buffer_cleanup(struct isp_video_buffer *buf) 170static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
172{ 171{
173 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
174 struct isp_video *video = vfh->video;
175 enum dma_data_direction direction; 172 enum dma_data_direction direction;
176 DEFINE_DMA_ATTRS(attrs); 173 DEFINE_DMA_ATTRS(attrs);
177 unsigned int i; 174 unsigned int i;
178 175
179 if (buf->dma) {
180 omap_iommu_vunmap(video->isp->domain, video->isp->dev,
181 buf->dma);
182 buf->dma = 0;
183 }
184
185 if (buf->vbuf.memory == V4L2_MEMORY_USERPTR) { 176 if (buf->vbuf.memory == V4L2_MEMORY_USERPTR) {
186 if (buf->skip_cache) 177 if (buf->skip_cache)
187 dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); 178 dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
@@ -419,11 +410,8 @@ done:
419 */ 410 */
420static int isp_video_buffer_prepare(struct isp_video_buffer *buf) 411static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
421{ 412{
422 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
423 struct isp_video *video = vfh->video;
424 enum dma_data_direction direction; 413 enum dma_data_direction direction;
425 DEFINE_DMA_ATTRS(attrs); 414 DEFINE_DMA_ATTRS(attrs);
426 unsigned long addr;
427 int ret; 415 int ret;
428 416
429 switch (buf->vbuf.memory) { 417 switch (buf->vbuf.memory) {
@@ -458,23 +446,15 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
458 goto done; 446 goto done;
459 } 447 }
460 448
449 buf->dma = sg_dma_address(buf->sgt.sgl);
461 break; 450 break;
462 451
463 default: 452 default:
464 return -EINVAL; 453 return -EINVAL;
465 } 454 }
466 455
467 addr = omap_iommu_vmap(video->isp->domain, video->isp->dev, 0, 456 if (!IS_ALIGNED(buf->dma, 32)) {
468 &buf->sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8); 457 dev_dbg(buf->queue->dev,
469 if (IS_ERR_VALUE(addr)) {
470 ret = -EIO;
471 goto done;
472 }
473
474 buf->dma = addr;
475
476 if (!IS_ALIGNED(addr, 32)) {
477 dev_dbg(video->isp->dev,
478 "Buffer address must be aligned to 32 bytes boundary.\n"); 458 "Buffer address must be aligned to 32 bytes boundary.\n");
479 ret = -EINVAL; 459 ret = -EINVAL;
480 goto done; 460 goto done;
@@ -576,7 +556,7 @@ static int isp_video_queue_free(struct isp_video_queue *queue)
576 if (buf->vaddr) { 556 if (buf->vaddr) {
577 dma_free_coherent(queue->dev, 557 dma_free_coherent(queue->dev,
578 PAGE_ALIGN(buf->vbuf.length), 558 PAGE_ALIGN(buf->vbuf.length),
579 buf->vaddr, buf->paddr); 559 buf->vaddr, buf->dma);
580 buf->vaddr = NULL; 560 buf->vaddr = NULL;
581 } 561 }
582 562
@@ -632,7 +612,7 @@ static int isp_video_queue_alloc(struct isp_video_queue *queue,
632 612
633 buf->vbuf.m.offset = i * PAGE_ALIGN(size); 613 buf->vbuf.m.offset = i * PAGE_ALIGN(size);
634 buf->vaddr = mem; 614 buf->vaddr = mem;
635 buf->paddr = dma; 615 buf->dma = dma;
636 } 616 }
637 617
638 buf->vbuf.index = i; 618 buf->vbuf.index = i;
@@ -1079,7 +1059,7 @@ int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
1079 */ 1059 */
1080 vma->vm_pgoff = 0; 1060 vma->vm_pgoff = 0;
1081 1061
1082 ret = dma_mmap_coherent(queue->dev, vma, buf->vaddr, buf->paddr, size); 1062 ret = dma_mmap_coherent(queue->dev, vma, buf->vaddr, buf->dma, size);
1083 if (ret < 0) 1063 if (ret < 0)
1084 goto done; 1064 goto done;
1085 1065