[RFC] [PATCH 3/3] staging: media: omap1: use dmaengine

Janusz Krzysztofik jmkrzyszt at gmail.com
Thu Jun 16 17:21:34 UTC 2016


Created and tested on Amstrad Delta on top of Linux-4.7-rc3 with
"staging: media: omap1: convert to videobuf2" applied.

Signed-off-by: Janusz Krzysztofik <jmkrzyszt at gmail.com>
---
 drivers/staging/media/omap1/Kconfig        |   2 +-
 drivers/staging/media/omap1/omap1_camera.c | 432 +++++++++--------------------
 2 files changed, 135 insertions(+), 299 deletions(-)

diff --git a/drivers/staging/media/omap1/Kconfig b/drivers/staging/media/omap1/Kconfig
index 12f1d7a..0b8456d 100644
--- a/drivers/staging/media/omap1/Kconfig
+++ b/drivers/staging/media/omap1/Kconfig
@@ -1,7 +1,7 @@
 config VIDEO_OMAP1
 	tristate "OMAP1 Camera Interface driver"
 	depends on VIDEO_DEV && SOC_CAMERA
-	depends on ARCH_OMAP1
+	depends on ARCH_OMAP1 && DMA_OMAP
 	depends on HAS_DMA
 	select VIDEOBUF2_DMA_CONTIG
 	---help---
diff --git a/drivers/staging/media/omap1/omap1_camera.c b/drivers/staging/media/omap1/omap1_camera.c
index 3761660..e22ba8a 100644
--- a/drivers/staging/media/omap1/omap1_camera.c
+++ b/drivers/staging/media/omap1/omap1_camera.c
@@ -33,11 +33,12 @@
 #include <media/drv-intf/soc_mediabus.h>
 #include <media/videobuf2-dma-contig.h>
 
-#include <linux/omap-dma.h>
+#include <linux/dmaengine.h>
+#include <linux/omap-dmaengine.h>
 
 
 #define DRIVER_NAME		"omap1-camera"
-#define DRIVER_VERSION		"0.0.4"
+#define DRIVER_VERSION		"0.0.5"
 
 #define OMAP_DMA_CAMERA_IF_RX		20
 
@@ -115,8 +116,8 @@
 #define DMA_BURST_SHIFT		(1 + OMAP_DMA_DATA_BURST_4)
 #define DMA_BURST_SIZE		BIT(DMA_BURST_SHIFT)
 
-#define DMA_ELEMENT_SHIFT	OMAP_DMA_DATA_TYPE_S32
-#define DMA_ELEMENT_SIZE	BIT(DMA_ELEMENT_SHIFT)
+#define DMA_ELEMENT_SIZE	DMA_SLAVE_BUSWIDTH_4_BYTES
+#define DMA_ELEMENT_SHIFT	__fls(DMA_ELEMENT_SIZE)
 
 #define DMA_FRAME_SHIFT		(FIFO_SHIFT - 1)
 #define DMA_FRAME_SIZE		BIT(DMA_FRAME_SHIFT)
@@ -124,7 +125,7 @@
 #define THRESHOLD_LEVEL		DMA_FRAME_SIZE
 
 #define OMAP1_CAMERA_MIN_BUF_COUNT \
-				3
+				2
 #define MAX_VIDEO_MEM		4	/* arbitrary video memory limit in MB */
 
 
