aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-03-08 07:38:38 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-25 10:15:47 -0400
commit7f5036d059fbd263b5322a4298a9935698e7625d (patch)
tree5e877a7e2c4fb8baf4f065f70b931c1df6b8f6c6 /drivers/media
parentd13f19f2ca7fb6b545915e96ffe19bb405b72037 (diff)
[media] omap3isp: queue: Allocate kernel buffers with dma_alloc_coherent
And retrieve the related sg table using dma_get_sgtable(). 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')
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.c57
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.h2
2 files changed, 27 insertions, 32 deletions
diff --git a/drivers/media/platform/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c
index 088710b2a5ea..2fd254f4dbe2 100644
--- a/drivers/media/platform/omap3isp/ispqueue.c
+++ b/drivers/media/platform/omap3isp/ispqueue.c
@@ -148,39 +148,18 @@ out:
148} 148}
149 149
150/* 150/*
151 * isp_video_buffer_prepare_kernel - Build scatter list for a vmalloc'ed buffer 151 * isp_video_buffer_prepare_kernel - Build scatter list for a kernel-allocated
152 * buffer
152 * 153 *
153 * Iterate over the vmalloc'ed area and create a scatter list entry for every 154 * Retrieve the sgtable using the DMA API.
154 * page.
155 */ 155 */
156static int isp_video_buffer_prepare_kernel(struct isp_video_buffer *buf) 156static int isp_video_buffer_prepare_kernel(struct isp_video_buffer *buf)
157{ 157{
158 struct scatterlist *sg; 158 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
159 unsigned int npages; 159 struct isp_video *video = vfh->video;
160 unsigned int i;
161 void *addr;
162 int ret;
163
164 addr = buf->vaddr;
165 npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;
166
167 ret = sg_alloc_table(&buf->sgt, npages, GFP_KERNEL);
168 if (ret < 0)
169 return ret;
170
171 for (sg = buf->sgt.sgl, i = 0; i < npages; ++i, addr += PAGE_SIZE) {
172 struct page *page = vmalloc_to_page(addr);
173
174 if (page == NULL || PageHighMem(page)) {
175 sg_free_table(&buf->sgt);
176 return -EINVAL;
177 }
178
179 sg_set_page(sg, page, PAGE_SIZE, 0);
180 sg = sg_next(sg);
181 }
182 160
183 return 0; 161 return dma_get_sgtable(video->isp->dev, &buf->sgt, buf->vaddr,
162 buf->paddr, PAGE_ALIGN(buf->vbuf.length));
184} 163}
185 164
186/* 165/*
@@ -601,8 +580,12 @@ static int isp_video_queue_free(struct isp_video_queue *queue)
601 580
602 isp_video_buffer_cleanup(buf); 581 isp_video_buffer_cleanup(buf);
603 582
604 vfree(buf->vaddr); 583 if (buf->vaddr) {
605 buf->vaddr = NULL; 584 dma_free_coherent(queue->dev,
585 PAGE_ALIGN(buf->vbuf.length),
586 buf->vaddr, buf->paddr);
587 buf->vaddr = NULL;
588 }
606 589
607 kfree(buf); 590 kfree(buf);
608 queue->buffers[i] = NULL; 591 queue->buffers[i] = NULL;
@@ -623,6 +606,7 @@ static int isp_video_queue_alloc(struct isp_video_queue *queue,
623 unsigned int size, enum v4l2_memory memory) 606 unsigned int size, enum v4l2_memory memory)
624{ 607{
625 struct isp_video_buffer *buf; 608 struct isp_video_buffer *buf;
609 dma_addr_t dma;
626 unsigned int i; 610 unsigned int i;
627 void *mem; 611 void *mem;
628 int ret; 612 int ret;
@@ -646,7 +630,8 @@ static int isp_video_queue_alloc(struct isp_video_queue *queue,
646 /* Allocate video buffers memory for mmap mode. Align 630 /* Allocate video buffers memory for mmap mode. Align
647 * the size to the page size. 631 * the size to the page size.
648 */ 632 */
649 mem = vmalloc_32_user(PAGE_ALIGN(size)); 633 mem = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size),
634 &dma, GFP_KERNEL);
650 if (mem == NULL) { 635 if (mem == NULL) {
651 kfree(buf); 636 kfree(buf);
652 break; 637 break;
@@ -654,6 +639,7 @@ static int isp_video_queue_alloc(struct isp_video_queue *queue,
654 639
655 buf->vbuf.m.offset = i * PAGE_ALIGN(size); 640 buf->vbuf.m.offset = i * PAGE_ALIGN(size);
656 buf->vaddr = mem; 641 buf->vaddr = mem;
642 buf->paddr = dma;
657 } 643 }
658 644
659 buf->vbuf.index = i; 645 buf->vbuf.index = i;
@@ -1094,10 +1080,17 @@ int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
1094 goto done; 1080 goto done;
1095 } 1081 }
1096 1082
1097 ret = remap_vmalloc_range(vma, buf->vaddr, 0); 1083 /* dma_mmap_coherent() uses vm_pgoff as an offset inside the buffer
1084 * while we used it to identify the buffer and want to map the whole
1085 * buffer.
1086 */
1087 vma->vm_pgoff = 0;
1088
1089 ret = dma_mmap_coherent(queue->dev, vma, buf->vaddr, buf->paddr, size);
1098 if (ret < 0) 1090 if (ret < 0)
1099 goto done; 1091 goto done;
1100 1092
1093 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
1101 vma->vm_ops = &isp_video_queue_vm_ops; 1094 vma->vm_ops = &isp_video_queue_vm_ops;
1102 vma->vm_private_data = buf; 1095 vma->vm_private_data = buf;
1103 isp_video_queue_vm_open(vma); 1096 isp_video_queue_vm_open(vma);
diff --git a/drivers/media/platform/omap3isp/ispqueue.h b/drivers/media/platform/omap3isp/ispqueue.h
index f78325dbcf49..e03af74ded28 100644
--- a/drivers/media/platform/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
@@ -68,6 +68,7 @@ enum isp_video_buffer_state {
68 * @prepared: Whether the buffer has been prepared 68 * @prepared: Whether the buffer has been prepared
69 * @skip_cache: Whether to skip cache management operations for this buffer 69 * @skip_cache: Whether to skip cache management operations for this buffer
70 * @vaddr: Memory virtual address (for kernel buffers) 70 * @vaddr: Memory virtual address (for kernel buffers)
71 * @paddr: Memory physicall address (for kernel buffers)
71 * @vm_flags: Buffer VMA flags (for userspace buffers) 72 * @vm_flags: Buffer VMA flags (for userspace buffers)
72 * @npages: Number of pages (for userspace buffers) 73 * @npages: Number of pages (for userspace buffers)
73 * @pages: Pages table (for userspace non-VM_PFNMAP buffers) 74 * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
@@ -86,6 +87,7 @@ struct isp_video_buffer {
86 87
87 /* For kernel buffers. */ 88 /* For kernel buffers. */
88 void *vaddr; 89 void *vaddr;
90 dma_addr_t paddr;
89 91
90 /* For userspace buffers. */ 92 /* For userspace buffers. */
91 vm_flags_t vm_flags; 93 vm_flags_t vm_flags;