[PATCH v4 4/4] media: pxa_camera: conversion to dmaengine

2015-08-30 Thread Robert Jarzmik
Convert pxa_camera to dmaengine. This removes all DMA registers
manipulation in favor of the more generic dmaengine API.

The functional level should be the same as before. The biggest change is
in the videobuf_sg_splice() function, which splits a videobuf-dma into
several scatterlists for 3 planes captures (Y, U, V).

Signed-off-by: Robert Jarzmik 
---
Since v1: Guennadi's fixes
  dma tasklet functions prototypes change (trivial move)
Since v2: sglist cut revamped with Guennadi's comments
Since v3: sglist split removed after Andrew's merge in -mm tree in lib/
  taken into account Vinod's change to DMA_CTRL_REUSE
---
 drivers/media/platform/soc_camera/Kconfig  |   1 +
 drivers/media/platform/soc_camera/pxa_camera.c | 404 +++--
 2 files changed, 172 insertions(+), 233 deletions(-)

diff --git a/drivers/media/platform/soc_camera/Kconfig 
b/drivers/media/platform/soc_camera/Kconfig
index f2776cd415ca..e5e2d6cf6638 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -30,6 +30,7 @@ config VIDEO_PXA27x
tristate "PXA27x Quick Capture Interface driver"
depends on VIDEO_DEV && PXA27x && SOC_CAMERA
select VIDEOBUF_DMA_SG
+   select SG_SPLIT
---help---
  This is a v4l2 driver for the PXA27x Quick Capture Interface
 
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
b/drivers/media/platform/soc_camera/pxa_camera.c
index cdfb93aaee43..969140634f3d 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -28,6 +28,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
@@ -38,7 +41,6 @@
 
 #include 
 
-#include 
 #include 
 
 #define PXA_CAM_VERSION "0.0.6"
@@ -175,21 +177,16 @@ enum pxa_camera_active_dma {
DMA_V = 0x4,
 };
 
-/* descriptor needed for the PXA DMA engine */
-struct pxa_cam_dma {
-   dma_addr_t  sg_dma;
-   struct pxa_dma_desc *sg_cpu;
-   size_t  sg_size;
-   int sglen;
-};
-
 /* buffer for one video frame */
 struct pxa_buffer {
/* common v4l buffer stuff -- must be first */
struct videobuf_buffer  vb;
u32 code;
/* our descriptor lists for Y, U and V channels */
-   struct pxa_cam_dma  dmas[3];
+   struct dma_async_tx_descriptor  *descs[3];
+   dma_cookie_tcookie[3];
+   struct scatterlist  *sg[3];
+   int sg_len[3];
int inwork;
enum pxa_camera_active_dma  active_dma;
 };