@@ -145,7 +146,8 @@ struct omap1_cam_dev {
 	unsigned int			irq;
 	void __iomem			*base;
 
-	int				dma_ch;
+	struct dma_chan			*dma_chan;
+	unsigned int			dma_rq;
 
 	struct omap1_cam_platform_data	*pdata;
 	unsigned long			pflags;
@@ -156,10 +158,6 @@ struct omap1_cam_dev {
 	/* lock used to protect videobuf */
 	spinlock_t			lock;
 
-	/* Pointers to DMA buffers */
-	struct omap1_cam_buf		*active;
-	struct omap1_cam_buf		*ready;
-
 	struct vb2_alloc_ctx		*alloc_ctx;
 	int				sequence;
 
@@ -222,6 +220,16 @@ static int omap1_videobuf_setup(struct vb2_queue *vq, unsigned int *count,
 	return 0;
 }
 
+static int omap1_videobuf_init(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct omap1_cam_buf *buf = vb2_to_omap1_cam_buf(vbuf);
+
+	INIT_LIST_HEAD(&buf->queue);
+
+	return 0;
+}
+
 static int omap1_videobuf_prepare(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -236,96 +244,27 @@ static int omap1_videobuf_prepare(struct vb2_buffer *vb)
 			vb2_plane_size(vb, 0), size);
 		return -ENOBUFS;
 	}
-
 	vb2_set_plane_payload(vb, 0, size);
 
 	return 0;
 }
 
-static void set_dma_dest_params(int dma_ch, struct omap1_cam_buf *buf)
-{
-	dma_addr_t dma_addr =
-			vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
-	unsigned int block_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
-
-	omap_set_dma_dest_params(dma_ch,
-		OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0);
-	omap_set_dma_transfer_params(dma_ch,
-		OMAP_DMA_DATA_TYPE_S32, DMA_FRAME_SIZE,
-		block_size >> (DMA_FRAME_SHIFT + DMA_ELEMENT_SHIFT),
-		DMA_SYNC, 0, 0);
-}
-
-static struct omap1_cam_buf *prepare_next_vb(struct omap1_cam_dev *pcdev)
-{
-	struct omap1_cam_buf *buf;
-
-	/*
-	 * If there is already a buffer pointed out by the pcdev->ready,
-	 * (re)use it, otherwise try to fetch and configure a new one.
-	 */
-	buf = pcdev->ready;
-	if (!buf) {
-		if (list_empty(&pcdev->capture))
-			return buf;
-		buf = list_entry(pcdev->capture.next,
-				struct omap1_cam_buf, queue);
-		pcdev->ready = buf;
-		list_del_init(&buf->queue);
-	}
-
-	/*
-	 * In CONTIG mode, we can safely enter next buffer parameters
-	 * into the DMA programming register set after the DMA
-	 * has already been activated on the previous buffer
-	 */
-	set_dma_dest_params(pcdev->dma_ch, buf);
-
-	return buf;
-}
-
-static void start_capture(struct omap1_cam_dev *pcdev)
+static void omap1_dma_complete(void *data)
 {
-	struct omap1_cam_buf *buf = pcdev->active;
-	u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
-	u32 mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN;
-
-	if (WARN_ON(!buf))
-		return;
-
-	/*
-	 * Enable start of frame interrupt, which we will use for activating
-	 * our end of frame watchdog when capture actually starts.
-	 */
-	mode |= EN_V_UP;
-
-	if (unlikely(ctrlclock & LCLK_EN))
-		/* stop pixel clock before FIFO reset */
-		CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
-	/* reset FIFO */
-	CAM_WRITE(pcdev, MODE, mode | RAZ_FIFO);
-
-	omap_start_dma(pcdev->dma_ch);
-
-	/* (re)enable pixel clock */
-	CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | LCLK_EN);
-	/* release FIFO reset */
-	CAM_WRITE(pcdev, MODE, mode);
-}
-
-static void suspend_capture(struct omap1_cam_dev *pcdev)
-{
-	u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
-
-	CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
-	omap_stop_dma(pcdev->dma_ch);
-}
+	struct omap1_cam_buf *buf = data;
+	struct soc_camera_device *icd =
+			soc_camera_from_vb2q(buf->vb.vb2_buf.vb2_queue);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct omap1_cam_dev *pcdev = ici->priv;
 
