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.pinch...@ideasonboard.com>
---
 drivers/media/platform/omap3isp/ispqueue.c | 108 ++++++++++-------------------
 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 8623c05..51ec40d 100644
--- a/drivers/media/platform/omap3isp/ispqueue.c
+++ b/drivers/media/platform/omap3isp/ispqueue.c
@@ -45,33 +45,17 @@
 #define IOMMU_FLAG     (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
 
 /*
- * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list
+ * ispmmu_vmap - Wrapper for virtual memory mapping of a scatter gather table
  * @dev: Device pointer specific to the OMAP3 ISP.
- * @sglist: Pointer to source Scatter gather list to allocate.
- * @sglen: Number of elements of the scatter-gatter list.
+ * @sgt: Pointer to source scatter gather table.
  *
  * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if
  * we ran out of memory.
  */
 static dma_addr_t
-ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int 
sglen)
+ispmmu_vmap(struct isp_device *isp, const struct sg_table *sgt)
 {
-       struct sg_table *sgt;
-       u32 da;
-
-       sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
-       if (sgt == NULL)
-               return -ENOMEM;
-
-       sgt->sgl = (struct scatterlist *)sglist;
-       sgt->nents = sglen;
-       sgt->orig_nents = sglen;
-
-       da = omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
-       if (IS_ERR_VALUE(da))
-               kfree(sgt);
-
-       return da;
+       return omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
 }
 
 /*
@@ -81,10 +65,7 @@ ispmmu_vmap(struct isp_device *isp, const struct scatterlist 
*sglist, int sglen)
  */
 static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
 {
-       struct sg_table *sgt;
-
-       sgt = omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
-       kfree(sgt);
+       omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
 }
 
 /* 
-----------------------------------------------------------------------------
@@ -204,34 +185,31 @@ out:
  */
 static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
 {
-       struct scatterlist *sglist;
+       struct scatterlist *sg;
        unsigned int npages;
        unsigned int i;
        void *addr;
+       int ret;
 
        addr = buf->vaddr;
        npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;
 
-       sglist = vmalloc(npages * sizeof(*sglist));
-       if (sglist == NULL)
-               return -ENOMEM;
-
-       sg_init_table(sglist, npages);
+       ret = sg_alloc_table(&buf->sgt, npages, GFP_KERNEL);
+       if (ret < 0)
+               return ret;
 
-       for (i = 0; i < npages; ++i, addr += PAGE_SIZE) {
+       for (sg = buf->sgt.sgl, i = 0; i < npages; ++i, addr += PAGE_SIZE) {
                struct page *page = vmalloc_to_page(addr);
 
                if (page == NULL || PageHighMem(page)) {
-                       vfree(sglist);
+                       sg_free_table(&buf->sgt);
                        return -EINVAL;
                }
 
-               sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
+               sg_set_page(sg, page, PAGE_SIZE, 0);
+               sg = sg_next(sg);
        }
 
-       buf->sglen = npages;
-       buf->sglist = sglist;
-
        return 0;
 }
 
@@ -242,30 +220,26 @@ static int isp_video_buffer_sglist_kernel(struct 
isp_video_buffer *buf)
  */
 static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
 {
-       struct scatterlist *sglist;
        unsigned int offset = buf->offset;
+       struct scatterlist *sg;
        unsigned int i;
+       int ret;
 
-       sglist = vmalloc(buf->npages * sizeof(*sglist));
-       if (sglist == NULL)
-               return -ENOMEM;
-
-       sg_init_table(sglist, buf->npages);
+       ret = sg_alloc_table(&buf->sgt, buf->npages, GFP_KERNEL);
+       if (ret < 0)
+               return ret;
 
-       for (i = 0; i < buf->npages; ++i) {
+       for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i) {
                if (PageHighMem(buf->pages[i])) {
-                       vfree(sglist);
+                       sg_free_table(&buf->sgt);
                        return -EINVAL;
                }
 
-               sg_set_page(&sglist[i], buf->pages[i], PAGE_SIZE - offset,
-                           offset);
+               sg_set_page(sg, buf->pages[i], PAGE_SIZE - offset, offset);
+               sg = sg_next(sg);
                offset = 0;
        }
 
-       buf->sglen = buf->npages;
-       buf->sglist = sglist;
-
        return 0;
 }
 
@@ -277,30 +251,26 @@ static int isp_video_buffer_sglist_user(struct 
isp_video_buffer *buf)
  */
 static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf)
 {
-       struct scatterlist *sglist;
+       struct scatterlist *sg;
        unsigned int offset = buf->offset;
        unsigned long pfn = buf->paddr >> PAGE_SHIFT;
        unsigned int i;
+       int ret;
 
-       sglist = vmalloc(buf->npages * sizeof(*sglist));
-       if (sglist == NULL)
-               return -ENOMEM;
-
-       sg_init_table(sglist, buf->npages);
+       ret = sg_alloc_table(&buf->sgt, buf->npages, GFP_KERNEL);
+       if (ret < 0)
+               return ret;
 
-       for (i = 0; i < buf->npages; ++i, ++pfn) {
-               sg_set_page(&sglist[i], pfn_to_page(pfn), PAGE_SIZE - offset,
-                           offset);
+       for (sg = buf->sgt.sgl, i = 0; i < buf->npages; ++i, ++pfn) {
+               sg_set_page(sg, pfn_to_page(pfn), PAGE_SIZE - offset, offset);
                /* PFNMAP buffers will not get DMA-mapped, set the DMA address
                 * manually.
                 */
-               sg_dma_address(&sglist[i]) = (pfn << PAGE_SHIFT) + offset;
+               sg_dma_address(sg) = (pfn << PAGE_SHIFT) + offset;
+               sg = sg_next(sg);
                offset = 0;
        }
 
-       buf->sglen = buf->npages;
-       buf->sglist = sglist;
-
        return 0;
 }
 
@@ -325,13 +295,11 @@ static void isp_video_buffer_cleanup(struct 
isp_video_buffer *buf)
        if (!(buf->vm_flags & VM_PFNMAP)) {
                direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
                          ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-               dma_unmap_sg(buf->queue->dev, buf->sglist, buf->sglen,
+               dma_unmap_sg(buf->queue->dev, buf->sgt.sgl, buf->sgt.orig_nents,
                             direction);
        }
 
-       vfree(buf->sglist);
-       buf->sglist = NULL;
-       buf->sglen = 0;
+       sg_free_table(&buf->sgt);
 
        if (buf->pages != NULL) {
                isp_video_buffer_lock_vma(buf, 0);
@@ -576,15 +544,15 @@ static int isp_video_buffer_prepare(struct 
isp_video_buffer *buf)
        if (!(buf->vm_flags & VM_PFNMAP)) {
                direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
                          ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-               ret = dma_map_sg(buf->queue->dev, buf->sglist, buf->sglen,
-                                direction);
-               if (ret != buf->sglen) {
+               ret = dma_map_sg(buf->queue->dev, buf->sgt.sgl,
+                                buf->sgt.orig_nents, direction);
+               if (ret != buf->sgt.orig_nents) {
                        ret = -EFAULT;
                        goto done;
                }
        }
 
-       addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
+       addr = ispmmu_vmap(video->isp, &buf->sgt);
        if (IS_ERR_VALUE(addr)) {
                ret = -EIO;
                goto done;
diff --git a/drivers/media/platform/omap3isp/ispqueue.h 
b/drivers/media/platform/omap3isp/ispqueue.h
index 0899a11..99c11e8 100644
--- a/drivers/media/platform/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
@@ -73,8 +73,7 @@ enum isp_video_buffer_state {
  * @npages: Number of pages (for userspace buffers)
  * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
  * @paddr: Memory physical address (for userspace VM_PFNMAP buffers)
- * @sglen: Number of elements in the scatter list (for non-VM_PFNMAP buffers)
- * @sglist: Scatter list (for non-VM_PFNMAP buffers)
+ * @sgt: Scatter gather table (for non-VM_PFNMAP buffers)
  * @vbuf: V4L2 buffer
  * @irqlist: List head for insertion into IRQ queue
  * @state: Current buffer state
@@ -98,8 +97,7 @@ struct isp_video_buffer {
        dma_addr_t paddr;
 
        /* For all buffers except VM_PFNMAP. */
-       unsigned int sglen;
-       struct scatterlist *sglist;
+       struct sg_table sgt;
 
        /* Touched by the interrupt handler. */
        struct v4l2_buffer vbuf;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to