@@ -207,7 +204,7 @@ struct pxa_camera_dev {
void __iomem*base;
 
int channels;
-   unsigned intdma_chans[3];
+   struct dma_chan *dma_chans[3];
 
struct pxacamera_platform_data *pdata;
struct resource *res;
@@ -222,7 +219,6 @@ struct pxa_camera_dev {
spinlock_t  lock;
 
struct pxa_buffer   *active;
-   struct pxa_dma_desc *sg_tail[3];
struct tasklet_struct   task_eof;
 
u32 save_cicr[5];
@@ -259,7 +255,6 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, 
unsigned int *count,
 static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
 {
struct soc_camera_device *icd = vq->priv_data;
-   struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct videobuf_dmabuf *dma = videobuf_to_dma(>vb);
int i;
 
@@ -276,61 +271,40 @@ static void free_buffer(struct videobuf_queue *vq, struct 
pxa_buffer *buf)
if (buf->vb.state == VIDEOBUF_NEEDS_INIT)
return;
 
-   for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
-   if (buf->dmas[i].sg_cpu)
-   dma_free_coherent(ici->v4l2_dev.dev,
- buf->dmas[i].sg_size,
- buf->dmas[i].sg_cpu,
- buf->dmas[i].sg_dma);
-   buf->dmas[i].sg_cpu = NULL;
+   for (i = 0; i < 3 && buf->descs[i]; i++) {
+   dmaengine_desc_free(buf->descs[i]);
+   kfree(buf->sg[i]);
+   buf->descs[i] = NULL;
+   buf->sg[i] = NULL;
+   buf->sg_len[i] = 0;
}
videobuf_dma_unmap(vq->dev, dma);
videobuf_dma_free(dma);
 
buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
-  int sg_first_ofs, int size)
-{
-   int i, offset, dma_len, xfer_len;
-   struct scatterlist *sg;
-
-   offset = sg_first_ofs;
-   for_each_sg(sglist, sg, sglen, i) {
-   dma_len = sg_dma_len(sg);
-
-   /* PXA27x Developer's Manual 

[PATCH v4 4/4] media: pxa_camera: conversion to dmaengine

2015-08-30 Thread Robert Jarzmik
Convert pxa_camera to dmaengine. This removes all DMA registers
manipulation in favor of the more generic dmaengine API.

The functional level should be the same as before. The biggest change is
in the videobuf_sg_splice() function, which splits a videobuf-dma into
several scatterlists for 3 planes captures (Y, U, V).

Signed-off-by: Robert Jarzmik robert.jarz...@free.fr
---
Since v1: Guennadi's fixes
  dma tasklet functions prototypes change (trivial move)
Since v2: sglist cut revamped with Guennadi's comments
Since v3: sglist split removed after Andrew's merge in -mm tree in lib/
  taken into account Vinod's change to DMA_CTRL_REUSE
---
 drivers/media/platform/soc_camera/Kconfig  |   1 +
 drivers/media/platform/soc_camera/pxa_camera.c | 404 +++--
 2 files changed, 172 insertions(+), 233 deletions(-)

diff --git a/drivers/media/platform/soc_camera/Kconfig 
b/drivers/media/platform/soc_camera/Kconfig
index f2776cd415ca..e5e2d6cf6638 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -30,6 +30,7 @@ config VIDEO_PXA27x
tristate PXA27x Quick Capture Interface driver
depends on VIDEO_DEV  PXA27x  SOC_CAMERA
select VIDEOBUF_DMA_SG
+   select SG_SPLIT
---help---
  This is a v4l2 driver for the PXA27x Quick Capture Interface
 
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c 
b/drivers/media/platform/soc_camera/pxa_camera.c
index cdfb93aaee43..969140634f3d 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -28,6 +28,9 @@
 #include linux/clk.h
 #include linux/sched.h
 #include linux/slab.h
+#include linux/dmaengine.h
+#include linux/dma-mapping.h
+#include linux/dma/pxa-dma.h
 
 #include media/v4l2-common.h
 #include media/v4l2-dev.h
@@ -38,7 +41,6 @@
 
 #include linux/videodev2.h
 
-#include mach/dma.h
 #include linux/platform_data/camera-pxa.h
 
 #define PXA_CAM_VERSION 0.0.6
@@ -175,21 +177,16 @@ enum pxa_camera_active_dma {
DMA_V = 0x4,
 };
 
-/* descriptor needed for the PXA DMA engine */
-struct pxa_cam_dma {
-   dma_addr_t  sg_dma;
-   struct pxa_dma_desc *sg_cpu;
-   size_t  sg_size;
-   int sglen;
-};
-
 /* buffer for one video frame */
 struct pxa_buffer {
/* common v4l buffer stuff -- must be first */
struct videobuf_buffer  vb;
u32 code;
/* our descriptor lists for Y, U and V channels */
-   struct pxa_cam_dma  dmas[3];
+   struct dma_async_tx_descriptor  *descs[3];
+   dma_cookie_tcookie[3];
+   struct scatterlist  *sg[3];
+   int sg_len[3];
int inwork;
enum pxa_camera_active_dma  active_dma;
 };
@@ -207,7 +204,7 @@ struct pxa_camera_dev {
void __iomem*base;
 
int channels;
-   unsigned intdma_chans[3];
+   struct dma_chan *dma_chans[3];
 
struct pxacamera_platform_data *pdata;
struct resource *res;
@@ -222,7 +219,6 @@ struct pxa_camera_dev {
spinlock_t  lock;
 
struct pxa_buffer   *active;
-   struct pxa_dma_desc *sg_tail[3];
struct tasklet_struct   task_eof;
 
u32 save_cicr[5];
@@ -259,7 +255,6 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, 
unsigned int *count,
 static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
 {
struct soc_camera_device *icd = vq-priv_data;
-   struct soc_camera_host *ici = to_soc_camera_host(icd-parent);
struct videobuf_dmabuf *dma = videobuf_to_dma(buf-vb);
int i;
 
@@ -276,61 +271,40 @@ static void free_buffer(struct videobuf_queue *vq, struct 
pxa_buffer *buf)
if (buf-vb.state == VIDEOBUF_NEEDS_INIT)
return;
 
-   for (i = 0; i  ARRAY_SIZE(buf-dmas); i++) {
-   if (buf-dmas[i].sg_cpu)
-   dma_free_coherent(ici-v4l2_dev.dev,
- buf-dmas[i].sg_size,
- buf-dmas[i].sg_cpu,
- buf-dmas[i].sg_dma);
-   buf-dmas[i].sg_cpu = NULL;
+   for (i = 0; i  3  buf-descs[i]; i++) {
+   dmaengine_desc_free(buf-descs[i]);
+   kfree(buf-sg[i]);
+   buf-descs[i] = NULL;
+   buf-sg[i] = NULL;
+   buf-sg_len[i] = 0;
}
videobuf_dma_unmap(vq-dev, dma);
videobuf_dma_free(dma);
 
buf-vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
-  int sg_first_ofs, int size)
-{
-   int i, offset, dma_len, xfer_len;
-   struct scatterlist