-static void disable_capture(struct omap1_cam_dev *pcdev)
-{
-	u32 mode = CAM_READ_CACHE(pcdev, MODE);
+	spin_lock_irq(&pcdev->lock);
+	list_del_init(&buf->queue);
+	spin_unlock_irq(&pcdev->lock);
 
-	CAM_WRITE(pcdev, MODE, mode & ~(IRQ_MASK | DMA));
+	buf->vb.field = V4L2_FIELD_NONE;
+	buf->vb.sequence = pcdev->sequence++;
+	buf->vb.vb2_buf.timestamp = ktime_get_ns();
+	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 }
 
 static void omap1_videobuf_queue(struct vb2_buffer *vb)
@@ -335,214 +274,87 @@ static void omap1_videobuf_queue(struct vb2_buffer *vb)
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct omap1_cam_dev *pcdev = ici->priv;
 	struct omap1_cam_buf *buf = vb2_to_omap1_cam_buf(vbuf);
-	u32 mode;
-
-	list_add_tail(&buf->queue, &pcdev->capture);
-
-	if (pcdev->active) {
-		/*
-		 * Capture in progress, so don't touch pcdev->ready even if
-		 * empty. Since the transfer of the DMA programming register set
-		 * content to the DMA working register set is done automatically
-		 * by the DMA hardware, this can pretty well happen while we
-		 * are keeping the lock here. Leave fetching it from the queue
-		 * to be done when a next DMA interrupt occures instead.
-		 */
-		return;
-	}
-
-	WARN_ON(pcdev->ready);
-
-	buf = prepare_next_vb(pcdev);
-	if (WARN_ON(!buf))
-		return;
-
-	pcdev->active = buf;
-	pcdev->ready = NULL;
-
-	dev_dbg(icd->parent,
-		"%s: capture not active, setup FIFO, start DMA\n", __func__);
-	mode = CAM_READ_CACHE(pcdev, MODE) & ~THRESHOLD_MASK;
-	mode |= THRESHOLD_LEVEL << THRESHOLD_SHIFT;
-	CAM_WRITE(pcdev, MODE, mode | EN_FIFO_FULL | DMA);
-
-	start_capture(pcdev);
-}
-
-static void omap1_videobuf_release(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct omap1_cam_buf *buf = vb2_to_omap1_cam_buf(vbuf);
-
-	list_del_init(&buf->queue);
-}
-
-static int omap1_videobuf_init(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct omap1_cam_buf *buf = vb2_to_omap1_cam_buf(vbuf);
-
-	INIT_LIST_HEAD(&buf->queue);
-	return 0;
-}
-
-static void videobuf_done(struct omap1_cam_dev *pcdev,
-		enum vb2_buffer_state result)
-{
-	struct omap1_cam_buf *buf = pcdev->active;
-	struct vb2_v4l2_buffer *vb;
-	struct device *dev = pcdev->soc_host.icd->parent;
-
-	if (WARN_ON(!buf)) {
-		suspend_capture(pcdev);
-		disable_capture(pcdev);
-		return;
+	dma_addr_t dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+	unsigned int size = vb2_plane_size(vb, 0);
+	struct dma_async_tx_descriptor *dma_desc;
+
+	dma_desc = dmaengine_prep_slave_single(pcdev->dma_chan, dma_addr, size,
+					       DMA_DEV_TO_MEM, DMA_CTRL_ACK);
+	if (!dma_desc) {
+		dev_err(icd->parent, "Failed to prepare DMA transfer\n");
+		goto err;
 	}
 
-	if (result == VB2_BUF_STATE_ERROR)
-		suspend_capture(pcdev);
-
-	vb = &buf->vb;
-	if (!pcdev->ready && result != VB2_BUF_STATE_ERROR) {
-		/*
-		 * No next buffer has been entered into the DMA
-		 * programming register set on time (could be done only
-		 * while the previous DMA interurpt was processed, not
-		 * later), so the last DMA block (whole buffer) is
-		 * about to be reused by the just autoreinitialized DMA
-		 * engine, and overwritten with next frame data. Best we
-		 * can do is stopping the capture as soon as possible,
-		 * hopefully before the next frame start.
-		 */
-		suspend_capture(pcdev);
+	dma_desc->callback = omap1_dma_complete;
+	dma_desc->callback_param = (void *)buf;
+	if (dma_submit_error(dmaengine_submit(dma_desc))) {
+		dev_err(icd->parent, "DMA submission failed\n");
+		goto err;
 	}
-	vb->vb2_buf.timestamp = ktime_get_ns();
-	if (result != VB2_BUF_STATE_ERROR)
-		vb->sequence = pcdev->sequence++;
-	vb2_buffer_done(&vb->vb2_buf, result);
 
-	/* shift in next buffer */
-	buf = pcdev->ready;
-	pcdev->active = buf;
-	pcdev->ready = NULL;
-
-	if (!buf) {
-		/*
-		 * No next buffer was ready on time (see above), so
-		 * indicate error condition to force capture restart or
-		 * stop, depending on next buffer already queued or not.
-		 */
-		result = VB2_BUF_STATE_ERROR;
-		prepare_next_vb(pcdev);
-
-		buf = pcdev->ready;
-		pcdev->active = buf;
-		pcdev->ready = NULL;
-	}
-
-	if (!buf) {
-		dev_dbg(dev, "%s: no more videobufs, stop capture\n", __func__);
-		disable_capture(pcdev);
-		return;
-	}
+	spin_lock_irq(&pcdev->lock);
+	list_add_tail(&buf->queue, &pcdev->capture);
+	spin_unlock_irq(&pcdev->lock);
 
-	/*
-	 * the current buffer parameters had already
-	 * been entered into the DMA programming register set while the
-	 * buffer was fetched with prepare_next_vb(), they may have also
-	 * been transferred into the runtime set and already active if
-	 * the DMA still running.
-	 */
+	if (vb2_is_streaming(vb->vb2_queue))
+		dma_async_issue_pending(pcdev->dma_chan);
 
-	if (result == VB2_BUF_STATE_ERROR) {
-		dev_dbg(dev, "%s: videobuf error; reset FIFO, restart DMA\n",
-				__func__);
-		start_capture(pcdev);
-	}
+	return;
 
-	/*
-	 * Finally, try fetching next buffer.
-	 * That will also enter it into the DMA programming
-	 * register set, making it ready for next DMA autoreinitialization.
-	 */
-	prepare_next_vb(pcdev);
+err:
+	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 }
 
-static void omap1_stop_streaming(struct vb2_queue *vq)
+static int omap1_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct omap1_cam_dev *pcdev = ici->priv;
-	struct omap1_cam_buf *buf, *tmp;
-
-	spin_lock_irq(&pcdev->lock);
-
-	list_for_each_entry_safe(buf, tmp, &pcdev->capture, queue) {
-		list_del_init(&buf->queue);
-		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-	}
-
-	if (pcdev->ready)
-		videobuf_done(pcdev, VB2_BUF_STATE_ERROR);
-	if (pcdev->active)
-		videobuf_done(pcdev, VB2_BUF_STATE_ERROR);
-
-	spin_unlock_irq(&pcdev->lock);
-}
+	u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
+	u32 mode = CAM_READ_CACHE(pcdev, MODE);
 
-static void dma_isr(int channel, unsigned short status, void *data)
-{
-	struct omap1_cam_dev *pcdev = data;
-	struct omap1_cam_buf *buf = pcdev->active;
-	unsigned long flags;
+	mode &= ~THRESHOLD_MASK;
+	mode |= (THRESHOLD_LEVEL << THRESHOLD_SHIFT) | EN_FIFO_FULL | DMA;
+	CAM_WRITE(pcdev, MODE, mode);
 
-	spin_lock_irqsave(&pcdev->lock, flags);
+	if (unlikely(ctrlclock & LCLK_EN))
+		/* stop pixel clock before FIFO reset */
+		CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
+	/* reset FIFO */
+	CAM_WRITE(pcdev, MODE, mode | RAZ_FIFO);
 
-	if (WARN_ON(!buf)) {
-		suspend_capture(pcdev);
-		disable_capture(pcdev);
-		goto out;
-	}
+	dma_async_issue_pending(pcdev->dma_chan);
 
-	/*
-	 * Assume we have just managed to collect the
-	 * whole frame, hopefully before our end of frame watchdog is
-	 * triggered. Then, all we have to do is disabling the watchdog
-	 * for this frame, and calling videobuf_done() with success
-	 * indicated.
-	 */
-	CAM_WRITE(pcdev, MODE, CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN);
-	videobuf_done(pcdev, VB2_BUF_STATE_DONE);
+	/* (re)enable pixel clock */
+	CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | LCLK_EN);
+	/* release FIFO reset */
+	CAM_WRITE(pcdev, MODE, mode);
 
-out:
-	spin_unlock_irqrestore(&pcdev->lock, flags);
+	return 0;
 }
 
