diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2014-01-06 14:21:54 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-25 10:14:02 -0400 |
commit | 73c1ea496cf79aec8a5681064719703b346301dc (patch) | |
tree | 1b2dc8ac1bca8af9f0f78248f093198f8c15ad43 /drivers/media | |
parent | 9000427aec61b2ae3766d0f635bf1d60fcb8c41b (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.c | 108 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispqueue.h | 6 |
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 | */ |
56 | static dma_addr_t | 55 | static dma_addr_t |
57 | ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen) | 56 | ispmmu_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 | */ |
82 | static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da) | 66 | static 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 | */ |
205 | static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf) | 186 | static 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 | */ |
243 | static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf) | 221 | static 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 | */ |
278 | static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf) | 252 | static 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; |