aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-01-06 14:21:54 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-25 10:14:02 -0400
commit73c1ea496cf79aec8a5681064719703b346301dc (patch)
tree1b2dc8ac1bca8af9f0f78248f093198f8c15ad43 /drivers/media
parent9000427aec61b2ae3766d0f635bf1d60fcb8c41b (diff)
[media] omap3isp: queue: Use sg_table structure
Replace the sglen and sglist fields stored in the buffer structure with an sg_table. This allows using the sg table allocation helper function. 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.c108
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.h6
2 files changed, 40 insertions, 74 deletions
diff --git a/drivers/media/platform/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c
index 8623c058734e..51ec40d6ea42 100644
--- a/drivers/media/platform/omap3isp/ispqueue.c
+++ b/drivers/media/platform/omap3isp/ispqueue.c
@@ -45,33 +45,17 @@
45#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8) 45#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
46 46
47/* 47/*
48 * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list 48 * ispmmu_vmap - Wrapper for virtual memory mapping of a scatter gather table
49 * @dev: Device pointer specific to the OMAP3 ISP. 49 * @dev: Device pointer specific to the OMAP3 ISP.
50 * @sglist: Pointer to source Scatter gather list to allocate. 50 * @sgt: Pointer to source scatter gather table.
51 * @sglen: Number of elements of the scatter-gatter list.
52 * 51 *
53 * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if 52 * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if
54 * we ran out of memory. 53 * we ran out of memory.
55 */ 54 */
56static dma_addr_t 55static dma_addr_t
57ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen) 56ispmmu_vmap(struct isp_device *isp, const struct sg_table *sgt)
58{ 57{
59 struct sg_table *sgt; 58 return omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
60 u32 da;
61
62 sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
63 if (sgt == NULL)
64 return -ENOMEM;
65
66 sgt->sgl = (struct scatterlist *)sglist;
67 sgt->nents = sglen;
68 sgt->orig_nents = sglen;
69
70 da = omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
71 if (IS_ERR_VALUE(da))
72 kfree(sgt);
73
74 return da;
75} 59}
76 60
77/* 61/*
@@ -81,10 +65,7 @@ ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
81 */ 65 */
82static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da) 66static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
83{ 67{
84 struct sg_table *sgt; 68 omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
85
86 sgt = omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
87 kfree(sgt);
88} 69}
89 70
90/* ----------------------------------------------------------------------------- 71/* -----------------------------------------------------------------------------
@@ -204,34 +185,31 @@ out:
204 */ 185 */
205static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf) 186static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
206{ 187{
207 struct scatterlist *sglist; 188 struct scatterlist *sg;
208 unsigned int npages; 189 unsigned int npages;
209 unsigned int i; 190 unsigned int i;
210 void *addr; 191 void *addr;
192 int ret;
211 193
212 addr = buf->vaddr; 194 addr = buf->vaddr;
213 npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT; 195 npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;
214 196
215 sglist = vmalloc(npages * sizeof(*sglist)); 197 ret = sg_alloc_table(&buf->sgt, npages, GFP_KERNEL);
216 if (sglist == NULL) 198 if (ret < 0)
217 return -ENOMEM; 199 return ret;
218
219 sg_init_table(sglist, npages);
220 200
221 for (i = 0; i < npages; ++i, addr += PAGE_SIZE) { 201 for (sg = buf->sgt.sgl, i = 0; i < npages; ++i, addr += PAGE_SIZE) {
222 struct page *page = vmalloc_to_page(addr); 202 struct page *page = vmalloc_to_page(addr);
223 203
224 if (page == NULL || PageHighMem(page)) { 204 if (page == NULL || PageHighMem(page)) {
225 vfree(sglist); 205 sg_free_table(&buf->sgt);
226 return -EINVAL; 206 return -EINVAL;
227 } 207 }
228 208
229 sg_set_page(&sglist[i], page, PAGE_SIZE, 0); 209 sg_set_page(sg, page, PAGE_SIZE, 0);
210 sg = sg_next(sg);
230 } 211 }
231 212
232 buf->sglen = npages;
233 buf->sglist = sglist;
234
235 return 0; 213 return 0;
236} 214}
237 215
@@ -242,30 +220,26 @@ static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
242 */ 220 */
243static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf) 221static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
244{ 222{
245 struct scatterlist *sglist;
246 unsigned int offset = buf->offset; 223 unsigned int offset = buf->offset;
224 struct scatterlist *sg;
247 unsigned int i; 225 unsigned int i;
226 int ret;
248 227
249 sglist = vmalloc(buf->npages * sizeof(*sglist)); 228 ret = sg_alloc_table(&buf->sgt, buf->npages, GFP_KERNEL);
250 if (sglist == NULL) 229 if (ret < 0)
251 return -ENOMEM; 230 return ret;
252
253 sg_init_table(sglist, buf->npages);
254 231
255 for (i = 0; i < buf->npages; ++i) { 232 for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i) {
256 if (PageHighMem(buf->pages[i])) { 233 if (PageHighMem(buf->pages[i])) {
257 vfree(sglist); 234 sg_free_table(&buf->sgt);
258 return -EINVAL; 235 return -EINVAL;
259 } 236 }
260 237
261 sg_set_page(&sglist[i], buf->pages[i], PAGE_SIZE - offset, 238 sg_set_page(sg, buf->pages[i], PAGE_SIZE - offset, offset);
262 offset); 239 sg = sg_next(sg);
263 offset = 0; 240 offset = 0;
264 } 241 }
265 242
266 buf->sglen = buf->npages;
267 buf->sglist = sglist;
268
269 return 0; 243 return 0;
270} 244}
271 245
@@ -277,30 +251,26 @@ static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
277 */ 251 */
278static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf) 252static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf)
279{ 253{
280 struct scatterlist *sglist; 254 struct scatterlist *sg;
281 unsigned int offset = buf->offset; 255 unsigned int offset = buf->offset;
282 unsigned long pfn = buf->paddr >> PAGE_SHIFT; 256 unsigned long pfn = buf->paddr >> PAGE_SHIFT;
283 unsigned int i; 257 unsigned int i;
258 int ret;
284 259
285 sglist = vmalloc(buf->npages * sizeof(*sglist)); 260 ret = sg_alloc_table(&buf->sgt, buf->npages, GFP_KERNEL);
286 if (sglist == NULL) 261 if (ret < 0)
287 return -ENOMEM; 262 return ret;
288
289 sg_init_table(sglist, buf->npages);
290 263
291 for (i = 0; i < buf->npages; ++i, ++pfn) { 264 for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) {
292 sg_set_page(&sglist[i], pfn_to_page(pfn), PAGE_SIZE - offset, 265 sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset);
293 offset);
294 /* PFNMAP buffers will not get DMA-mapped, set the DMA address 266 /* PFNMAP buffers will not get DMA-mapped, set the DMA address
295 * manually. 267 * manually.
296 */ 268 */
297 sg_dma_address(&sglist[i]) = (pfn << PAGE_SHIFT) + offset; 269 sg_dma_address(sg) = (pfn << PAGE_SHIFT) + offset;
270 sg = sg_next(sg);
298 offset = 0; 271 offset = 0;
299 } 272 }
300 273
301 buf->sglen = buf->npages;
302 buf->sglist = sglist;
303
304 return 0; 274 return 0;
305} 275}
306 276
@@ -325,13 +295,11 @@ static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
325 if (!(buf->vm_flags & VM_PFNMAP)) { 295 if (!(buf->vm_flags & VM_PFNMAP)) {
326 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE 296 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
327 ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 297 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
328 dma_unmap_sg(buf->queue->dev, buf->sglist, buf->sglen, 298 dma_unmap_sg(buf->queue->dev, buf->sgt.sgl, buf->sgt.orig_nents,
329 direction); 299 direction);
330 } 300 }
331 301
332 vfree(buf->sglist); 302 sg_free_table(&buf->sgt);
333 buf->sglist = NULL;
334 buf->sglen = 0;
335 303
336 if (buf->pages != NULL) { 304 if (buf->pages != NULL) {
337 isp_video_buffer_lock_vma(buf, 0); 305 isp_video_buffer_lock_vma(buf, 0);
@@ -576,15 +544,15 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
576 if (!(buf->vm_flags & VM_PFNMAP)) { 544 if (!(buf->vm_flags & VM_PFNMAP)) {
577 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE 545 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
578 ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 546 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
579 ret = dma_map_sg(buf->queue->dev, buf->sglist, buf->sglen, 547 ret = dma_map_sg(buf->queue->dev, buf->sgt.sgl,
580 direction); 548 buf->sgt.orig_nents, direction);
581 if (ret != buf->sglen) { 549 if (ret != buf->sgt.orig_nents) {
582 ret = -EFAULT; 550 ret = -EFAULT;
583 goto done; 551 goto done;
584 } 552 }
585 } 553 }
586 554
587 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen); 555 addr = ispmmu_vmap(video->isp, &buf->sgt);
588 if (IS_ERR_VALUE(addr)) { 556 if (IS_ERR_VALUE(addr)) {
589 ret = -EIO; 557 ret = -EIO;
590 goto done; 558 goto done;
diff --git a/drivers/media/platform/omap3isp/ispqueue.h b/drivers/media/platform/omap3isp/ispqueue.h
index 0899a116b4d5..99c11e8c6e9d 100644
--- a/drivers/media/platform/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
@@ -73,8 +73,7 @@ enum isp_video_buffer_state {
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 * @paddr: Memory physical address (for userspace VM_PFNMAP buffers) 75 * @paddr: Memory physical address (for userspace VM_PFNMAP buffers)
76 * @sglen: Number of elements in the scatter list (for non-VM_PFNMAP buffers) 76 * @sgt: Scatter gather table (for non-VM_PFNMAP buffers)
77 * @sglist: Scatter list (for non-VM_PFNMAP buffers)
78 * @vbuf: V4L2 buffer 77 * @vbuf: V4L2 buffer
79 * @irqlist: List head for insertion into IRQ queue 78 * @irqlist: List head for insertion into IRQ queue
80 * @state: Current buffer state 79 * @state: Current buffer state
@@ -98,8 +97,7 @@ struct isp_video_buffer {
98 dma_addr_t paddr; 97 dma_addr_t paddr;
99 98
100 /* For all buffers except VM_PFNMAP. */ 99 /* For all buffers except VM_PFNMAP. */
101 unsigned int sglen; 100 struct sg_table sgt;
102 struct scatterlist *sglist;
103 101
104 /* Touched by the interrupt handler. */ 102 /* Touched by the interrupt handler. */
105 struct v4l2_buffer vbuf; 103 struct v4l2_buffer vbuf;