-static irqreturn_t cam_isr(int irq, void *data)
+static irqreturn_t omap1_cam_isr(int irq, void *data)
 {
 	struct omap1_cam_dev *pcdev = data;
-	struct device *dev = pcdev->soc_host.icd->parent;
-	struct omap1_cam_buf *buf = pcdev->active;
+	struct device *dev;
 	u32 it_status;
 	unsigned long flags;
-
-	it_status = CAM_READ(pcdev, IT_STATUS);
-	if (!it_status)
-		return IRQ_NONE;
+	irqreturn_t ret;
 
 	spin_lock_irqsave(&pcdev->lock, flags);
 
-	if (WARN_ON(!buf)) {
-		dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
-			 __func__, it_status);
-		suspend_capture(pcdev);
-		disable_capture(pcdev);
+	ret = IRQ_HANDLED;
+
+	it_status = CAM_READ(pcdev, IT_STATUS);
+	if (!it_status) {
+		ret = IRQ_NONE;
 		goto out;
 	}
 
+	dev = pcdev->soc_host.icd->parent;
+
 	if (unlikely(it_status & FIFO_FULL)) {
 		dev_warn(dev, "%s: FIFO overflow\n", __func__);
-
 	} else if (it_status & V_DOWN) {
 		/* End of video frame watchdog
 		 * the watchdog is disabled with
@@ -552,7 +364,6 @@ static irqreturn_t cam_isr(int irq, void *data)
 		 */
 		dev_notice(dev, "%s: unexpected end of video frame\n",
 				__func__);
-
 	} else if (it_status & V_UP) {
 		u32 mode;
 
@@ -568,28 +379,47 @@ static irqreturn_t cam_isr(int irq, void *data)
 		}
 		CAM_WRITE(pcdev, MODE, mode);
 		goto out;
-
 	} else {
 		dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
 				__func__, it_status);
 		goto out;
 	}
 
-	videobuf_done(pcdev, VB2_BUF_STATE_ERROR);
 out:
 	spin_unlock_irqrestore(&pcdev->lock, flags);
-	return IRQ_HANDLED;
+	return ret;
+}
+
+static void omap1_stop_streaming(struct vb2_queue *vq)
+{
+	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct omap1_cam_dev *pcdev = ici->priv;
+	struct omap1_cam_buf *buf, *tmp;
+	u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
+	u32 mode = CAM_READ_CACHE(pcdev, MODE);
+
+	CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
+	dmaengine_terminate_sync(pcdev->dma_chan);
+	CAM_WRITE(pcdev, MODE, mode & ~(IRQ_MASK | DMA));
+
+	spin_lock_irq(&pcdev->lock);
+	list_for_each_entry_safe(buf, tmp, &pcdev->capture, queue) {
+		list_del_init(&buf->queue);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+	spin_unlock_irq(&pcdev->lock);
 }
 
 static struct vb2_ops omap1_videobuf_ops = {
-	.queue_setup	= omap1_videobuf_setup,
-	.buf_prepare	= omap1_videobuf_prepare,
-	.buf_queue	= omap1_videobuf_queue,
-	.buf_cleanup	= omap1_videobuf_release,
-	.buf_init	= omap1_videobuf_init,
-	.wait_prepare	= vb2_ops_wait_prepare,
-	.wait_finish	= vb2_ops_wait_finish,
-	.stop_streaming	= omap1_stop_streaming,
+	.queue_setup		= omap1_videobuf_setup,
+	.buf_init		= omap1_videobuf_init,
+	.buf_prepare		= omap1_videobuf_prepare,
+	.buf_queue		= omap1_videobuf_queue,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+	.start_streaming	= omap1_start_streaming,
+	.stop_streaming		= omap1_stop_streaming,
 };
 
 
@@ -671,9 +501,6 @@ static void omap1_cam_clock_stop(struct soc_camera_host *ici)
 	struct omap1_cam_dev *pcdev = ici->priv;
 	u32 ctrlclock;
 
-	suspend_capture(pcdev);
-	disable_capture(pcdev);
-
 	sensor_reset(pcdev, true);
 
 	/* disable and release system clocks */
@@ -1206,6 +1033,8 @@ static int omap1_cam_probe(struct platform_device *pdev)
 	void __iomem *base;
 	unsigned int irq;
 	int err = 0;
+	dma_cap_mask_t mask;
+	struct dma_slave_config dma_cfg;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
@@ -1260,24 +1089,31 @@ static int omap1_cam_probe(struct platform_device *pdev)
 
 	sensor_reset(pcdev, true);
 
-	err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME,
-			dma_isr, (void *)pcdev, &pcdev->dma_ch);
-	if (err < 0) {
+	pcdev->dma_rq = OMAP_DMA_CAMERA_IF_RX;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	pcdev->dma_chan = __dma_request_channel(&mask, omap_dma_filter_fn,
+			(void *)&pcdev->dma_rq);
+	if (!pcdev->dma_chan) {
 		dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n");
 		return -EBUSY;
 	}
-	dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch);
+	dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan->chan_id);
 
 	/* preconfigure DMA */
-	omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB,
-			OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA,
-			0, 0);
-	omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4);
-	/* setup DMA autoinitialization */
-	omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch);
-
-	err = devm_request_irq(&pdev->dev, pcdev->irq, cam_isr, 0, DRIVER_NAME,
-			       pcdev);
+	memset(&dma_cfg, 0, sizeof(dma_cfg));
+	dma_cfg.direction = DMA_DEV_TO_MEM;
+	dma_cfg.src_addr = res->start + REG_CAMDATA;
+	dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dma_cfg.src_maxburst = DMA_FRAME_SIZE;
+	err = dmaengine_slave_config(pcdev->dma_chan, &dma_cfg);
+	if (err) {
+		dev_err(&pdev->dev, "DMA slave configuration failed\n");
+		goto exit_free_dma;
+	}
+
+	err = devm_request_irq(&pdev->dev, pcdev->irq, omap1_cam_isr, 0,
+			       DRIVER_NAME, pcdev);
 	if (err) {
 		dev_err(&pdev->dev, "Camera interrupt register failed\n");
 		goto exit_free_dma;
@@ -1310,7 +1146,7 @@ static int omap1_cam_probe(struct platform_device *pdev)
 exit_free_ctx:
 	vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
 exit_free_dma:
-	omap_free_dma(pcdev->dma_ch);
+	dma_release_channel(pcdev->dma_chan);
 	return err;
 }
 
@@ -1320,7 +1156,7 @@ static int omap1_cam_remove(struct platform_device *pdev)
 	struct omap1_cam_dev *pcdev = container_of(soc_host,
 					struct omap1_cam_dev, soc_host);
 
-	omap_free_dma(pcdev->dma_ch);
+	dma_release_channel(pcdev->dma_chan);
 
 	soc_camera_host_unregister(soc_host);
 
-- 
2.7.3



More information about the devel mailing list