All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-06 22:33 ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:33 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul
  Cc: Viresh Kumar, Stephen Warren, Linus Walleij, Srinidhi Kasagar,
	Barry Song, linuxppc-dev, linux-arm-kernel

[v2 - more or less same description.  Including lakml in cc for the full
set]

This patch series cleans up the handling of cookies in DMA engine drivers.
This is done by providing a set of inline library functions for common
tasks:

- moving the 'last completed cookie' into struct dma_chan - everyone
  has this in their driver private channel data structure

- consolidate allocation of cookies to DMA descriptors

- common way to update 'last completed cookie' value

- standard way to implement tx_status callback and update the residue

- consolidate initialization of cookies

- update implementations differing from the majority of DMA engine drivers
  to behave the same as the majority implementation in respect of cookies

What this means is that we get to the point where all DMA engine drivers
will hand out cookie value '2' as the first, and incrementing cookie
values up to INT_MAX, returning to cookie '1' as the next cookie.

Think of this patch series as round 1...  I am hoping over time that more
code can be consolidated between the DMA engine drivers and end up with a
consistent way to handle various common themes in DMA engine hardware
(like physical channel<->peripheral request signal selection.)

Overall, the diffstat looks like this:

 arch/arm/include/asm/hardware/iop_adma.h |    2 -
 drivers/dma/amba-pl08x.c                 |   38 ++++---------
 drivers/dma/at_hdmac.c                   |   48 ++++------------
 drivers/dma/at_hdmac_regs.h              |    2 -
 drivers/dma/coh901318.c                  |   39 +++----------
 drivers/dma/dmaengine.h                  |   89 ++++++++++++++++++++++++++++++
 drivers/dma/dw_dmac.c                    |   43 +++-----------
 drivers/dma/dw_dmac_regs.h               |    1 -
 drivers/dma/ep93xx_dma.c                 |   25 ++------
 drivers/dma/fsldma.c                     |   24 ++------
 drivers/dma/fsldma.h                     |    1 -
 drivers/dma/imx-dma.c                    |   32 ++---------
 drivers/dma/imx-sdma.c                   |   23 ++------
 drivers/dma/intel_mid_dma.c              |   37 +++---------
 drivers/dma/intel_mid_dma_regs.h         |    2 -
 drivers/dma/ioat/dma.c                   |   21 +++----
 drivers/dma/ioat/dma.h                   |   23 --------
 drivers/dma/ioat/dma_v2.c                |   13 ++---
 drivers/dma/ioat/dma_v3.c                |   11 ++--
 drivers/dma/iop-adma.c                   |   51 ++++-------------
 drivers/dma/ipu/ipu_idmac.c              |   22 ++-----
 drivers/dma/mpc512x_dma.c                |   25 +++------
 drivers/dma/mv_xor.c                     |   34 ++---------
 drivers/dma/mv_xor.h                     |    3 -
 drivers/dma/mxs-dma.c                    |   23 ++------
 drivers/dma/pch_dma.c                    |   34 ++---------
 drivers/dma/pl330.c                      |   36 ++----------
 drivers/dma/ppc4xx/adma.c                |   49 +++-------------
 drivers/dma/ppc4xx/adma.h                |    2 -
 drivers/dma/shdma.c                      |   30 +++-------
 drivers/dma/shdma.h                      |    1 -
 drivers/dma/sirf-dma.c                   |   23 ++------
 drivers/dma/ste_dma40.c                  |   36 +++---------
 drivers/dma/timb_dma.c                   |   28 +++-------
 drivers/dma/txx9dmac.c                   |   41 +++-----------
 drivers/dma/txx9dmac.h                   |    1 -
 include/linux/amba/pl08x.h               |    2 -
 include/linux/dmaengine.h                |    6 +-
 38 files changed, 293 insertions(+), 628 deletions(-)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-06 22:33 ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:33 UTC (permalink / raw)
  To: linux-arm-kernel

[v2 - more or less same description.  Including lakml in cc for the full
set]

This patch series cleans up the handling of cookies in DMA engine drivers.
This is done by providing a set of inline library functions for common
tasks:

- moving the 'last completed cookie' into struct dma_chan - everyone
  has this in their driver private channel data structure

- consolidate allocation of cookies to DMA descriptors

- common way to update 'last completed cookie' value

- standard way to implement tx_status callback and update the residue

- consolidate initialization of cookies

- update implementations differing from the majority of DMA engine drivers
  to behave the same as the majority implementation in respect of cookies

What this means is that we get to the point where all DMA engine drivers
will hand out cookie value '2' as the first, and incrementing cookie
values up to INT_MAX, returning to cookie '1' as the next cookie.

Think of this patch series as round 1...  I am hoping over time that more
code can be consolidated between the DMA engine drivers and end up with a
consistent way to handle various common themes in DMA engine hardware
(like physical channel<->peripheral request signal selection.)

Overall, the diffstat looks like this:

 arch/arm/include/asm/hardware/iop_adma.h |    2 -
 drivers/dma/amba-pl08x.c                 |   38 ++++---------
 drivers/dma/at_hdmac.c                   |   48 ++++------------
 drivers/dma/at_hdmac_regs.h              |    2 -
 drivers/dma/coh901318.c                  |   39 +++----------
 drivers/dma/dmaengine.h                  |   89 ++++++++++++++++++++++++++++++
 drivers/dma/dw_dmac.c                    |   43 +++-----------
 drivers/dma/dw_dmac_regs.h               |    1 -
 drivers/dma/ep93xx_dma.c                 |   25 ++------
 drivers/dma/fsldma.c                     |   24 ++------
 drivers/dma/fsldma.h                     |    1 -
 drivers/dma/imx-dma.c                    |   32 ++---------
 drivers/dma/imx-sdma.c                   |   23 ++------
 drivers/dma/intel_mid_dma.c              |   37 +++---------
 drivers/dma/intel_mid_dma_regs.h         |    2 -
 drivers/dma/ioat/dma.c                   |   21 +++----
 drivers/dma/ioat/dma.h                   |   23 --------
 drivers/dma/ioat/dma_v2.c                |   13 ++---
 drivers/dma/ioat/dma_v3.c                |   11 ++--
 drivers/dma/iop-adma.c                   |   51 ++++-------------
 drivers/dma/ipu/ipu_idmac.c              |   22 ++-----
 drivers/dma/mpc512x_dma.c                |   25 +++------
 drivers/dma/mv_xor.c                     |   34 ++---------
 drivers/dma/mv_xor.h                     |    3 -
 drivers/dma/mxs-dma.c                    |   23 ++------
 drivers/dma/pch_dma.c                    |   34 ++---------
 drivers/dma/pl330.c                      |   36 ++----------
 drivers/dma/ppc4xx/adma.c                |   49 +++-------------
 drivers/dma/ppc4xx/adma.h                |    2 -
 drivers/dma/shdma.c                      |   30 +++-------
 drivers/dma/shdma.h                      |    1 -
 drivers/dma/sirf-dma.c                   |   23 ++------
 drivers/dma/ste_dma40.c                  |   36 +++---------
 drivers/dma/timb_dma.c                   |   28 +++-------
 drivers/dma/txx9dmac.c                   |   41 +++-----------
 drivers/dma/txx9dmac.h                   |    1 -
 include/linux/amba/pl08x.h               |    2 -
 include/linux/dmaengine.h                |    6 +-
 38 files changed, 293 insertions(+), 628 deletions(-)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 1/9] dmaengine: mv_xor: remove write-only is_complete_cookie
  2012-03-06 22:33 ` Russell King - ARM Linux
  (?)
@ 2012-03-06 22:33 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:33 UTC (permalink / raw)
  To: linux-arm-kernel

mv_xor's is_complete_cookie is only ever written to, but never read.
This is silly, remove the write-only structure member.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/mv_xor.c |    1 -
 drivers/dma/mv_xor.h |    1 -
 2 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index e779b43..ad7d03f 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -826,7 +826,6 @@ static enum dma_status mv_xor_status(struct dma_chan *chan,
 
 	last_used = chan->cookie;
 	last_complete = mv_chan->completed_cookie;
-	mv_chan->is_complete_cookie = cookie;
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index 977b592..da04ac2 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -109,7 +109,6 @@ struct mv_xor_chan {
 #ifdef USE_TIMER
 	unsigned long		cleanup_time;
 	u32			current_on_last_cleanup;
-	dma_cookie_t		is_complete_cookie;
 #endif
 };
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 2/9] dmaengine: move last completed cookie into generic dma_chan structure
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-06 22:34   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:34 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul
  Cc: Viresh Kumar, Stephen Warren, Linus Walleij, Srinidhi Kasagar,
	Barry Song, linuxppc-dev, linux-arm-kernel

Every DMA engine implementation declares a last completed dma cookie
in their private dma channel structures.  This is pointless, and
forces driver specific code.  Move this out into the common dma_chan
structure.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/hardware/iop_adma.h |    2 --
 drivers/dma/amba-pl08x.c                 |    8 ++++----
 drivers/dma/at_hdmac.c                   |   10 +++++-----
 drivers/dma/at_hdmac_regs.h              |    2 --
 drivers/dma/coh901318.c                  |    7 +++----
 drivers/dma/dw_dmac.c                    |   10 +++++-----
 drivers/dma/dw_dmac_regs.h               |    1 -
 drivers/dma/ep93xx_dma.c                 |    8 +++-----
 drivers/dma/fsldma.c                     |    4 ++--
 drivers/dma/fsldma.h                     |    1 -
 drivers/dma/imx-dma.c                    |    7 +++----
 drivers/dma/imx-sdma.c                   |    5 ++---
 drivers/dma/intel_mid_dma.c              |    9 ++++-----
 drivers/dma/intel_mid_dma_regs.h         |    2 --
 drivers/dma/ioat/dma.c                   |    2 +-
 drivers/dma/ioat/dma.h                   |    4 +---
 drivers/dma/ioat/dma_v2.c                |    2 +-
 drivers/dma/ioat/dma_v3.c                |    2 +-
 drivers/dma/iop-adma.c                   |   10 +++++-----
 drivers/dma/ipu/ipu_idmac.c              |   10 ++++------
 drivers/dma/mpc512x_dma.c                |    7 +++----
 drivers/dma/mv_xor.c                     |    6 +++---
 drivers/dma/mv_xor.h                     |    2 --
 drivers/dma/mxs-dma.c                    |    5 ++---
 drivers/dma/pch_dma.c                    |    5 ++---
 drivers/dma/pl330.c                      |    9 +++------
 drivers/dma/ppc4xx/adma.c                |   10 +++++-----
 drivers/dma/ppc4xx/adma.h                |    2 --
 drivers/dma/shdma.c                      |   10 +++++-----
 drivers/dma/shdma.h                      |    1 -
 drivers/dma/sirf-dma.c                   |    7 +++----
 drivers/dma/ste_dma40.c                  |   10 +++-------
 drivers/dma/timb_dma.c                   |    7 +++----
 drivers/dma/txx9dmac.c                   |   10 +++++-----
 drivers/dma/txx9dmac.h                   |    1 -
 include/linux/amba/pl08x.h               |    2 --
 include/linux/dmaengine.h                |    2 ++
 37 files changed, 83 insertions(+), 119 deletions(-)

diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h
index 59b8c38..122f86d 100644
--- a/arch/arm/include/asm/hardware/iop_adma.h
+++ b/arch/arm/include/asm/hardware/iop_adma.h
@@ -49,7 +49,6 @@ struct iop_adma_device {
 /**
  * struct iop_adma_chan - internal representation of an ADMA device
  * @pending: allows batching of hardware operations
- * @completed_cookie: identifier for the most recently completed operation
  * @lock: serializes enqueue/dequeue operations to the slot pool
  * @mmr_base: memory mapped register base
  * @chain: device chain view of the descriptors
@@ -62,7 +61,6 @@ struct iop_adma_device {
  */
 struct iop_adma_chan {
 	int pending;
-	dma_cookie_t completed_cookie;
 	spinlock_t lock; /* protects the descriptor slot pool */
 	void __iomem *mmr_base;
 	struct list_head chain;
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 8a28158..2b5121f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -971,7 +971,7 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
 	u32 bytesleft = 0;
 
 	last_used = plchan->chan.cookie;
-	last_complete = plchan->lc;
+	last_complete = plchan->chan.completed_cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret == DMA_SUCCESS) {
@@ -983,7 +983,7 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
 	 * This cookie not complete yet
 	 */
 	last_used = plchan->chan.cookie;
-	last_complete = plchan->lc;
+	last_complete = plchan->chan.completed_cookie;
 
 	/* Get number of bytes left in the active transactions and queue */
 	bytesleft = pl08x_getbytes_chan(plchan);
@@ -1541,7 +1541,7 @@ static void pl08x_tasklet(unsigned long data)
 
 	if (txd) {
 		/* Update last completed */
-		plchan->lc = txd->tx.cookie;
+		plchan->chan.completed_cookie = txd->tx.cookie;
 	}
 
 	/* If a new descriptor is queued, set it up plchan->at is NULL here */
@@ -1723,7 +1723,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
 
 		chan->chan.device = dmadev;
 		chan->chan.cookie = 0;
-		chan->lc = 0;
+		chan->chan.completed_cookie = 0;
 
 		spin_lock_init(&chan->lock);
 		INIT_LIST_HEAD(&chan->pend_list);
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index f4aed5f..6baf5d7 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -269,7 +269,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 	dev_vdbg(chan2dev(&atchan->chan_common),
 		"descriptor %u complete\n", txd->cookie);
 
-	atchan->completed_cookie = txd->cookie;
+	atchan->chan_common.completed_cookie = txd->cookie;
 
 	/* move children to free_list */
 	list_splice_init(&desc->tx_list, &atchan->free_list);
@@ -1016,14 +1016,14 @@ atc_tx_status(struct dma_chan *chan,
 
 	spin_lock_irqsave(&atchan->lock, flags);
 
-	last_complete = atchan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret != DMA_SUCCESS) {
 		atc_cleanup_descriptors(atchan);
 
-		last_complete = atchan->completed_cookie;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -1129,7 +1129,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
 	spin_lock_irqsave(&atchan->lock, flags);
 	atchan->descs_allocated = i;
 	list_splice(&tmp_list, &atchan->free_list);
-	atchan->completed_cookie = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 	spin_unlock_irqrestore(&atchan->lock, flags);
 
 	/* channel parameters */
@@ -1329,7 +1329,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
 		struct at_dma_chan	*atchan = &atdma->chan[i];
 
 		atchan->chan_common.device = &atdma->dma_common;
-		atchan->chan_common.cookie = atchan->completed_cookie = 1;
+		atchan->chan_common.cookie = atchan->chan_common.completed_cookie = 1;
 		list_add_tail(&atchan->chan_common.device_node,
 				&atdma->dma_common.channels);
 
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index a8d3277..08fd8a0 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -208,7 +208,6 @@ enum atc_status {
  * @save_dscr: for cyclic operations, preserve next descriptor address in
  *             the cyclic list on suspend/resume cycle
  * @lock: serializes enqueue/dequeue operations to descriptors lists
- * @completed_cookie: identifier for the most recently completed operation
  * @active_list: list of descriptors dmaengine is being running on
  * @queue: list of descriptors ready to be submitted to engine
  * @free_list: list of descriptors usable by the channel
@@ -227,7 +226,6 @@ struct at_dma_chan {
 	spinlock_t		lock;
 
 	/* these other elements are all protected by lock */
-	dma_cookie_t		completed_cookie;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index d65a718..521434b 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -59,7 +59,6 @@ struct coh901318_base {
 struct coh901318_chan {
 	spinlock_t lock;
 	int allocated;
-	int completed;
 	int id;
 	int stopped;
 
@@ -705,7 +704,7 @@ static void dma_tasklet(unsigned long data)
 	callback_param = cohd_fin->desc.callback_param;
 
 	/* sign this job as completed on the channel */
-	cohc->completed = cohd_fin->desc.cookie;
+	cohc->chan.completed_cookie = cohd_fin->desc.cookie;
 
 	/* release the lli allocation and remove the descriptor */
 	coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli);
@@ -929,7 +928,7 @@ static int coh901318_alloc_chan_resources(struct dma_chan *chan)
 	coh901318_config(cohc, NULL);
 
 	cohc->allocated = 1;
-	cohc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	spin_unlock_irqrestore(&cohc->lock, flags);
 
@@ -1169,7 +1168,7 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	dma_cookie_t last_complete;
 	int ret;
 
-	last_complete = cohc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 9b592b0..defe574 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -245,7 +245,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
 	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	dwc->completed = txd->cookie;
+	dwc->chan.completed_cookie = txd->cookie;
 	if (callback_required) {
 		callback = txd->callback;
 		param = txd->callback_param;
@@ -955,14 +955,14 @@ dwc_tx_status(struct dma_chan *chan,
 	dma_cookie_t		last_complete;
 	int			ret;
 
-	last_complete = dwc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret != DMA_SUCCESS) {
 		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
 
-		last_complete = dwc->completed;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -1004,7 +1004,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
 		return -EIO;
 	}
 
-	dwc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	/*
 	 * NOTE: some controllers may have additional features that we
@@ -1423,7 +1423,7 @@ static int __init dw_probe(struct platform_device *pdev)
 		struct dw_dma_chan	*dwc = &dw->chan[i];
 
 		dwc->chan.device = &dw->dma;
-		dwc->chan.cookie = dwc->completed = 1;
+		dwc->chan.cookie = dwc->chan.completed_cookie = 1;
 		if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
 			list_add_tail(&dwc->chan.device_node,
 					&dw->dma.channels);
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index 5eef694..cce1752 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -146,7 +146,6 @@ struct dw_dma_chan {
 
 	/* these other elements are all protected by lock */
 	unsigned long		flags;
-	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 59e7a96..bc45787 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -122,7 +122,6 @@ struct ep93xx_dma_desc {
  * @lock: lock protecting the fields following
  * @flags: flags for the channel
  * @buffer: which buffer to use next (0/1)
- * @last_completed: last completed cookie value
  * @active: flattened chain of descriptors currently being processed
  * @queue: pending descriptors which are handled next
  * @free_list: list of free descriptors which can be used
@@ -157,7 +156,6 @@ struct ep93xx_dma_chan {
 #define EP93XX_DMA_IS_CYCLIC		0
 
 	int				buffer;
-	dma_cookie_t			last_completed;
 	struct list_head		active;
 	struct list_head		queue;
 	struct list_head		free_list;
@@ -703,7 +701,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
 	desc = ep93xx_dma_get_active(edmac);
 	if (desc) {
 		if (desc->complete) {
-			edmac->last_completed = desc->txd.cookie;
+			edmac->chan.completed_cookie = desc->txd.cookie;
 			list_splice_init(&edmac->active, &list);
 		}
 		callback = desc->txd.callback;
@@ -861,7 +859,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
 		goto fail_clk_disable;
 
 	spin_lock_irq(&edmac->lock);
-	edmac->last_completed = 1;
+	edmac->chan.completed_cookie = 1;
 	edmac->chan.cookie = 1;
 	ret = edmac->edma->hw_setup(edmac);
 	spin_unlock_irq(&edmac->lock);
@@ -1254,7 +1252,7 @@ static enum dma_status ep93xx_dma_tx_status(struct dma_chan *chan,
 
 	spin_lock_irqsave(&edmac->lock, flags);
 	last_used = chan->cookie;
-	last_completed = edmac->last_completed;
+	last_completed = chan->completed_cookie;
 	spin_unlock_irqrestore(&edmac->lock, flags);
 
 	ret = dma_async_is_complete(cookie, last_completed, last_used);
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index b98070c..9b5cb8a 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -990,7 +990,7 @@ static enum dma_status fsl_tx_status(struct dma_chan *dchan,
 
 	spin_lock_irqsave(&chan->desc_lock, flags);
 
-	last_complete = chan->completed_cookie;
+	last_complete = dchan->completed_cookie;
 	last_used = dchan->cookie;
 
 	spin_unlock_irqrestore(&chan->desc_lock, flags);
@@ -1088,7 +1088,7 @@ static void dma_do_tasklet(unsigned long data)
 		desc = to_fsl_desc(chan->ld_running.prev);
 		cookie = desc->async_tx.cookie;
 
-		chan->completed_cookie = cookie;
+		chan->common.completed_cookie = cookie;
 		chan_dbg(chan, "completed_cookie=%d\n", cookie);
 	}
 
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index 9cb5aa5..f5c3879 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -137,7 +137,6 @@ struct fsldma_device {
 struct fsldma_chan {
 	char name[8];			/* Channel name */
 	struct fsldma_chan_regs __iomem *regs;
-	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
 	spinlock_t desc_lock;		/* Descriptor operation lock */
 	struct list_head ld_pending;	/* Link descriptors queue */
 	struct list_head ld_running;	/* Link descriptors queue */
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index e4383ee..321fc1f 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -41,7 +41,6 @@ struct imxdma_channel {
 	struct dma_chan			chan;
 	spinlock_t			lock;
 	struct dma_async_tx_descriptor	desc;
-	dma_cookie_t			last_completed;
 	enum dma_status			status;
 	int				dma_request;
 	struct scatterlist		*sg_list;
@@ -65,7 +64,7 @@ static void imxdma_handle(struct imxdma_channel *imxdmac)
 {
 	if (imxdmac->desc.callback)
 		imxdmac->desc.callback(imxdmac->desc.callback_param);
-	imxdmac->last_completed = imxdmac->desc.cookie;
+	imxdmac->chan.completed_cookie = imxdmac->desc.cookie;
 }
 
 static void imxdma_irq_handler(int channel, void *data)
@@ -158,8 +157,8 @@ static enum dma_status imxdma_tx_status(struct dma_chan *chan,
 
 	last_used = chan->cookie;
 
-	ret = dma_async_is_complete(cookie, imxdmac->last_completed, last_used);
-	dma_set_tx_state(txstate, imxdmac->last_completed, last_used, 0);
+	ret = dma_async_is_complete(cookie, chan->completed_cookie, last_used);
+	dma_set_tx_state(txstate, chan->completed_cookie, last_used, 0);
 
 	return ret;
 }
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 8bc5acf..e857904 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -266,7 +266,6 @@ struct sdma_channel {
 	struct dma_chan			chan;
 	spinlock_t			lock;
 	struct dma_async_tx_descriptor	desc;
-	dma_cookie_t			last_completed;
 	enum dma_status			status;
 	unsigned int			chn_count;
 	unsigned int			chn_real_count;
@@ -523,7 +522,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
 	else
 		sdmac->status = DMA_SUCCESS;
 
-	sdmac->last_completed = sdmac->desc.cookie;
+	sdmac->chan.completed_cookie = sdmac->desc.cookie;
 	if (sdmac->desc.callback)
 		sdmac->desc.callback(sdmac->desc.callback_param);
 }
@@ -1129,7 +1128,7 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
 
 	last_used = chan->cookie;
 
-	dma_set_tx_state(txstate, sdmac->last_completed, last_used,
+	dma_set_tx_state(txstate, chan->completed_cookie, last_used,
 			sdmac->chn_count - sdmac->chn_real_count);
 
 	return sdmac->status;
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 74f70aa..a27ae45 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -288,7 +288,7 @@ static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
 	struct intel_mid_dma_lli	*llitem;
 	void *param_txd = NULL;
 
-	midc->completed = txd->cookie;
+	midc->chan.completed_cookie = txd->cookie;
 	callback_txd = txd->callback;
 	param_txd = txd->callback_param;
 
@@ -482,12 +482,11 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 						dma_cookie_t cookie,
 						struct dma_tx_state *txstate)
 {
-	struct intel_mid_dma_chan	*midc = to_intel_mid_dma_chan(chan);
 	dma_cookie_t		last_used;
 	dma_cookie_t		last_complete;
 	int				ret;
 
-	last_complete = midc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -496,7 +495,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 		midc_scan_descriptors(to_middma_device(chan->device), midc);
 		spin_unlock_bh(&midc->lock);
 
-		last_complete = midc->completed;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -886,7 +885,7 @@ static int intel_mid_dma_alloc_chan_resources(struct dma_chan *chan)
 		pm_runtime_put(&mid->pdev->dev);
 		return -EIO;
 	}
-	midc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	spin_lock_bh(&midc->lock);
 	while (midc->descs_allocated < DESCS_PER_CHANNEL) {
diff --git a/drivers/dma/intel_mid_dma_regs.h b/drivers/dma/intel_mid_dma_regs.h
index c83d35b..1bfa926 100644
--- a/drivers/dma/intel_mid_dma_regs.h
+++ b/drivers/dma/intel_mid_dma_regs.h
@@ -165,7 +165,6 @@ union intel_mid_dma_cfg_hi {
  * @dma_base: MMIO register space DMA engine base pointer
  * @ch_id: DMA channel id
  * @lock: channel spinlock
- * @completed: DMA cookie
  * @active_list: current active descriptors
  * @queue: current queued up descriptors
  * @free_list: current free descriptors
@@ -183,7 +182,6 @@ struct intel_mid_dma_chan {
 	void __iomem		*dma_base;
 	int			ch_id;
 	spinlock_t		lock;
-	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index a4d6cb0..fab440a 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -603,7 +603,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
 		 */
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
-			chan->completed_cookie = tx->cookie;
+			chan->common.completed_cookie = tx->cookie;
 			tx->cookie = 0;
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
 			ioat->active -= desc->hw->tx_cnt;
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index 5216c8a..9653b6b 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -90,7 +90,6 @@ struct ioat_chan_common {
 	void __iomem *reg_base;
 	unsigned long last_completion;
 	spinlock_t cleanup_lock;
-	dma_cookie_t completed_cookie;
 	unsigned long state;
 	#define IOAT_COMPLETION_PENDING 0
 	#define IOAT_COMPLETION_ACK 1
@@ -153,12 +152,11 @@ static inline enum dma_status
 ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie,
 		 struct dma_tx_state *txstate)
 {
-	struct ioat_chan_common *chan = to_chan_common(c);
 	dma_cookie_t last_used;
 	dma_cookie_t last_complete;
 
 	last_used = c->cookie;
-	last_complete = chan->completed_cookie;
+	last_complete = c->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 5d65f83..d3f0aff 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -147,7 +147,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
-			chan->completed_cookie = tx->cookie;
+			chan->common.completed_cookie = tx->cookie;
 			tx->cookie = 0;
 			if (tx->callback) {
 				tx->callback(tx->callback_param);
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index f519c93..d4afac7 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -277,7 +277,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		tx = &desc->txd;
 		if (tx->cookie) {
-			chan->completed_cookie = tx->cookie;
+			chan->common.completed_cookie = tx->cookie;
 			ioat3_dma_unmap(ioat, desc, idx + i);
 			tx->cookie = 0;
 			if (tx->callback) {
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 04be90b..d8027c2 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -317,7 +317,7 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan)
 	}
 
 	if (cookie > 0) {
-		iop_chan->completed_cookie = cookie;
+		iop_chan->common.completed_cookie = cookie;
 		pr_debug("\tcompleted cookie %d\n", cookie);
 	}
 }
@@ -909,7 +909,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 	enum dma_status ret;
 
 	last_used = chan->cookie;
-	last_complete = iop_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret == DMA_SUCCESS)
@@ -918,7 +918,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 	iop_adma_slot_cleanup(iop_chan);
 
 	last_used = chan->cookie;
-	last_complete = iop_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
 	return dma_async_is_complete(cookie, last_complete, last_used);
@@ -1650,7 +1650,7 @@ static void iop_chan_start_null_memcpy(struct iop_adma_chan *iop_chan)
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
-		iop_chan->completed_cookie = cookie - 1;
+		iop_chan->common.completed_cookie = cookie - 1;
 		iop_chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
@@ -1707,7 +1707,7 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan)
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
-		iop_chan->completed_cookie = cookie - 1;
+		iop_chan->common.completed_cookie = cookie - 1;
 		iop_chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 6212b16..9149ade 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1295,7 +1295,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 	/* Flip the active buffer - even if update above failed */
 	ichan->active_buffer = !ichan->active_buffer;
 	if (done)
-		ichan->completed = desc->txd.cookie;
+		ichan->dma_chan.completed_cookie = desc->txd.cookie;
 
 	callback = desc->txd.callback;
 	callback_param = desc->txd.callback_param;
@@ -1511,7 +1511,7 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
 	WARN_ON(ichan->status != IPU_CHANNEL_FREE);
 
 	chan->cookie		= 1;
-	ichan->completed	= -ENXIO;
+	chan->completed_cookie	= -ENXIO;
 
 	ret = ipu_irq_map(chan->chan_id);
 	if (ret < 0)
@@ -1600,9 +1600,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
 static enum dma_status idmac_tx_status(struct dma_chan *chan,
 		       dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
-	struct idmac_channel *ichan = to_idmac_chan(chan);
-
-	dma_set_tx_state(txstate, ichan->completed, chan->cookie, 0);
+	dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie, 0);
 	if (cookie != chan->cookie)
 		return DMA_ERROR;
 	return DMA_SUCCESS;
@@ -1638,11 +1636,11 @@ static int __init ipu_idmac_init(struct ipu *ipu)
 
 		ichan->status		= IPU_CHANNEL_FREE;
 		ichan->sec_chan_en	= false;
-		ichan->completed	= -ENXIO;
 		snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i);
 
 		dma_chan->device	= &idmac->dma;
 		dma_chan->cookie	= 1;
+		dma_chan->completed_cookie	= -ENXIO;
 		dma_chan->chan_id	= i;
 		list_add_tail(&dma_chan->device_node, &dma->channels);
 	}
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 4d6d4cf..39a5cde 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -188,7 +188,6 @@ struct mpc_dma_chan {
 	struct list_head		completed;
 	struct mpc_dma_tcd		*tcd;
 	dma_addr_t			tcd_paddr;
-	dma_cookie_t			completed_cookie;
 
 	/* Lock for this structure */
 	spinlock_t			lock;
@@ -365,7 +364,7 @@ static void mpc_dma_process_completed(struct mpc_dma *mdma)
 		/* Free descriptors */
 		spin_lock_irqsave(&mchan->lock, flags);
 		list_splice_tail_init(&list, &mchan->free);
-		mchan->completed_cookie = last_cookie;
+		mchan->chan.completed_cookie = last_cookie;
 		spin_unlock_irqrestore(&mchan->lock, flags);
 	}
 }
@@ -568,7 +567,7 @@ mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 
 	spin_lock_irqsave(&mchan->lock, flags);
 	last_used = mchan->chan.cookie;
-	last_complete = mchan->completed_cookie;
+	last_complete = mchan->chan.completed_cookie;
 	spin_unlock_irqrestore(&mchan->lock, flags);
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
@@ -742,7 +741,7 @@ static int __devinit mpc_dma_probe(struct platform_device *op)
 
 		mchan->chan.device = dma;
 		mchan->chan.cookie = 1;
-		mchan->completed_cookie = mchan->chan.cookie;
+		mchan->chan.completed_cookie = mchan->chan.cookie;
 
 		INIT_LIST_HEAD(&mchan->free);
 		INIT_LIST_HEAD(&mchan->prepared);
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index ad7d03f..c6a84da 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -435,7 +435,7 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
 	}
 
 	if (cookie > 0)
-		mv_chan->completed_cookie = cookie;
+		mv_chan->common.completed_cookie = cookie;
 }
 
 static void
@@ -825,7 +825,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan,
 	enum dma_status ret;
 
 	last_used = chan->cookie;
-	last_complete = mv_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -836,7 +836,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan,
 	mv_xor_slot_cleanup(mv_chan);
 
 	last_used = chan->cookie;
-	last_complete = mv_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 	return dma_async_is_complete(cookie, last_complete, last_used);
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index da04ac2..654876b 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -78,7 +78,6 @@ struct mv_xor_device {
 /**
  * struct mv_xor_chan - internal representation of a XOR channel
  * @pending: allows batching of hardware operations
- * @completed_cookie: identifier for the most recently completed operation
  * @lock: serializes enqueue/dequeue operations to the descriptors pool
  * @mmr_base: memory mapped register base
  * @idx: the index of the xor channel
@@ -93,7 +92,6 @@ struct mv_xor_device {
  */
 struct mv_xor_chan {
 	int			pending;
-	dma_cookie_t		completed_cookie;
 	spinlock_t		lock; /* protects the descriptor slot pool */
 	void __iomem		*mmr_base;
 	unsigned int		idx;
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index b06cd4c..3696e6e 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -111,7 +111,6 @@ struct mxs_dma_chan {
 	struct mxs_dma_ccw		*ccw;
 	dma_addr_t			ccw_phys;
 	int				desc_count;
-	dma_cookie_t			last_completed;
 	enum dma_status			status;
 	unsigned int			flags;
 #define MXS_DMA_SG_LOOP			(1 << 0)
@@ -274,7 +273,7 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
 		stat1 &= ~(1 << channel);
 
 		if (mxs_chan->status == DMA_SUCCESS)
-			mxs_chan->last_completed = mxs_chan->desc.cookie;
+			mxs_chan->chan.completed_cookie = mxs_chan->desc.cookie;
 
 		/* schedule tasklet on this channel */
 		tasklet_schedule(&mxs_chan->tasklet);
@@ -538,7 +537,7 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,
 	dma_cookie_t last_used;
 
 	last_used = chan->cookie;
-	dma_set_tx_state(txstate, mxs_chan->last_completed, last_used, 0);
+	dma_set_tx_state(txstate, chan->completed_cookie, last_used, 0);
 
 	return mxs_chan->status;
 }
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 823f581..79a7185 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -105,7 +105,6 @@ struct pch_dma_chan {
 
 	spinlock_t		lock;
 
-	dma_cookie_t		completed_cookie;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
@@ -544,7 +543,7 @@ static int pd_alloc_chan_resources(struct dma_chan *chan)
 	spin_lock_irq(&pd_chan->lock);
 	list_splice(&tmp_list, &pd_chan->free_list);
 	pd_chan->descs_allocated = i;
-	pd_chan->completed_cookie = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 	spin_unlock_irq(&pd_chan->lock);
 
 	pdc_enable_irq(chan, 1);
@@ -583,7 +582,7 @@ static enum dma_status pd_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	int ret;
 
 	spin_lock_irq(&pd_chan->lock);
-	last_completed = pd_chan->completed_cookie;
+	last_completed = chan->completed_cookie;
 	last_used = chan->cookie;
 	spin_unlock_irq(&pd_chan->lock);
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index b8ec03e..bdf04f1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -51,9 +51,6 @@ struct dma_pl330_chan {
 	/* DMA-Engine Channel */
 	struct dma_chan chan;
 
-	/* Last completed cookie */
-	dma_cookie_t completed;
-
 	/* List of to be xfered descriptors */
 	struct list_head work_list;
 
@@ -234,7 +231,7 @@ static void pl330_tasklet(unsigned long data)
 	/* Pick up ripe tomatoes */
 	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
 		if (desc->status == DONE) {
-			pch->completed = desc->txd.cookie;
+			pch->chan.completed_cookie = desc->txd.cookie;
 			list_move_tail(&desc->node, &list);
 		}
 
@@ -305,7 +302,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
 
 	spin_lock_irqsave(&pch->lock, flags);
 
-	pch->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 	pch->cyclic = false;
 
 	pch->pl330_chid = pl330_request_channel(&pdmac->pif);
@@ -400,7 +397,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	dma_cookie_t last_done, last_used;
 	int ret;
 
-	last_done = pch->completed;
+	last_done = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_done, last_used);
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index fc457a7..f878322 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -1930,7 +1930,7 @@ static void __ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan)
 				if (end_of_chain && slot_cnt) {
 					/* Should wait for ZeroSum completion */
 					if (cookie > 0)
-						chan->completed_cookie = cookie;
+						chan->common.completed_cookie = cookie;
 					return;
 				}
 
@@ -1960,7 +1960,7 @@ static void __ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan)
 	BUG_ON(!seen_current);
 
 	if (cookie > 0) {
-		chan->completed_cookie = cookie;
+		chan->common.completed_cookie = cookie;
 		pr_debug("\tcompleted cookie %d\n", cookie);
 	}
 
@@ -3950,7 +3950,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan,
 
 	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
 	last_used = chan->cookie;
-	last_complete = ppc440spe_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
@@ -3961,7 +3961,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan,
 	ppc440spe_adma_slot_cleanup(ppc440spe_chan);
 
 	last_used = chan->cookie;
-	last_complete = ppc440spe_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
@@ -4058,7 +4058,7 @@ static void ppc440spe_chan_start_null_xor(struct ppc440spe_adma_chan *chan)
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
-		chan->completed_cookie = cookie - 1;
+		chan->common.completed_cookie = cookie - 1;
 		chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
diff --git a/drivers/dma/ppc4xx/adma.h b/drivers/dma/ppc4xx/adma.h
index 8ada5a8..26b7a5e 100644
--- a/drivers/dma/ppc4xx/adma.h
+++ b/drivers/dma/ppc4xx/adma.h
@@ -81,7 +81,6 @@ struct ppc440spe_adma_device {
  * @common: common dmaengine channel object members
  * @all_slots: complete domain of slots usable by the channel
  * @pending: allows batching of hardware operations
- * @completed_cookie: identifier for the most recently completed operation
  * @slots_allocated: records the actual size of the descriptor slot pool
  * @hw_chain_inited: h/w descriptor chain initialization flag
  * @irq_tasklet: bottom half where ppc440spe_adma_slot_cleanup runs
@@ -99,7 +98,6 @@ struct ppc440spe_adma_chan {
 	struct list_head all_slots;
 	struct ppc440spe_adma_desc_slot *last_used;
 	int pending;
-	dma_cookie_t completed_cookie;
 	int slots_allocated;
 	int hw_chain_inited;
 	struct tasklet_struct irq_tasklet;
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 812fd76..ae84c12 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -764,12 +764,12 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
 			cookie = tx->cookie;
 
 		if (desc->mark == DESC_COMPLETED && desc->chunks == 1) {
-			if (sh_chan->completed_cookie != desc->cookie - 1)
+			if (sh_chan->common.completed_cookie != desc->cookie - 1)
 				dev_dbg(sh_chan->dev,
 					"Completing cookie %d, expected %d\n",
 					desc->cookie,
-					sh_chan->completed_cookie + 1);
-			sh_chan->completed_cookie = desc->cookie;
+					sh_chan->common.completed_cookie + 1);
+			sh_chan->common.completed_cookie = desc->cookie;
 		}
 
 		/* Call callback on the last chunk */
@@ -823,7 +823,7 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
 		 * Terminating and the loop completed normally: forgive
 		 * uncompleted cookies
 		 */
-		sh_chan->completed_cookie = sh_chan->common.cookie;
+		sh_chan->common.completed_cookie = sh_chan->common.cookie;
 
 	spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
 
@@ -891,7 +891,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
 	sh_dmae_chan_ld_cleanup(sh_chan, false);
 
 	/* First read completed cookie to avoid a skew */
-	last_complete = sh_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	rmb();
 	last_used = chan->cookie;
 	BUG_ON(last_complete < 0);
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 2b55a27..0b1d2c1 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -30,7 +30,6 @@ enum dmae_pm_state {
 };
 
 struct sh_dmae_chan {
-	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
 	spinlock_t desc_lock;		/* Descriptor operation lock */
 	struct list_head ld_queue;	/* Link descriptors queue */
 	struct list_head ld_free;	/* Link descriptors free */
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 2333810..60473f0 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -59,7 +59,6 @@ struct sirfsoc_dma_chan {
 	struct list_head		queued;
 	struct list_head		active;
 	struct list_head		completed;
-	dma_cookie_t			completed_cookie;
 	unsigned long			happened_cyclic;
 	unsigned long			completed_cyclic;
 
@@ -208,7 +207,7 @@ static void sirfsoc_dma_process_completed(struct sirfsoc_dma *sdma)
 			/* Free descriptors */
 			spin_lock_irqsave(&schan->lock, flags);
 			list_splice_tail_init(&list, &schan->free);
-			schan->completed_cookie = last_cookie;
+			schan->chan.completed_cookie = last_cookie;
 			spin_unlock_irqrestore(&schan->lock, flags);
 		} else {
 			/* for cyclic channel, desc is always in active list */
@@ -419,7 +418,7 @@ sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 
 	spin_lock_irqsave(&schan->lock, flags);
 	last_used = schan->chan.cookie;
-	last_complete = schan->completed_cookie;
+	last_complete = schan->chan.completed_cookie;
 	spin_unlock_irqrestore(&schan->lock, flags);
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
@@ -636,7 +635,7 @@ static int __devinit sirfsoc_dma_probe(struct platform_device *op)
 
 		schan->chan.device = dma;
 		schan->chan.cookie = 1;
-		schan->completed_cookie = schan->chan.cookie;
+		schan->chan.completed_cookie = schan->chan.cookie;
 
 		INIT_LIST_HEAD(&schan->free);
 		INIT_LIST_HEAD(&schan->prepared);
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index cc5ecbc..cfca2a0 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -220,8 +220,6 @@ struct d40_base;
  *
  * @lock: A spinlock to protect this struct.
  * @log_num: The logical number, if any of this channel.
- * @completed: Starts with 1, after first interrupt it is set to dma engine's
- * current cookie.
  * @pending_tx: The number of pending transfers. Used between interrupt handler
  * and tasklet.
  * @busy: Set to true when transfer is ongoing on this channel.
@@ -250,8 +248,6 @@ struct d40_base;
 struct d40_chan {
 	spinlock_t			 lock;
 	int				 log_num;
-	/* ID of the most recent completed transfer */
-	int				 completed;
 	int				 pending_tx;
 	bool				 busy;
 	struct d40_phy_res		*phy_chan;
@@ -1357,7 +1353,7 @@ static void dma_tasklet(unsigned long data)
 		goto err;
 
 	if (!d40d->cyclic)
-		d40c->completed = d40d->txd.cookie;
+		d40c->chan.completed_cookie = d40d->txd.cookie;
 
 	/*
 	 * If terminating a channel pending_tx is set to zero.
@@ -2182,7 +2178,7 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
 	bool is_free_phy;
 	spin_lock_irqsave(&d40c->lock, flags);
 
-	d40c->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	/* If no dma configuration is set use default configuration (memcpy) */
 	if (!d40c->configured) {
@@ -2351,7 +2347,7 @@ static enum dma_status d40_tx_status(struct dma_chan *chan,
 		return -EINVAL;
 	}
 
-	last_complete = d40c->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	if (d40_is_paused(d40c))
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index a6f9c16..a1d1559 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -84,7 +84,6 @@ struct timb_dma_chan {
 					especially the lists and descriptors,
 					from races between the tasklet and calls
 					from above */
-	dma_cookie_t		last_completed_cookie;
 	bool			ongoing;
 	struct list_head	active_list;
 	struct list_head	queue;
@@ -284,7 +283,7 @@ static void __td_finish(struct timb_dma_chan *td_chan)
 	else
 		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR);
 */
-	td_chan->last_completed_cookie = txd->cookie;
+	td_chan->chan.completed_cookie = txd->cookie;
 	td_chan->ongoing = false;
 
 	callback = txd->callback;
@@ -481,7 +480,7 @@ static int td_alloc_chan_resources(struct dma_chan *chan)
 	}
 
 	spin_lock_bh(&td_chan->lock);
-	td_chan->last_completed_cookie = 1;
+	chan->completed_cookie = 1;
 	chan->cookie = 1;
 	spin_unlock_bh(&td_chan->lock);
 
@@ -523,7 +522,7 @@ static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 
 	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
 
-	last_complete = td_chan->last_completed_cookie;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 6122c36..a917b67 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -424,7 +424,7 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
 	dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
 		 txd->cookie, desc);
 
-	dc->completed = txd->cookie;
+	dc->chan.completed_cookie = txd->cookie;
 	callback = txd->callback;
 	param = txd->callback_param;
 
@@ -976,7 +976,7 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	dma_cookie_t last_complete;
 	int ret;
 
-	last_complete = dc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -985,7 +985,7 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		txx9dmac_scan_descriptors(dc);
 		spin_unlock_bh(&dc->lock);
 
-		last_complete = dc->completed;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -1057,7 +1057,7 @@ static int txx9dmac_alloc_chan_resources(struct dma_chan *chan)
 		return -EIO;
 	}
 
-	dc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	dc->ccr = TXX9_DMA_CCR_IMMCHN | TXX9_DMA_CCR_INTENE | CCR_LE;
 	txx9dmac_chan_set_SMPCHN(dc);
@@ -1186,7 +1186,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev)
 	dc->ddev->chan[ch] = dc;
 	dc->chan.device = &dc->dma;
 	list_add_tail(&dc->chan.device_node, &dc->chan.device->channels);
-	dc->chan.cookie = dc->completed = 1;
+	dc->chan.cookie = dc->chan.completed_cookie = 1;
 
 	if (is_dmac64(dc))
 		dc->ch_regs = &__txx9dmac_regs(dc->ddev)->CHAN[ch];
diff --git a/drivers/dma/txx9dmac.h b/drivers/dma/txx9dmac.h
index 365d423..f5a7605 100644
--- a/drivers/dma/txx9dmac.h
+++ b/drivers/dma/txx9dmac.h
@@ -172,7 +172,6 @@ struct txx9dmac_chan {
 	spinlock_t		lock;
 
 	/* these other elements are all protected by lock */
-	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 033f6aa..1bb134b 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -176,7 +176,6 @@ enum pl08x_dma_chan_state {
  * @runtime_addr: address for RX/TX according to the runtime config
  * @runtime_direction: current direction of this channel according to
  * runtime config
- * @lc: last completed transaction on this channel
  * @pend_list: queued transactions pending on this channel
  * @at: active transaction on this channel
  * @lock: a lock for this channel data
@@ -198,7 +197,6 @@ struct pl08x_dma_chan {
 	u32 src_cctl;
 	u32 dst_cctl;
 	enum dma_transfer_direction runtime_direction;
-	dma_cookie_t lc;
 	struct list_head pend_list;
 	struct pl08x_txd *at;
 	spinlock_t lock;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 679b349..41d0f92 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -257,6 +257,7 @@ struct dma_chan_percpu {
  * struct dma_chan - devices supply DMA channels, clients use them
  * @device: ptr to the dma device who supplies this channel, always !%NULL
  * @cookie: last cookie value returned to client
+ * @completed_cookie: last completed cookie for this channel
  * @chan_id: channel ID for sysfs
  * @dev: class device for sysfs
  * @device_node: used to add this to the device chan list
@@ -268,6 +269,7 @@ struct dma_chan_percpu {
 struct dma_chan {
 	struct dma_device *device;
 	dma_cookie_t cookie;
+	dma_cookie_t completed_cookie;
 
 	/* sysfs */
 	int chan_id;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 2/9] dmaengine: move last completed cookie into generic dma_chan structure
@ 2012-03-06 22:34   ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:34 UTC (permalink / raw)
  To: linux-arm-kernel

Every DMA engine implementation declares a last completed dma cookie
in their private dma channel structures.  This is pointless, and
forces driver specific code.  Move this out into the common dma_chan
structure.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/hardware/iop_adma.h |    2 --
 drivers/dma/amba-pl08x.c                 |    8 ++++----
 drivers/dma/at_hdmac.c                   |   10 +++++-----
 drivers/dma/at_hdmac_regs.h              |    2 --
 drivers/dma/coh901318.c                  |    7 +++----
 drivers/dma/dw_dmac.c                    |   10 +++++-----
 drivers/dma/dw_dmac_regs.h               |    1 -
 drivers/dma/ep93xx_dma.c                 |    8 +++-----
 drivers/dma/fsldma.c                     |    4 ++--
 drivers/dma/fsldma.h                     |    1 -
 drivers/dma/imx-dma.c                    |    7 +++----
 drivers/dma/imx-sdma.c                   |    5 ++---
 drivers/dma/intel_mid_dma.c              |    9 ++++-----
 drivers/dma/intel_mid_dma_regs.h         |    2 --
 drivers/dma/ioat/dma.c                   |    2 +-
 drivers/dma/ioat/dma.h                   |    4 +---
 drivers/dma/ioat/dma_v2.c                |    2 +-
 drivers/dma/ioat/dma_v3.c                |    2 +-
 drivers/dma/iop-adma.c                   |   10 +++++-----
 drivers/dma/ipu/ipu_idmac.c              |   10 ++++------
 drivers/dma/mpc512x_dma.c                |    7 +++----
 drivers/dma/mv_xor.c                     |    6 +++---
 drivers/dma/mv_xor.h                     |    2 --
 drivers/dma/mxs-dma.c                    |    5 ++---
 drivers/dma/pch_dma.c                    |    5 ++---
 drivers/dma/pl330.c                      |    9 +++------
 drivers/dma/ppc4xx/adma.c                |   10 +++++-----
 drivers/dma/ppc4xx/adma.h                |    2 --
 drivers/dma/shdma.c                      |   10 +++++-----
 drivers/dma/shdma.h                      |    1 -
 drivers/dma/sirf-dma.c                   |    7 +++----
 drivers/dma/ste_dma40.c                  |   10 +++-------
 drivers/dma/timb_dma.c                   |    7 +++----
 drivers/dma/txx9dmac.c                   |   10 +++++-----
 drivers/dma/txx9dmac.h                   |    1 -
 include/linux/amba/pl08x.h               |    2 --
 include/linux/dmaengine.h                |    2 ++
 37 files changed, 83 insertions(+), 119 deletions(-)

diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h
index 59b8c38..122f86d 100644
--- a/arch/arm/include/asm/hardware/iop_adma.h
+++ b/arch/arm/include/asm/hardware/iop_adma.h
@@ -49,7 +49,6 @@ struct iop_adma_device {
 /**
  * struct iop_adma_chan - internal representation of an ADMA device
  * @pending: allows batching of hardware operations
- * @completed_cookie: identifier for the most recently completed operation
  * @lock: serializes enqueue/dequeue operations to the slot pool
  * @mmr_base: memory mapped register base
  * @chain: device chain view of the descriptors
@@ -62,7 +61,6 @@ struct iop_adma_device {
  */
 struct iop_adma_chan {
 	int pending;
-	dma_cookie_t completed_cookie;
 	spinlock_t lock; /* protects the descriptor slot pool */
 	void __iomem *mmr_base;
 	struct list_head chain;
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 8a28158..2b5121f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -971,7 +971,7 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
 	u32 bytesleft = 0;
 
 	last_used = plchan->chan.cookie;
-	last_complete = plchan->lc;
+	last_complete = plchan->chan.completed_cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret == DMA_SUCCESS) {
@@ -983,7 +983,7 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
 	 * This cookie not complete yet
 	 */
 	last_used = plchan->chan.cookie;
-	last_complete = plchan->lc;
+	last_complete = plchan->chan.completed_cookie;
 
 	/* Get number of bytes left in the active transactions and queue */
 	bytesleft = pl08x_getbytes_chan(plchan);
@@ -1541,7 +1541,7 @@ static void pl08x_tasklet(unsigned long data)
 
 	if (txd) {
 		/* Update last completed */
-		plchan->lc = txd->tx.cookie;
+		plchan->chan.completed_cookie = txd->tx.cookie;
 	}
 
 	/* If a new descriptor is queued, set it up plchan->at is NULL here */
@@ -1723,7 +1723,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
 
 		chan->chan.device = dmadev;
 		chan->chan.cookie = 0;
-		chan->lc = 0;
+		chan->chan.completed_cookie = 0;
 
 		spin_lock_init(&chan->lock);
 		INIT_LIST_HEAD(&chan->pend_list);
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index f4aed5f..6baf5d7 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -269,7 +269,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 	dev_vdbg(chan2dev(&atchan->chan_common),
 		"descriptor %u complete\n", txd->cookie);
 
-	atchan->completed_cookie = txd->cookie;
+	atchan->chan_common.completed_cookie = txd->cookie;
 
 	/* move children to free_list */
 	list_splice_init(&desc->tx_list, &atchan->free_list);
@@ -1016,14 +1016,14 @@ atc_tx_status(struct dma_chan *chan,
 
 	spin_lock_irqsave(&atchan->lock, flags);
 
-	last_complete = atchan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret != DMA_SUCCESS) {
 		atc_cleanup_descriptors(atchan);
 
-		last_complete = atchan->completed_cookie;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -1129,7 +1129,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
 	spin_lock_irqsave(&atchan->lock, flags);
 	atchan->descs_allocated = i;
 	list_splice(&tmp_list, &atchan->free_list);
-	atchan->completed_cookie = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 	spin_unlock_irqrestore(&atchan->lock, flags);
 
 	/* channel parameters */
@@ -1329,7 +1329,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
 		struct at_dma_chan	*atchan = &atdma->chan[i];
 
 		atchan->chan_common.device = &atdma->dma_common;
-		atchan->chan_common.cookie = atchan->completed_cookie = 1;
+		atchan->chan_common.cookie = atchan->chan_common.completed_cookie = 1;
 		list_add_tail(&atchan->chan_common.device_node,
 				&atdma->dma_common.channels);
 
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index a8d3277..08fd8a0 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -208,7 +208,6 @@ enum atc_status {
  * @save_dscr: for cyclic operations, preserve next descriptor address in
  *             the cyclic list on suspend/resume cycle
  * @lock: serializes enqueue/dequeue operations to descriptors lists
- * @completed_cookie: identifier for the most recently completed operation
  * @active_list: list of descriptors dmaengine is being running on
  * @queue: list of descriptors ready to be submitted to engine
  * @free_list: list of descriptors usable by the channel
@@ -227,7 +226,6 @@ struct at_dma_chan {
 	spinlock_t		lock;
 
 	/* these other elements are all protected by lock */
-	dma_cookie_t		completed_cookie;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index d65a718..521434b 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -59,7 +59,6 @@ struct coh901318_base {
 struct coh901318_chan {
 	spinlock_t lock;
 	int allocated;
-	int completed;
 	int id;
 	int stopped;
 
@@ -705,7 +704,7 @@ static void dma_tasklet(unsigned long data)
 	callback_param = cohd_fin->desc.callback_param;
 
 	/* sign this job as completed on the channel */
-	cohc->completed = cohd_fin->desc.cookie;
+	cohc->chan.completed_cookie = cohd_fin->desc.cookie;
 
 	/* release the lli allocation and remove the descriptor */
 	coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli);
@@ -929,7 +928,7 @@ static int coh901318_alloc_chan_resources(struct dma_chan *chan)
 	coh901318_config(cohc, NULL);
 
 	cohc->allocated = 1;
-	cohc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	spin_unlock_irqrestore(&cohc->lock, flags);
 
@@ -1169,7 +1168,7 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	dma_cookie_t last_complete;
 	int ret;
 
-	last_complete = cohc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 9b592b0..defe574 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -245,7 +245,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
 	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	dwc->completed = txd->cookie;
+	dwc->chan.completed_cookie = txd->cookie;
 	if (callback_required) {
 		callback = txd->callback;
 		param = txd->callback_param;
@@ -955,14 +955,14 @@ dwc_tx_status(struct dma_chan *chan,
 	dma_cookie_t		last_complete;
 	int			ret;
 
-	last_complete = dwc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret != DMA_SUCCESS) {
 		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
 
-		last_complete = dwc->completed;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -1004,7 +1004,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
 		return -EIO;
 	}
 
-	dwc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	/*
 	 * NOTE: some controllers may have additional features that we
@@ -1423,7 +1423,7 @@ static int __init dw_probe(struct platform_device *pdev)
 		struct dw_dma_chan	*dwc = &dw->chan[i];
 
 		dwc->chan.device = &dw->dma;
-		dwc->chan.cookie = dwc->completed = 1;
+		dwc->chan.cookie = dwc->chan.completed_cookie = 1;
 		if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
 			list_add_tail(&dwc->chan.device_node,
 					&dw->dma.channels);
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index 5eef694..cce1752 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -146,7 +146,6 @@ struct dw_dma_chan {
 
 	/* these other elements are all protected by lock */
 	unsigned long		flags;
-	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 59e7a96..bc45787 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -122,7 +122,6 @@ struct ep93xx_dma_desc {
  * @lock: lock protecting the fields following
  * @flags: flags for the channel
  * @buffer: which buffer to use next (0/1)
- * @last_completed: last completed cookie value
  * @active: flattened chain of descriptors currently being processed
  * @queue: pending descriptors which are handled next
  * @free_list: list of free descriptors which can be used
@@ -157,7 +156,6 @@ struct ep93xx_dma_chan {
 #define EP93XX_DMA_IS_CYCLIC		0
 
 	int				buffer;
-	dma_cookie_t			last_completed;
 	struct list_head		active;
 	struct list_head		queue;
 	struct list_head		free_list;
@@ -703,7 +701,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
 	desc = ep93xx_dma_get_active(edmac);
 	if (desc) {
 		if (desc->complete) {
-			edmac->last_completed = desc->txd.cookie;
+			edmac->chan.completed_cookie = desc->txd.cookie;
 			list_splice_init(&edmac->active, &list);
 		}
 		callback = desc->txd.callback;
@@ -861,7 +859,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
 		goto fail_clk_disable;
 
 	spin_lock_irq(&edmac->lock);
-	edmac->last_completed = 1;
+	edmac->chan.completed_cookie = 1;
 	edmac->chan.cookie = 1;
 	ret = edmac->edma->hw_setup(edmac);
 	spin_unlock_irq(&edmac->lock);
@@ -1254,7 +1252,7 @@ static enum dma_status ep93xx_dma_tx_status(struct dma_chan *chan,
 
 	spin_lock_irqsave(&edmac->lock, flags);
 	last_used = chan->cookie;
-	last_completed = edmac->last_completed;
+	last_completed = chan->completed_cookie;
 	spin_unlock_irqrestore(&edmac->lock, flags);
 
 	ret = dma_async_is_complete(cookie, last_completed, last_used);
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index b98070c..9b5cb8a 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -990,7 +990,7 @@ static enum dma_status fsl_tx_status(struct dma_chan *dchan,
 
 	spin_lock_irqsave(&chan->desc_lock, flags);
 
-	last_complete = chan->completed_cookie;
+	last_complete = dchan->completed_cookie;
 	last_used = dchan->cookie;
 
 	spin_unlock_irqrestore(&chan->desc_lock, flags);
@@ -1088,7 +1088,7 @@ static void dma_do_tasklet(unsigned long data)
 		desc = to_fsl_desc(chan->ld_running.prev);
 		cookie = desc->async_tx.cookie;
 
-		chan->completed_cookie = cookie;
+		chan->common.completed_cookie = cookie;
 		chan_dbg(chan, "completed_cookie=%d\n", cookie);
 	}
 
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index 9cb5aa5..f5c3879 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -137,7 +137,6 @@ struct fsldma_device {
 struct fsldma_chan {
 	char name[8];			/* Channel name */
 	struct fsldma_chan_regs __iomem *regs;
-	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
 	spinlock_t desc_lock;		/* Descriptor operation lock */
 	struct list_head ld_pending;	/* Link descriptors queue */
 	struct list_head ld_running;	/* Link descriptors queue */
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index e4383ee..321fc1f 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -41,7 +41,6 @@ struct imxdma_channel {
 	struct dma_chan			chan;
 	spinlock_t			lock;
 	struct dma_async_tx_descriptor	desc;
-	dma_cookie_t			last_completed;
 	enum dma_status			status;
 	int				dma_request;
 	struct scatterlist		*sg_list;
@@ -65,7 +64,7 @@ static void imxdma_handle(struct imxdma_channel *imxdmac)
 {
 	if (imxdmac->desc.callback)
 		imxdmac->desc.callback(imxdmac->desc.callback_param);
-	imxdmac->last_completed = imxdmac->desc.cookie;
+	imxdmac->chan.completed_cookie = imxdmac->desc.cookie;
 }
 
 static void imxdma_irq_handler(int channel, void *data)
@@ -158,8 +157,8 @@ static enum dma_status imxdma_tx_status(struct dma_chan *chan,
 
 	last_used = chan->cookie;
 
-	ret = dma_async_is_complete(cookie, imxdmac->last_completed, last_used);
-	dma_set_tx_state(txstate, imxdmac->last_completed, last_used, 0);
+	ret = dma_async_is_complete(cookie, chan->completed_cookie, last_used);
+	dma_set_tx_state(txstate, chan->completed_cookie, last_used, 0);
 
 	return ret;
 }
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 8bc5acf..e857904 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -266,7 +266,6 @@ struct sdma_channel {
 	struct dma_chan			chan;
 	spinlock_t			lock;
 	struct dma_async_tx_descriptor	desc;
-	dma_cookie_t			last_completed;
 	enum dma_status			status;
 	unsigned int			chn_count;
 	unsigned int			chn_real_count;
@@ -523,7 +522,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
 	else
 		sdmac->status = DMA_SUCCESS;
 
-	sdmac->last_completed = sdmac->desc.cookie;
+	sdmac->chan.completed_cookie = sdmac->desc.cookie;
 	if (sdmac->desc.callback)
 		sdmac->desc.callback(sdmac->desc.callback_param);
 }
@@ -1129,7 +1128,7 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
 
 	last_used = chan->cookie;
 
-	dma_set_tx_state(txstate, sdmac->last_completed, last_used,
+	dma_set_tx_state(txstate, chan->completed_cookie, last_used,
 			sdmac->chn_count - sdmac->chn_real_count);
 
 	return sdmac->status;
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 74f70aa..a27ae45 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -288,7 +288,7 @@ static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
 	struct intel_mid_dma_lli	*llitem;
 	void *param_txd = NULL;
 
-	midc->completed = txd->cookie;
+	midc->chan.completed_cookie = txd->cookie;
 	callback_txd = txd->callback;
 	param_txd = txd->callback_param;
 
@@ -482,12 +482,11 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 						dma_cookie_t cookie,
 						struct dma_tx_state *txstate)
 {
-	struct intel_mid_dma_chan	*midc = to_intel_mid_dma_chan(chan);
 	dma_cookie_t		last_used;
 	dma_cookie_t		last_complete;
 	int				ret;
 
-	last_complete = midc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -496,7 +495,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 		midc_scan_descriptors(to_middma_device(chan->device), midc);
 		spin_unlock_bh(&midc->lock);
 
-		last_complete = midc->completed;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -886,7 +885,7 @@ static int intel_mid_dma_alloc_chan_resources(struct dma_chan *chan)
 		pm_runtime_put(&mid->pdev->dev);
 		return -EIO;
 	}
-	midc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	spin_lock_bh(&midc->lock);
 	while (midc->descs_allocated < DESCS_PER_CHANNEL) {
diff --git a/drivers/dma/intel_mid_dma_regs.h b/drivers/dma/intel_mid_dma_regs.h
index c83d35b..1bfa926 100644
--- a/drivers/dma/intel_mid_dma_regs.h
+++ b/drivers/dma/intel_mid_dma_regs.h
@@ -165,7 +165,6 @@ union intel_mid_dma_cfg_hi {
  * @dma_base: MMIO register space DMA engine base pointer
  * @ch_id: DMA channel id
  * @lock: channel spinlock
- * @completed: DMA cookie
  * @active_list: current active descriptors
  * @queue: current queued up descriptors
  * @free_list: current free descriptors
@@ -183,7 +182,6 @@ struct intel_mid_dma_chan {
 	void __iomem		*dma_base;
 	int			ch_id;
 	spinlock_t		lock;
-	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index a4d6cb0..fab440a 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -603,7 +603,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
 		 */
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
-			chan->completed_cookie = tx->cookie;
+			chan->common.completed_cookie = tx->cookie;
 			tx->cookie = 0;
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
 			ioat->active -= desc->hw->tx_cnt;
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index 5216c8a..9653b6b 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -90,7 +90,6 @@ struct ioat_chan_common {
 	void __iomem *reg_base;
 	unsigned long last_completion;
 	spinlock_t cleanup_lock;
-	dma_cookie_t completed_cookie;
 	unsigned long state;
 	#define IOAT_COMPLETION_PENDING 0
 	#define IOAT_COMPLETION_ACK 1
@@ -153,12 +152,11 @@ static inline enum dma_status
 ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie,
 		 struct dma_tx_state *txstate)
 {
-	struct ioat_chan_common *chan = to_chan_common(c);
 	dma_cookie_t last_used;
 	dma_cookie_t last_complete;
 
 	last_used = c->cookie;
-	last_complete = chan->completed_cookie;
+	last_complete = c->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 5d65f83..d3f0aff 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -147,7 +147,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
-			chan->completed_cookie = tx->cookie;
+			chan->common.completed_cookie = tx->cookie;
 			tx->cookie = 0;
 			if (tx->callback) {
 				tx->callback(tx->callback_param);
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index f519c93..d4afac7 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -277,7 +277,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		tx = &desc->txd;
 		if (tx->cookie) {
-			chan->completed_cookie = tx->cookie;
+			chan->common.completed_cookie = tx->cookie;
 			ioat3_dma_unmap(ioat, desc, idx + i);
 			tx->cookie = 0;
 			if (tx->callback) {
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 04be90b..d8027c2 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -317,7 +317,7 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan)
 	}
 
 	if (cookie > 0) {
-		iop_chan->completed_cookie = cookie;
+		iop_chan->common.completed_cookie = cookie;
 		pr_debug("\tcompleted cookie %d\n", cookie);
 	}
 }
@@ -909,7 +909,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 	enum dma_status ret;
 
 	last_used = chan->cookie;
-	last_complete = iop_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret == DMA_SUCCESS)
@@ -918,7 +918,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 	iop_adma_slot_cleanup(iop_chan);
 
 	last_used = chan->cookie;
-	last_complete = iop_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
 	return dma_async_is_complete(cookie, last_complete, last_used);
@@ -1650,7 +1650,7 @@ static void iop_chan_start_null_memcpy(struct iop_adma_chan *iop_chan)
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
-		iop_chan->completed_cookie = cookie - 1;
+		iop_chan->common.completed_cookie = cookie - 1;
 		iop_chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
@@ -1707,7 +1707,7 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan)
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
-		iop_chan->completed_cookie = cookie - 1;
+		iop_chan->common.completed_cookie = cookie - 1;
 		iop_chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 6212b16..9149ade 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1295,7 +1295,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 	/* Flip the active buffer - even if update above failed */
 	ichan->active_buffer = !ichan->active_buffer;
 	if (done)
-		ichan->completed = desc->txd.cookie;
+		ichan->dma_chan.completed_cookie = desc->txd.cookie;
 
 	callback = desc->txd.callback;
 	callback_param = desc->txd.callback_param;
@@ -1511,7 +1511,7 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
 	WARN_ON(ichan->status != IPU_CHANNEL_FREE);
 
 	chan->cookie		= 1;
-	ichan->completed	= -ENXIO;
+	chan->completed_cookie	= -ENXIO;
 
 	ret = ipu_irq_map(chan->chan_id);
 	if (ret < 0)
@@ -1600,9 +1600,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
 static enum dma_status idmac_tx_status(struct dma_chan *chan,
 		       dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
-	struct idmac_channel *ichan = to_idmac_chan(chan);
-
-	dma_set_tx_state(txstate, ichan->completed, chan->cookie, 0);
+	dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie, 0);
 	if (cookie != chan->cookie)
 		return DMA_ERROR;
 	return DMA_SUCCESS;
@@ -1638,11 +1636,11 @@ static int __init ipu_idmac_init(struct ipu *ipu)
 
 		ichan->status		= IPU_CHANNEL_FREE;
 		ichan->sec_chan_en	= false;
-		ichan->completed	= -ENXIO;
 		snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i);
 
 		dma_chan->device	= &idmac->dma;
 		dma_chan->cookie	= 1;
+		dma_chan->completed_cookie	= -ENXIO;
 		dma_chan->chan_id	= i;
 		list_add_tail(&dma_chan->device_node, &dma->channels);
 	}
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 4d6d4cf..39a5cde 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -188,7 +188,6 @@ struct mpc_dma_chan {
 	struct list_head		completed;
 	struct mpc_dma_tcd		*tcd;
 	dma_addr_t			tcd_paddr;
-	dma_cookie_t			completed_cookie;
 
 	/* Lock for this structure */
 	spinlock_t			lock;
@@ -365,7 +364,7 @@ static void mpc_dma_process_completed(struct mpc_dma *mdma)
 		/* Free descriptors */
 		spin_lock_irqsave(&mchan->lock, flags);
 		list_splice_tail_init(&list, &mchan->free);
-		mchan->completed_cookie = last_cookie;
+		mchan->chan.completed_cookie = last_cookie;
 		spin_unlock_irqrestore(&mchan->lock, flags);
 	}
 }
@@ -568,7 +567,7 @@ mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 
 	spin_lock_irqsave(&mchan->lock, flags);
 	last_used = mchan->chan.cookie;
-	last_complete = mchan->completed_cookie;
+	last_complete = mchan->chan.completed_cookie;
 	spin_unlock_irqrestore(&mchan->lock, flags);
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
@@ -742,7 +741,7 @@ static int __devinit mpc_dma_probe(struct platform_device *op)
 
 		mchan->chan.device = dma;
 		mchan->chan.cookie = 1;
-		mchan->completed_cookie = mchan->chan.cookie;
+		mchan->chan.completed_cookie = mchan->chan.cookie;
 
 		INIT_LIST_HEAD(&mchan->free);
 		INIT_LIST_HEAD(&mchan->prepared);
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index ad7d03f..c6a84da 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -435,7 +435,7 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
 	}
 
 	if (cookie > 0)
-		mv_chan->completed_cookie = cookie;
+		mv_chan->common.completed_cookie = cookie;
 }
 
 static void
@@ -825,7 +825,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan,
 	enum dma_status ret;
 
 	last_used = chan->cookie;
-	last_complete = mv_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -836,7 +836,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan,
 	mv_xor_slot_cleanup(mv_chan);
 
 	last_used = chan->cookie;
-	last_complete = mv_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 	return dma_async_is_complete(cookie, last_complete, last_used);
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index da04ac2..654876b 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -78,7 +78,6 @@ struct mv_xor_device {
 /**
  * struct mv_xor_chan - internal representation of a XOR channel
  * @pending: allows batching of hardware operations
- * @completed_cookie: identifier for the most recently completed operation
  * @lock: serializes enqueue/dequeue operations to the descriptors pool
  * @mmr_base: memory mapped register base
  * @idx: the index of the xor channel
@@ -93,7 +92,6 @@ struct mv_xor_device {
  */
 struct mv_xor_chan {
 	int			pending;
-	dma_cookie_t		completed_cookie;
 	spinlock_t		lock; /* protects the descriptor slot pool */
 	void __iomem		*mmr_base;
 	unsigned int		idx;
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index b06cd4c..3696e6e 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -111,7 +111,6 @@ struct mxs_dma_chan {
 	struct mxs_dma_ccw		*ccw;
 	dma_addr_t			ccw_phys;
 	int				desc_count;
-	dma_cookie_t			last_completed;
 	enum dma_status			status;
 	unsigned int			flags;
 #define MXS_DMA_SG_LOOP			(1 << 0)
@@ -274,7 +273,7 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
 		stat1 &= ~(1 << channel);
 
 		if (mxs_chan->status == DMA_SUCCESS)
-			mxs_chan->last_completed = mxs_chan->desc.cookie;
+			mxs_chan->chan.completed_cookie = mxs_chan->desc.cookie;
 
 		/* schedule tasklet on this channel */
 		tasklet_schedule(&mxs_chan->tasklet);
@@ -538,7 +537,7 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,
 	dma_cookie_t last_used;
 
 	last_used = chan->cookie;
-	dma_set_tx_state(txstate, mxs_chan->last_completed, last_used, 0);
+	dma_set_tx_state(txstate, chan->completed_cookie, last_used, 0);
 
 	return mxs_chan->status;
 }
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 823f581..79a7185 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -105,7 +105,6 @@ struct pch_dma_chan {
 
 	spinlock_t		lock;
 
-	dma_cookie_t		completed_cookie;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
@@ -544,7 +543,7 @@ static int pd_alloc_chan_resources(struct dma_chan *chan)
 	spin_lock_irq(&pd_chan->lock);
 	list_splice(&tmp_list, &pd_chan->free_list);
 	pd_chan->descs_allocated = i;
-	pd_chan->completed_cookie = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 	spin_unlock_irq(&pd_chan->lock);
 
 	pdc_enable_irq(chan, 1);
@@ -583,7 +582,7 @@ static enum dma_status pd_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	int ret;
 
 	spin_lock_irq(&pd_chan->lock);
-	last_completed = pd_chan->completed_cookie;
+	last_completed = chan->completed_cookie;
 	last_used = chan->cookie;
 	spin_unlock_irq(&pd_chan->lock);
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index b8ec03e..bdf04f1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -51,9 +51,6 @@ struct dma_pl330_chan {
 	/* DMA-Engine Channel */
 	struct dma_chan chan;
 
-	/* Last completed cookie */
-	dma_cookie_t completed;
-
 	/* List of to be xfered descriptors */
 	struct list_head work_list;
 
@@ -234,7 +231,7 @@ static void pl330_tasklet(unsigned long data)
 	/* Pick up ripe tomatoes */
 	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
 		if (desc->status == DONE) {
-			pch->completed = desc->txd.cookie;
+			pch->chan.completed_cookie = desc->txd.cookie;
 			list_move_tail(&desc->node, &list);
 		}
 
@@ -305,7 +302,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
 
 	spin_lock_irqsave(&pch->lock, flags);
 
-	pch->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 	pch->cyclic = false;
 
 	pch->pl330_chid = pl330_request_channel(&pdmac->pif);
@@ -400,7 +397,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	dma_cookie_t last_done, last_used;
 	int ret;
 
-	last_done = pch->completed;
+	last_done = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_done, last_used);
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index fc457a7..f878322 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -1930,7 +1930,7 @@ static void __ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan)
 				if (end_of_chain && slot_cnt) {
 					/* Should wait for ZeroSum completion */
 					if (cookie > 0)
-						chan->completed_cookie = cookie;
+						chan->common.completed_cookie = cookie;
 					return;
 				}
 
@@ -1960,7 +1960,7 @@ static void __ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan)
 	BUG_ON(!seen_current);
 
 	if (cookie > 0) {
-		chan->completed_cookie = cookie;
+		chan->common.completed_cookie = cookie;
 		pr_debug("\tcompleted cookie %d\n", cookie);
 	}
 
@@ -3950,7 +3950,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan,
 
 	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
 	last_used = chan->cookie;
-	last_complete = ppc440spe_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
@@ -3961,7 +3961,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan,
 	ppc440spe_adma_slot_cleanup(ppc440spe_chan);
 
 	last_used = chan->cookie;
-	last_complete = ppc440spe_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
@@ -4058,7 +4058,7 @@ static void ppc440spe_chan_start_null_xor(struct ppc440spe_adma_chan *chan)
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
-		chan->completed_cookie = cookie - 1;
+		chan->common.completed_cookie = cookie - 1;
 		chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
diff --git a/drivers/dma/ppc4xx/adma.h b/drivers/dma/ppc4xx/adma.h
index 8ada5a8..26b7a5e 100644
--- a/drivers/dma/ppc4xx/adma.h
+++ b/drivers/dma/ppc4xx/adma.h
@@ -81,7 +81,6 @@ struct ppc440spe_adma_device {
  * @common: common dmaengine channel object members
  * @all_slots: complete domain of slots usable by the channel
  * @pending: allows batching of hardware operations
- * @completed_cookie: identifier for the most recently completed operation
  * @slots_allocated: records the actual size of the descriptor slot pool
  * @hw_chain_inited: h/w descriptor chain initialization flag
  * @irq_tasklet: bottom half where ppc440spe_adma_slot_cleanup runs
@@ -99,7 +98,6 @@ struct ppc440spe_adma_chan {
 	struct list_head all_slots;
 	struct ppc440spe_adma_desc_slot *last_used;
 	int pending;
-	dma_cookie_t completed_cookie;
 	int slots_allocated;
 	int hw_chain_inited;
 	struct tasklet_struct irq_tasklet;
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 812fd76..ae84c12 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -764,12 +764,12 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
 			cookie = tx->cookie;
 
 		if (desc->mark == DESC_COMPLETED && desc->chunks == 1) {
-			if (sh_chan->completed_cookie != desc->cookie - 1)
+			if (sh_chan->common.completed_cookie != desc->cookie - 1)
 				dev_dbg(sh_chan->dev,
 					"Completing cookie %d, expected %d\n",
 					desc->cookie,
-					sh_chan->completed_cookie + 1);
-			sh_chan->completed_cookie = desc->cookie;
+					sh_chan->common.completed_cookie + 1);
+			sh_chan->common.completed_cookie = desc->cookie;
 		}
 
 		/* Call callback on the last chunk */
@@ -823,7 +823,7 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
 		 * Terminating and the loop completed normally: forgive
 		 * uncompleted cookies
 		 */
-		sh_chan->completed_cookie = sh_chan->common.cookie;
+		sh_chan->common.completed_cookie = sh_chan->common.cookie;
 
 	spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
 
@@ -891,7 +891,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
 	sh_dmae_chan_ld_cleanup(sh_chan, false);
 
 	/* First read completed cookie to avoid a skew */
-	last_complete = sh_chan->completed_cookie;
+	last_complete = chan->completed_cookie;
 	rmb();
 	last_used = chan->cookie;
 	BUG_ON(last_complete < 0);
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 2b55a27..0b1d2c1 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -30,7 +30,6 @@ enum dmae_pm_state {
 };
 
 struct sh_dmae_chan {
-	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
 	spinlock_t desc_lock;		/* Descriptor operation lock */
 	struct list_head ld_queue;	/* Link descriptors queue */
 	struct list_head ld_free;	/* Link descriptors free */
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 2333810..60473f0 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -59,7 +59,6 @@ struct sirfsoc_dma_chan {
 	struct list_head		queued;
 	struct list_head		active;
 	struct list_head		completed;
-	dma_cookie_t			completed_cookie;
 	unsigned long			happened_cyclic;
 	unsigned long			completed_cyclic;
 
@@ -208,7 +207,7 @@ static void sirfsoc_dma_process_completed(struct sirfsoc_dma *sdma)
 			/* Free descriptors */
 			spin_lock_irqsave(&schan->lock, flags);
 			list_splice_tail_init(&list, &schan->free);
-			schan->completed_cookie = last_cookie;
+			schan->chan.completed_cookie = last_cookie;
 			spin_unlock_irqrestore(&schan->lock, flags);
 		} else {
 			/* for cyclic channel, desc is always in active list */
@@ -419,7 +418,7 @@ sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 
 	spin_lock_irqsave(&schan->lock, flags);
 	last_used = schan->chan.cookie;
-	last_complete = schan->completed_cookie;
+	last_complete = schan->chan.completed_cookie;
 	spin_unlock_irqrestore(&schan->lock, flags);
 
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
@@ -636,7 +635,7 @@ static int __devinit sirfsoc_dma_probe(struct platform_device *op)
 
 		schan->chan.device = dma;
 		schan->chan.cookie = 1;
-		schan->completed_cookie = schan->chan.cookie;
+		schan->chan.completed_cookie = schan->chan.cookie;
 
 		INIT_LIST_HEAD(&schan->free);
 		INIT_LIST_HEAD(&schan->prepared);
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index cc5ecbc..cfca2a0 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -220,8 +220,6 @@ struct d40_base;
  *
  * @lock: A spinlock to protect this struct.
  * @log_num: The logical number, if any of this channel.
- * @completed: Starts with 1, after first interrupt it is set to dma engine's
- * current cookie.
  * @pending_tx: The number of pending transfers. Used between interrupt handler
  * and tasklet.
  * @busy: Set to true when transfer is ongoing on this channel.
@@ -250,8 +248,6 @@ struct d40_base;
 struct d40_chan {
 	spinlock_t			 lock;
 	int				 log_num;
-	/* ID of the most recent completed transfer */
-	int				 completed;
 	int				 pending_tx;
 	bool				 busy;
 	struct d40_phy_res		*phy_chan;
@@ -1357,7 +1353,7 @@ static void dma_tasklet(unsigned long data)
 		goto err;
 
 	if (!d40d->cyclic)
-		d40c->completed = d40d->txd.cookie;
+		d40c->chan.completed_cookie = d40d->txd.cookie;
 
 	/*
 	 * If terminating a channel pending_tx is set to zero.
@@ -2182,7 +2178,7 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
 	bool is_free_phy;
 	spin_lock_irqsave(&d40c->lock, flags);
 
-	d40c->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	/* If no dma configuration is set use default configuration (memcpy) */
 	if (!d40c->configured) {
@@ -2351,7 +2347,7 @@ static enum dma_status d40_tx_status(struct dma_chan *chan,
 		return -EINVAL;
 	}
 
-	last_complete = d40c->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	if (d40_is_paused(d40c))
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index a6f9c16..a1d1559 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -84,7 +84,6 @@ struct timb_dma_chan {
 					especially the lists and descriptors,
 					from races between the tasklet and calls
 					from above */
-	dma_cookie_t		last_completed_cookie;
 	bool			ongoing;
 	struct list_head	active_list;
 	struct list_head	queue;
@@ -284,7 +283,7 @@ static void __td_finish(struct timb_dma_chan *td_chan)
 	else
 		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR);
 */
-	td_chan->last_completed_cookie = txd->cookie;
+	td_chan->chan.completed_cookie = txd->cookie;
 	td_chan->ongoing = false;
 
 	callback = txd->callback;
@@ -481,7 +480,7 @@ static int td_alloc_chan_resources(struct dma_chan *chan)
 	}
 
 	spin_lock_bh(&td_chan->lock);
-	td_chan->last_completed_cookie = 1;
+	chan->completed_cookie = 1;
 	chan->cookie = 1;
 	spin_unlock_bh(&td_chan->lock);
 
@@ -523,7 +522,7 @@ static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 
 	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
 
-	last_complete = td_chan->last_completed_cookie;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 6122c36..a917b67 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -424,7 +424,7 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
 	dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
 		 txd->cookie, desc);
 
-	dc->completed = txd->cookie;
+	dc->chan.completed_cookie = txd->cookie;
 	callback = txd->callback;
 	param = txd->callback_param;
 
@@ -976,7 +976,7 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	dma_cookie_t last_complete;
 	int ret;
 
-	last_complete = dc->completed;
+	last_complete = chan->completed_cookie;
 	last_used = chan->cookie;
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -985,7 +985,7 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		txx9dmac_scan_descriptors(dc);
 		spin_unlock_bh(&dc->lock);
 
-		last_complete = dc->completed;
+		last_complete = chan->completed_cookie;
 		last_used = chan->cookie;
 
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -1057,7 +1057,7 @@ static int txx9dmac_alloc_chan_resources(struct dma_chan *chan)
 		return -EIO;
 	}
 
-	dc->completed = chan->cookie = 1;
+	chan->completed_cookie = chan->cookie = 1;
 
 	dc->ccr = TXX9_DMA_CCR_IMMCHN | TXX9_DMA_CCR_INTENE | CCR_LE;
 	txx9dmac_chan_set_SMPCHN(dc);
@@ -1186,7 +1186,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev)
 	dc->ddev->chan[ch] = dc;
 	dc->chan.device = &dc->dma;
 	list_add_tail(&dc->chan.device_node, &dc->chan.device->channels);
-	dc->chan.cookie = dc->completed = 1;
+	dc->chan.cookie = dc->chan.completed_cookie = 1;
 
 	if (is_dmac64(dc))
 		dc->ch_regs = &__txx9dmac_regs(dc->ddev)->CHAN[ch];
diff --git a/drivers/dma/txx9dmac.h b/drivers/dma/txx9dmac.h
index 365d423..f5a7605 100644
--- a/drivers/dma/txx9dmac.h
+++ b/drivers/dma/txx9dmac.h
@@ -172,7 +172,6 @@ struct txx9dmac_chan {
 	spinlock_t		lock;
 
 	/* these other elements are all protected by lock */
-	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 033f6aa..1bb134b 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -176,7 +176,6 @@ enum pl08x_dma_chan_state {
  * @runtime_addr: address for RX/TX according to the runtime config
  * @runtime_direction: current direction of this channel according to
  * runtime config
- * @lc: last completed transaction on this channel
  * @pend_list: queued transactions pending on this channel
  * @at: active transaction on this channel
  * @lock: a lock for this channel data
@@ -198,7 +197,6 @@ struct pl08x_dma_chan {
 	u32 src_cctl;
 	u32 dst_cctl;
 	enum dma_transfer_direction runtime_direction;
-	dma_cookie_t lc;
 	struct list_head pend_list;
 	struct pl08x_txd *at;
 	spinlock_t lock;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 679b349..41d0f92 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -257,6 +257,7 @@ struct dma_chan_percpu {
  * struct dma_chan - devices supply DMA channels, clients use them
  * @device: ptr to the dma device who supplies this channel, always !%NULL
  * @cookie: last cookie value returned to client
+ * @completed_cookie: last completed cookie for this channel
  * @chan_id: channel ID for sysfs
  * @dev: class device for sysfs
  * @device_node: used to add this to the device chan list
@@ -268,6 +269,7 @@ struct dma_chan_percpu {
 struct dma_chan {
 	struct dma_device *device;
 	dma_cookie_t cookie;
+	dma_cookie_t completed_cookie;
 
 	/* sysfs */
 	int chan_id;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 3/9] dmaengine: add private header file
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-06 22:34   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:34 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul
  Cc: Viresh Kumar, Stephen Warren, Linus Walleij, Srinidhi Kasagar,
	linuxppc-dev, linux-arm-kernel

Add a local private header file to contain definitions and declarations
which should only be used by DMA engine drivers.

We also fix linux/dmaengine.h to use LINUX_DMAENGINE_H to guard against
multiple inclusion.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |    2 ++
 drivers/dma/at_hdmac.c      |    1 +
 drivers/dma/coh901318.c     |    1 +
 drivers/dma/dmaengine.h     |   10 ++++++++++
 drivers/dma/dw_dmac.c       |    1 +
 drivers/dma/ep93xx_dma.c    |    2 ++
 drivers/dma/fsldma.c        |    1 +
 drivers/dma/imx-dma.c       |    2 ++
 drivers/dma/imx-sdma.c      |    2 ++
 drivers/dma/intel_mid_dma.c |    2 ++
 drivers/dma/ioat/dma.c      |    2 ++
 drivers/dma/ioat/dma_v2.c   |    2 ++
 drivers/dma/iop-adma.c      |    2 ++
 drivers/dma/ipu/ipu_idmac.c |    1 +
 drivers/dma/mpc512x_dma.c   |    2 ++
 drivers/dma/mv_xor.c        |    2 ++
 drivers/dma/mxs-dma.c       |    2 ++
 drivers/dma/pch_dma.c       |    2 ++
 drivers/dma/pl330.c         |    2 ++
 drivers/dma/ppc4xx/adma.c   |    1 +
 drivers/dma/shdma.c         |    2 ++
 drivers/dma/ste_dma40.c     |    1 +
 drivers/dma/timb_dma.c      |    2 ++
 drivers/dma/txx9dmac.c      |    2 ++
 include/linux/dmaengine.h   |    4 ++--
 25 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 drivers/dma/dmaengine.h

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 2b5121f..87475cb 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -85,6 +85,8 @@
 #include <linux/slab.h>
 #include <asm/hardware/pl080.h>
 
+#include "dmaengine.h"
+
 #define DRIVER_NAME	"pl08xdmac"
 
 static struct amba_driver pl08x_amba_driver;
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 6baf5d7..ce26ba3 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -27,6 +27,7 @@
 #include <linux/of_device.h>
 
 #include "at_hdmac_regs.h"
+#include "dmaengine.h"
 
 /*
  * Glossary
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 521434b..fb0d124 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -24,6 +24,7 @@
 #include <mach/coh901318.h>
 
 #include "coh901318_lli.h"
+#include "dmaengine.h"
 
 #define COHC_2_DEV(cohc) (&cohc->chan.dev->device)
 
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
new file mode 100644
index 0000000..968570d
--- /dev/null
+++ b/drivers/dma/dmaengine.h
@@ -0,0 +1,10 @@
+/*
+ * The contents of this file are private to DMA engine drivers, and is not
+ * part of the API to be used by DMA engine users.
+ */
+#ifndef DMAENGINE_H
+#define DMAENGINE_H
+
+#include <linux/dmaengine.h>
+
+#endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index defe574..f10dbe1 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 
 #include "dw_dmac_regs.h"
+#include "dmaengine.h"
 
 /*
  * This supports the Synopsys "DesignWare AHB Central DMA Controller",
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index bc45787..3260198 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -28,6 +28,8 @@
 
 #include <mach/dma.h>
 
+#include "dmaengine.h"
+
 /* M2P registers */
 #define M2P_CONTROL			0x0000
 #define M2P_CONTROL_STALLINT		BIT(0)
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 9b5cb8a..2ebbe57 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -35,6 +35,7 @@
 #include <linux/dmapool.h>
 #include <linux/of_platform.h>
 
+#include "dmaengine.h"
 #include "fsldma.h"
 
 #define chan_dbg(chan, fmt, arg...)					\
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 321fc1f..51251a6 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -30,6 +30,8 @@
 #include <mach/dma-v1.h>
 #include <mach/hardware.h>
 
+#include "dmaengine.h"
+
 struct imxdma_channel {
 	struct imxdma_engine		*imxdma;
 	unsigned int			channel;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index e857904..9950ec3 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -42,6 +42,8 @@
 #include <mach/dma.h>
 #include <mach/hardware.h>
 
+#include "dmaengine.h"
+
 /* SDMA registers */
 #define SDMA_H_C0PTR		0x000
 #define SDMA_H_INTR		0x004
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index a27ae45..a907dd6 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -29,6 +29,8 @@
 #include <linux/intel_mid_dma.h>
 #include <linux/module.h>
 
+#include "dmaengine.h"
+
 #define MAX_CHAN	4 /*max ch across controllers*/
 #include "intel_mid_dma_regs.h"
 
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index fab440a..dfe411b 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -40,6 +40,8 @@
 #include "registers.h"
 #include "hw.h"
 
+#include "../dmaengine.h"
+
 int ioat_pending_level = 4;
 module_param(ioat_pending_level, int, 0644);
 MODULE_PARM_DESC(ioat_pending_level,
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index d3f0aff..6c1e675 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -41,6 +41,8 @@
 #include "registers.h"
 #include "hw.h"
 
+#include "../dmaengine.h"
+
 int ioat_ring_alloc_order = 8;
 module_param(ioat_ring_alloc_order, int, 0644);
 MODULE_PARM_DESC(ioat_ring_alloc_order,
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index d8027c2..650bf1e 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -36,6 +36,8 @@
 
 #include <mach/adma.h>
 
+#include "dmaengine.h"
+
 #define to_iop_adma_chan(chan) container_of(chan, struct iop_adma_chan, common)
 #define to_iop_adma_device(dev) \
 	container_of(dev, struct iop_adma_device, common)
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 9149ade..0fcff65 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -25,6 +25,7 @@
 
 #include <mach/ipu.h>
 
+#include "../dmaengine.h"
 #include "ipu_intern.h"
 
 #define FS_VF_IN_VALID	0x00000002
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 39a5cde..c56b3fe 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -44,6 +44,8 @@
 
 #include <linux/random.h>
 
+#include "dmaengine.h"
+
 /* Number of DMA Transfer descriptors allocated per channel */
 #define MPC_DMA_DESCRIPTORS	64
 
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index c6a84da..ee61778 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -26,6 +26,8 @@
 #include <linux/platform_device.h>
 #include <linux/memory.h>
 #include <plat/mv_xor.h>
+
+#include "dmaengine.h"
 #include "mv_xor.h"
 
 static void mv_xor_issue_pending(struct dma_chan *chan);
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 3696e6e..daa84ee 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -28,6 +28,8 @@
 #include <mach/dma.h>
 #include <mach/common.h>
 
+#include "dmaengine.h"
+
 /*
  * NOTE: The term "PIO" throughout the mxs-dma implementation means
  * PIO mode of mxs apbh-dma and apbx-dma.  With this working mode,
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 79a7185..2b3479d 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -25,6 +25,8 @@
 #include <linux/module.h>
 #include <linux/pch_dma.h>
 
+#include "dmaengine.h"
+
 #define DRV_NAME "pch-dma"
 
 #define DMA_CTL0_DISABLE		0x0
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index bdf04f1..d7b0af2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -21,6 +21,8 @@
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 
+#include "dmaengine.h"
+
 #define NR_DEFAULT_DESC	16
 
 enum desc_status {
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index f878322..40082ec 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -46,6 +46,7 @@
 #include <asm/dcr.h>
 #include <asm/dcr-regs.h>
 #include "adma.h"
+#include "../dmaengine.h"
 
 enum ppc_adma_init_code {
 	PPC_ADMA_INIT_OK = 0,
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index ae84c12..c291433 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -30,6 +30,8 @@
 #include <linux/kdebug.h>
 #include <linux/spinlock.h>
 #include <linux/rculist.h>
+
+#include "dmaengine.h"
 #include "shdma.h"
 
 /* DMA descriptor control */
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index cfca2a0..156b98f 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -21,6 +21,7 @@
 
 #include <plat/ste_dma40.h>
 
+#include "dmaengine.h"
 #include "ste_dma40_ll.h"
 
 #define D40_NAME "dma40"
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index a1d1559..4b61879 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -31,6 +31,8 @@
 
 #include <linux/timb_dma.h>
 
+#include "dmaengine.h"
+
 #define DRIVER_NAME "timb-dma"
 
 /* Global DMA registers */
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index a917b67..db6d809 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -15,6 +15,8 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/scatterlist.h>
+
+#include "dmaengine.h"
 #include "txx9dmac.h"
 
 static struct txx9dmac_chan *to_txx9dmac_chan(struct dma_chan *chan)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 41d0f92..4b17ca8 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -18,8 +18,8 @@
  * The full GNU General Public License is included in this distribution in the
  * file called COPYING.
  */
-#ifndef DMAENGINE_H
-#define DMAENGINE_H
+#ifndef LINUX_DMAENGINE_H
+#define LINUX_DMAENGINE_H
 
 #include <linux/device.h>
 #include <linux/uio.h>
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 3/9] dmaengine: add private header file
@ 2012-03-06 22:34   ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:34 UTC (permalink / raw)
  To: linux-arm-kernel

Add a local private header file to contain definitions and declarations
which should only be used by DMA engine drivers.

We also fix linux/dmaengine.h to use LINUX_DMAENGINE_H to guard against
multiple inclusion.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |    2 ++
 drivers/dma/at_hdmac.c      |    1 +
 drivers/dma/coh901318.c     |    1 +
 drivers/dma/dmaengine.h     |   10 ++++++++++
 drivers/dma/dw_dmac.c       |    1 +
 drivers/dma/ep93xx_dma.c    |    2 ++
 drivers/dma/fsldma.c        |    1 +
 drivers/dma/imx-dma.c       |    2 ++
 drivers/dma/imx-sdma.c      |    2 ++
 drivers/dma/intel_mid_dma.c |    2 ++
 drivers/dma/ioat/dma.c      |    2 ++
 drivers/dma/ioat/dma_v2.c   |    2 ++
 drivers/dma/iop-adma.c      |    2 ++
 drivers/dma/ipu/ipu_idmac.c |    1 +
 drivers/dma/mpc512x_dma.c   |    2 ++
 drivers/dma/mv_xor.c        |    2 ++
 drivers/dma/mxs-dma.c       |    2 ++
 drivers/dma/pch_dma.c       |    2 ++
 drivers/dma/pl330.c         |    2 ++
 drivers/dma/ppc4xx/adma.c   |    1 +
 drivers/dma/shdma.c         |    2 ++
 drivers/dma/ste_dma40.c     |    1 +
 drivers/dma/timb_dma.c      |    2 ++
 drivers/dma/txx9dmac.c      |    2 ++
 include/linux/dmaengine.h   |    4 ++--
 25 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 drivers/dma/dmaengine.h

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 2b5121f..87475cb 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -85,6 +85,8 @@
 #include <linux/slab.h>
 #include <asm/hardware/pl080.h>
 
+#include "dmaengine.h"
+
 #define DRIVER_NAME	"pl08xdmac"
 
 static struct amba_driver pl08x_amba_driver;
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 6baf5d7..ce26ba3 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -27,6 +27,7 @@
 #include <linux/of_device.h>
 
 #include "at_hdmac_regs.h"
+#include "dmaengine.h"
 
 /*
  * Glossary
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 521434b..fb0d124 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -24,6 +24,7 @@
 #include <mach/coh901318.h>
 
 #include "coh901318_lli.h"
+#include "dmaengine.h"
 
 #define COHC_2_DEV(cohc) (&cohc->chan.dev->device)
 
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
new file mode 100644
index 0000000..968570d
--- /dev/null
+++ b/drivers/dma/dmaengine.h
@@ -0,0 +1,10 @@
+/*
+ * The contents of this file are private to DMA engine drivers, and is not
+ * part of the API to be used by DMA engine users.
+ */
+#ifndef DMAENGINE_H
+#define DMAENGINE_H
+
+#include <linux/dmaengine.h>
+
+#endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index defe574..f10dbe1 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 
 #include "dw_dmac_regs.h"
+#include "dmaengine.h"
 
 /*
  * This supports the Synopsys "DesignWare AHB Central DMA Controller",
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index bc45787..3260198 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -28,6 +28,8 @@
 
 #include <mach/dma.h>
 
+#include "dmaengine.h"
+
 /* M2P registers */
 #define M2P_CONTROL			0x0000
 #define M2P_CONTROL_STALLINT		BIT(0)
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 9b5cb8a..2ebbe57 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -35,6 +35,7 @@
 #include <linux/dmapool.h>
 #include <linux/of_platform.h>
 
+#include "dmaengine.h"
 #include "fsldma.h"
 
 #define chan_dbg(chan, fmt, arg...)					\
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 321fc1f..51251a6 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -30,6 +30,8 @@
 #include <mach/dma-v1.h>
 #include <mach/hardware.h>
 
+#include "dmaengine.h"
+
 struct imxdma_channel {
 	struct imxdma_engine		*imxdma;
 	unsigned int			channel;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index e857904..9950ec3 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -42,6 +42,8 @@
 #include <mach/dma.h>
 #include <mach/hardware.h>
 
+#include "dmaengine.h"
+
 /* SDMA registers */
 #define SDMA_H_C0PTR		0x000
 #define SDMA_H_INTR		0x004
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index a27ae45..a907dd6 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -29,6 +29,8 @@
 #include <linux/intel_mid_dma.h>
 #include <linux/module.h>
 
+#include "dmaengine.h"
+
 #define MAX_CHAN	4 /*max ch across controllers*/
 #include "intel_mid_dma_regs.h"
 
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index fab440a..dfe411b 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -40,6 +40,8 @@
 #include "registers.h"
 #include "hw.h"
 
+#include "../dmaengine.h"
+
 int ioat_pending_level = 4;
 module_param(ioat_pending_level, int, 0644);
 MODULE_PARM_DESC(ioat_pending_level,
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index d3f0aff..6c1e675 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -41,6 +41,8 @@
 #include "registers.h"
 #include "hw.h"
 
+#include "../dmaengine.h"
+
 int ioat_ring_alloc_order = 8;
 module_param(ioat_ring_alloc_order, int, 0644);
 MODULE_PARM_DESC(ioat_ring_alloc_order,
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index d8027c2..650bf1e 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -36,6 +36,8 @@
 
 #include <mach/adma.h>
 
+#include "dmaengine.h"
+
 #define to_iop_adma_chan(chan) container_of(chan, struct iop_adma_chan, common)
 #define to_iop_adma_device(dev) \
 	container_of(dev, struct iop_adma_device, common)
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 9149ade..0fcff65 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -25,6 +25,7 @@
 
 #include <mach/ipu.h>
 
+#include "../dmaengine.h"
 #include "ipu_intern.h"
 
 #define FS_VF_IN_VALID	0x00000002
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 39a5cde..c56b3fe 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -44,6 +44,8 @@
 
 #include <linux/random.h>
 
+#include "dmaengine.h"
+
 /* Number of DMA Transfer descriptors allocated per channel */
 #define MPC_DMA_DESCRIPTORS	64
 
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index c6a84da..ee61778 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -26,6 +26,8 @@
 #include <linux/platform_device.h>
 #include <linux/memory.h>
 #include <plat/mv_xor.h>
+
+#include "dmaengine.h"
 #include "mv_xor.h"
 
 static void mv_xor_issue_pending(struct dma_chan *chan);
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 3696e6e..daa84ee 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -28,6 +28,8 @@
 #include <mach/dma.h>
 #include <mach/common.h>
 
+#include "dmaengine.h"
+
 /*
  * NOTE: The term "PIO" throughout the mxs-dma implementation means
  * PIO mode of mxs apbh-dma and apbx-dma.  With this working mode,
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 79a7185..2b3479d 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -25,6 +25,8 @@
 #include <linux/module.h>
 #include <linux/pch_dma.h>
 
+#include "dmaengine.h"
+
 #define DRV_NAME "pch-dma"
 
 #define DMA_CTL0_DISABLE		0x0
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index bdf04f1..d7b0af2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -21,6 +21,8 @@
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 
+#include "dmaengine.h"
+
 #define NR_DEFAULT_DESC	16
 
 enum desc_status {
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index f878322..40082ec 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -46,6 +46,7 @@
 #include <asm/dcr.h>
 #include <asm/dcr-regs.h>
 #include "adma.h"
+#include "../dmaengine.h"
 
 enum ppc_adma_init_code {
 	PPC_ADMA_INIT_OK = 0,
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index ae84c12..c291433 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -30,6 +30,8 @@
 #include <linux/kdebug.h>
 #include <linux/spinlock.h>
 #include <linux/rculist.h>
+
+#include "dmaengine.h"
 #include "shdma.h"
 
 /* DMA descriptor control */
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index cfca2a0..156b98f 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -21,6 +21,7 @@
 
 #include <plat/ste_dma40.h>
 
+#include "dmaengine.h"
 #include "ste_dma40_ll.h"
 
 #define D40_NAME "dma40"
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index a1d1559..4b61879 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -31,6 +31,8 @@
 
 #include <linux/timb_dma.h>
 
+#include "dmaengine.h"
+
 #define DRIVER_NAME "timb-dma"
 
 /* Global DMA registers */
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index a917b67..db6d809 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -15,6 +15,8 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/scatterlist.h>
+
+#include "dmaengine.h"
 #include "txx9dmac.h"
 
 static struct txx9dmac_chan *to_txx9dmac_chan(struct dma_chan *chan)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 41d0f92..4b17ca8 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -18,8 +18,8 @@
  * The full GNU General Public License is included in this distribution in the
  * file called COPYING.
  */
-#ifndef DMAENGINE_H
-#define DMAENGINE_H
+#ifndef LINUX_DMAENGINE_H
+#define LINUX_DMAENGINE_H
 
 #include <linux/device.h>
 #include <linux/uio.h>
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 4/9] dmaengine: consolidate assignment of DMA cookies
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-06 22:34   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:34 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul
  Cc: Viresh Kumar, Stephen Warren, Linus Walleij, Srinidhi Kasagar,
	Barry Song, linuxppc-dev, linux-arm-kernel

Everyone deals with assigning DMA cookies in the same way (it's part of
the API so they should be), so lets consolidate the common code into a
helper function to avoid this duplication.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |    9 +++------
 drivers/dma/at_hdmac.c      |   23 +----------------------
 drivers/dma/coh901318.c     |   20 +++-----------------
 drivers/dma/dmaengine.h     |   20 ++++++++++++++++++++
 drivers/dma/dw_dmac.c       |   17 +----------------
 drivers/dma/ep93xx_dma.c    |    9 +--------
 drivers/dma/fsldma.c        |    9 +--------
 drivers/dma/imx-dma.c       |   15 +--------------
 drivers/dma/imx-sdma.c      |   15 +--------------
 drivers/dma/intel_mid_dma.c |    9 +--------
 drivers/dma/ioat/dma.c      |    7 +------
 drivers/dma/ioat/dma_v2.c   |    8 ++------
 drivers/dma/iop-adma.c      |   14 +-------------
 drivers/dma/ipu/ipu_idmac.c |    9 +--------
 drivers/dma/mpc512x_dma.c   |    8 +-------
 drivers/dma/mv_xor.c        |   14 +-------------
 drivers/dma/mxs-dma.c       |   15 +--------------
 drivers/dma/pch_dma.c       |   16 +---------------
 drivers/dma/pl330.c         |   14 ++------------
 drivers/dma/ppc4xx/adma.c   |   19 +------------------
 drivers/dma/shdma.c         |    8 +-------
 drivers/dma/sirf-dma.c      |    8 +-------
 drivers/dma/ste_dma40.c     |   13 +++----------
 drivers/dma/timb_dma.c      |    7 +------
 drivers/dma/txx9dmac.c      |   17 +----------------
 25 files changed, 52 insertions(+), 271 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 87475cb..5996386 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -921,13 +921,10 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
 	struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan);
 	struct pl08x_txd *txd = to_pl08x_txd(tx);
 	unsigned long flags;
+	dma_cookie_t cookie;
 
 	spin_lock_irqsave(&plchan->lock, flags);
-
-	plchan->chan.cookie += 1;
-	if (plchan->chan.cookie < 0)
-		plchan->chan.cookie = 1;
-	tx->cookie = plchan->chan.cookie;
+	cookie = dma_cookie_assign(tx);
 
 	/* Put this onto the pending list */
 	list_add_tail(&txd->node, &plchan->pend_list);
@@ -947,7 +944,7 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_unlock_irqrestore(&plchan->lock, flags);
 
-	return tx->cookie;
+	return cookie;
 }
 
 static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index ce26ba3..df47e7d 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -193,27 +193,6 @@ static void atc_desc_chain(struct at_desc **first, struct at_desc **prev,
 }
 
 /**
- * atc_assign_cookie - compute and assign new cookie
- * @atchan: channel we work on
- * @desc: descriptor to assign cookie for
- *
- * Called with atchan->lock held and bh disabled
- */
-static dma_cookie_t
-atc_assign_cookie(struct at_dma_chan *atchan, struct at_desc *desc)
-{
-	dma_cookie_t cookie = atchan->chan_common.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	atchan->chan_common.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
-/**
  * atc_dostart - starts the DMA engine for real
  * @atchan: the channel we want to start
  * @first: first descriptor in the list we want to begin with
@@ -548,7 +527,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
 	unsigned long		flags;
 
 	spin_lock_irqsave(&atchan->lock, flags);
-	cookie = atc_assign_cookie(atchan, desc);
+	cookie = dma_cookie_assign(tx);
 
 	if (list_empty(&atchan->active_list)) {
 		dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index fb0d124..843a1a3 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -318,20 +318,6 @@ static int coh901318_prep_linked_list(struct coh901318_chan *cohc,
 
 	return 0;
 }
-static dma_cookie_t
-coh901318_assign_cookie(struct coh901318_chan *cohc,
-			struct coh901318_desc *cohd)
-{
-	dma_cookie_t cookie = cohc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	cohc->chan.cookie = cookie;
-	cohd->desc.cookie = cookie;
-
-	return cookie;
-}
 
 static struct coh901318_desc *
 coh901318_desc_get(struct coh901318_chan *cohc)
@@ -966,16 +952,16 @@ coh901318_tx_submit(struct dma_async_tx_descriptor *tx)
 						   desc);
 	struct coh901318_chan *cohc = to_coh901318_chan(tx->chan);
 	unsigned long flags;
+	dma_cookie_t cookie;
 
 	spin_lock_irqsave(&cohc->lock, flags);
-
-	tx->cookie = coh901318_assign_cookie(cohc, cohd);
+	cookie = dma_cookie_assign(tx);
 
 	coh901318_desc_queue(cohc, cohd);
 
 	spin_unlock_irqrestore(&cohc->lock, flags);
 
-	return tx->cookie;
+	return cookie;
 }
 
 static struct dma_async_tx_descriptor *
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 968570d..7692c86 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -7,4 +7,24 @@
 
 #include <linux/dmaengine.h>
 
+/**
+ * dma_cookie_assign - assign a DMA engine cookie to the descriptor
+ * @tx: descriptor needing cookie
+ *
+ * Assign a unique non-zero per-channel cookie to the descriptor.
+ * Note: caller is expected to hold a lock to prevent concurrency.
+ */
+static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
+{
+	struct dma_chan *chan = tx->chan;
+	dma_cookie_t cookie;
+
+	cookie = chan->cookie + 1;
+	if (cookie < DMA_MIN_COOKIE)
+		cookie = DMA_MIN_COOKIE;
+	tx->cookie = chan->cookie = cookie;
+
+	return cookie;
+}
+
 #endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index f10dbe1..5ee9498 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -152,21 +152,6 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
 	}
 }
 
-/* Called with dwc->lock held and bh disabled */
-static dma_cookie_t
-dwc_assign_cookie(struct dw_dma_chan *dwc, struct dw_desc *desc)
-{
-	dma_cookie_t cookie = dwc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	dwc->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
 static void dwc_initialize(struct dw_dma_chan *dwc)
 {
 	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
@@ -616,7 +601,7 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
 	unsigned long		flags;
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	cookie = dwc_assign_cookie(dwc, desc);
+	cookie = dma_cookie_assign(tx);
 
 	/*
 	 * REVISIT: We should attempt to chain as many descriptors as
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 3260198..e5aaae8 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -783,17 +783,10 @@ static dma_cookie_t ep93xx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	unsigned long flags;
 
 	spin_lock_irqsave(&edmac->lock, flags);
-
-	cookie = edmac->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
+	cookie = dma_cookie_assign(tx);
 
 	desc = container_of(tx, struct ep93xx_dma_desc, txd);
 
-	edmac->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
 	/*
 	 * If nothing is currently prosessed, we push this descriptor
 	 * directly to the hardware. Otherwise we put the descriptor
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 2ebbe57..04b4347 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -414,17 +414,10 @@ static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	 * assign cookies to all of the software descriptors
 	 * that make up this transaction
 	 */
-	cookie = chan->common.cookie;
 	list_for_each_entry(child, &desc->tx_list, node) {
-		cookie++;
-		if (cookie < DMA_MIN_COOKIE)
-			cookie = DMA_MIN_COOKIE;
-
-		child->async_tx.cookie = cookie;
+		cookie = dma_cookie_assign(&child->async_tx);
 	}
 
-	chan->common.cookie = cookie;
-
 	/* put this transaction onto the tail of the pending queue */
 	append_ld_queue(chan, desc);
 
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 51251a6..42154b6 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -165,19 +165,6 @@ static enum dma_status imxdma_tx_status(struct dma_chan *chan,
 	return ret;
 }
 
-static dma_cookie_t imxdma_assign_cookie(struct imxdma_channel *imxdma)
-{
-	dma_cookie_t cookie = imxdma->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	imxdma->chan.cookie = cookie;
-	imxdma->desc.cookie = cookie;
-
-	return cookie;
-}
-
 static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx)
 {
 	struct imxdma_channel *imxdmac = to_imxdma_chan(tx->chan);
@@ -185,7 +172,7 @@ static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_lock_irq(&imxdmac->lock);
 
-	cookie = imxdma_assign_cookie(imxdmac);
+	cookie = dma_cookie_assign(tx);
 
 	imx_dma_enable(imxdmac->imxdma_channel);
 
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9950ec3..4e4f40e 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -817,19 +817,6 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
 	__raw_writel(1 << channel, sdma->regs + SDMA_H_START);
 }
 
-static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac)
-{
-	dma_cookie_t cookie = sdmac->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	sdmac->chan.cookie = cookie;
-	sdmac->desc.cookie = cookie;
-
-	return cookie;
-}
-
 static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
 {
 	return container_of(chan, struct sdma_channel, chan);
@@ -844,7 +831,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_lock_irqsave(&sdmac->lock, flags);
 
-	cookie = sdma_assign_cookie(sdmac);
+	cookie = dma_cookie_assign(tx);
 
 	sdma_enable_channel(sdma, sdmac->channel);
 
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index a907dd6..dfe4396 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -436,14 +436,7 @@ static dma_cookie_t intel_mid_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	dma_cookie_t		cookie;
 
 	spin_lock_bh(&midc->lock);
-	cookie = midc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	midc->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
+	cookie = dma_cookie_assign(tx);
 
 	if (list_empty(&midc->active_list))
 		list_add_tail(&desc->desc_node, &midc->active_list);
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index dfe411b..5c06117 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -237,12 +237,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_lock_bh(&ioat->desc_lock);
 	/* cookie incr and addition to used_list must be atomic */
-	cookie = c->cookie;
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	c->cookie = cookie;
-	tx->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 	dev_dbg(to_dev(&ioat->base), "%s: cookie: %d\n", __func__, cookie);
 
 	/* write address into NextDescriptor field of last desc in chain */
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 6c1e675..17ecacb 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -400,13 +400,9 @@ static dma_cookie_t ioat2_tx_submit_unlock(struct dma_async_tx_descriptor *tx)
 	struct dma_chan *c = tx->chan;
 	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
 	struct ioat_chan_common *chan = &ioat->base;
-	dma_cookie_t cookie = c->cookie;
+	dma_cookie_t cookie;
 
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	tx->cookie = cookie;
-	c->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 	dev_dbg(to_dev(&ioat->base), "%s: cookie: %d\n", __func__, cookie);
 
 	if (!test_and_set_bit(IOAT_COMPLETION_PENDING, &chan->state))
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 650bf1e..f2392d5 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -440,18 +440,6 @@ iop_adma_alloc_slots(struct iop_adma_chan *iop_chan, int num_slots,
 	return NULL;
 }
 
-static dma_cookie_t
-iop_desc_assign_cookie(struct iop_adma_chan *iop_chan,
-	struct iop_adma_desc_slot *desc)
-{
-	dma_cookie_t cookie = iop_chan->common.cookie;
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	iop_chan->common.cookie = desc->async_tx.cookie = cookie;
-	return cookie;
-}
-
 static void iop_adma_check_threshold(struct iop_adma_chan *iop_chan)
 {
 	dev_dbg(iop_chan->device->common.dev, "pending: %d\n",
@@ -479,7 +467,7 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx)
 	slots_per_op = grp_start->slots_per_op;
 
 	spin_lock_bh(&iop_chan->lock);
-	cookie = iop_desc_assign_cookie(iop_chan, sw_desc);
+	cookie = dma_cookie_assign(tx);
 
 	old_chain_tail = list_entry(iop_chan->chain.prev,
 		struct iop_adma_desc_slot, chain_node);
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 0fcff65..d4620c5 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -867,14 +867,7 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
 
-	cookie = ichan->dma_chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	/* from dmaengine.h: "last cookie value returned to client" */
-	ichan->dma_chan.cookie = cookie;
-	tx->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 
 	/* ipu->lock can be taken under ichan->lock, but not v.v. */
 	spin_lock_irqsave(&ichan->lock, flags);
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index c56b3fe..0253d5a 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -439,13 +439,7 @@ static dma_cookie_t mpc_dma_tx_submit(struct dma_async_tx_descriptor *txd)
 		mpc_dma_execute(mchan);
 
 	/* Update cookie */
-	cookie = mchan->chan.cookie + 1;
-	if (cookie <= 0)
-		cookie = 1;
-
-	mchan->chan.cookie = cookie;
-	mdesc->desc.cookie = cookie;
-
+	cookie = dma_cookie_assign(txd);
 	spin_unlock_irqrestore(&mchan->lock, flags);
 
 	return cookie;
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index ee61778..d9810ce 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -536,18 +536,6 @@ mv_xor_alloc_slots(struct mv_xor_chan *mv_chan, int num_slots,
 	return NULL;
 }
 
-static dma_cookie_t
-mv_desc_assign_cookie(struct mv_xor_chan *mv_chan,
-		      struct mv_xor_desc_slot *desc)
-{
-	dma_cookie_t cookie = mv_chan->common.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-	mv_chan->common.cookie = desc->async_tx.cookie = cookie;
-	return cookie;
-}
-
 /************************ DMA engine API functions ****************************/
 static dma_cookie_t
 mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
@@ -565,7 +553,7 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
 	grp_start = sw_desc->group_head;
 
 	spin_lock_bh(&mv_chan->lock);
-	cookie = mv_desc_assign_cookie(mv_chan, sw_desc);
+	cookie = dma_cookie_assign(tx);
 
 	if (list_empty(&mv_chan->chain))
 		list_splice_init(&sw_desc->tx_list, &mv_chan->chain);
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index daa84ee..4d3b6ff 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -194,19 +194,6 @@ static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
 	mxs_chan->status = DMA_IN_PROGRESS;
 }
 
-static dma_cookie_t mxs_dma_assign_cookie(struct mxs_dma_chan *mxs_chan)
-{
-	dma_cookie_t cookie = mxs_chan->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	mxs_chan->chan.cookie = cookie;
-	mxs_chan->desc.cookie = cookie;
-
-	return cookie;
-}
-
 static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
 {
 	return container_of(chan, struct mxs_dma_chan, chan);
@@ -218,7 +205,7 @@ static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	mxs_dma_enable_chan(mxs_chan);
 
-	return mxs_dma_assign_cookie(mxs_chan);
+	return dma_cookie_assign(tx);
 }
 
 static void mxs_dma_tasklet(unsigned long data)
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 2b3479d..5218e48 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -417,20 +417,6 @@ static void pdc_advance_work(struct pch_dma_chan *pd_chan)
 	}
 }
 
-static dma_cookie_t pdc_assign_cookie(struct pch_dma_chan *pd_chan,
-				      struct pch_dma_desc *desc)
-{
-	dma_cookie_t cookie = pd_chan->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	pd_chan->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
 static dma_cookie_t pd_tx_submit(struct dma_async_tx_descriptor *txd)
 {
 	struct pch_dma_desc *desc = to_pd_desc(txd);
@@ -438,7 +424,7 @@ static dma_cookie_t pd_tx_submit(struct dma_async_tx_descriptor *txd)
 	dma_cookie_t cookie;
 
 	spin_lock(&pd_chan->lock);
-	cookie = pdc_assign_cookie(pd_chan, desc);
+	cookie = dma_cookie_assign(txd);
 
 	if (list_empty(&pd_chan->active_list)) {
 		list_add_tail(&desc->desc_node, &pd_chan->active_list);
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index d7b0af2..ec9638b 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -429,26 +429,16 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx)
 	spin_lock_irqsave(&pch->lock, flags);
 
 	/* Assign cookies to all nodes */
-	cookie = tx->chan->cookie;
-
 	while (!list_empty(&last->node)) {
 		desc = list_entry(last->node.next, struct dma_pl330_desc, node);
 
-		if (++cookie < 0)
-			cookie = 1;
-		desc->txd.cookie = cookie;
+		dma_cookie_assign(&desc->txd);
 
 		list_move_tail(&desc->node, &pch->work_list);
 	}
 
-	if (++cookie < 0)
-		cookie = 1;
-	last->txd.cookie = cookie;
-
+	cookie = dma_cookie_assign(&last->txd);
 	list_add_tail(&last->node, &pch->work_list);
-
-	tx->chan->cookie = cookie;
-
 	spin_unlock_irqrestore(&pch->lock, flags);
 
 	return cookie;
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 40082ec..12e94dd 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -2151,22 +2151,6 @@ static int ppc440spe_adma_alloc_chan_resources(struct dma_chan *chan)
 }
 
 /**
- * ppc440spe_desc_assign_cookie - assign a cookie
- */
-static dma_cookie_t ppc440spe_desc_assign_cookie(
-		struct ppc440spe_adma_chan *chan,
-		struct ppc440spe_adma_desc_slot *desc)
-{
-	dma_cookie_t cookie = chan->common.cookie;
-
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	chan->common.cookie = desc->async_tx.cookie = cookie;
-	return cookie;
-}
-
-/**
  * ppc440spe_rxor_set_region_data -
  */
 static void ppc440spe_rxor_set_region(struct ppc440spe_adma_desc_slot *desc,
@@ -2236,8 +2220,7 @@ static dma_cookie_t ppc440spe_adma_tx_submit(struct dma_async_tx_descriptor *tx)
 	slots_per_op = group_start->slots_per_op;
 
 	spin_lock_bh(&chan->lock);
-
-	cookie = ppc440spe_desc_assign_cookie(chan, sw_desc);
+	cookie = dma_cookie_assign(tx);
 
 	if (unlikely(list_empty(&chan->chain))) {
 		/* first peer */
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index c291433..96d0a4f 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -298,13 +298,7 @@ static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
 	else
 		power_up = false;
 
-	cookie = sh_chan->common.cookie;
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-
-	sh_chan->common.cookie = cookie;
-	tx->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 
 	/* Mark all chunks of this descriptor as submitted, move to the queue */
 	list_for_each_entry_safe(chunk, c, desc->node.prev, node) {
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 60473f0..7bb154a 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -257,13 +257,7 @@ static dma_cookie_t sirfsoc_dma_tx_submit(struct dma_async_tx_descriptor *txd)
 	/* Move descriptor to queue */
 	list_move_tail(&sdesc->node, &schan->queued);
 
-	/* Update cookie */
-	cookie = schan->chan.cookie + 1;
-	if (cookie <= 0)
-		cookie = 1;
-
-	schan->chan.cookie = cookie;
-	sdesc->desc.cookie = cookie;
+	cookie = dma_cookie_assign(txd);
 
 	spin_unlock_irqrestore(&schan->lock, flags);
 
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 156b98f..23e2edc 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1220,21 +1220,14 @@ static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx)
 					     chan);
 	struct d40_desc *d40d = container_of(tx, struct d40_desc, txd);
 	unsigned long flags;
+	dma_cookie_t cookie;
 
 	spin_lock_irqsave(&d40c->lock, flags);
-
-	d40c->chan.cookie++;
-
-	if (d40c->chan.cookie < 0)
-		d40c->chan.cookie = 1;
-
-	d40d->txd.cookie = d40c->chan.cookie;
-
+	cookie = dma_cookie_assign(tx);
 	d40_desc_queue(d40c, d40d);
-
 	spin_unlock_irqrestore(&d40c->lock, flags);
 
-	return tx->cookie;
+	return cookie;
 }
 
 static int d40_start(struct d40_chan *d40c)
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 4b61879..b6e83fc 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -350,12 +350,7 @@ static dma_cookie_t td_tx_submit(struct dma_async_tx_descriptor *txd)
 	dma_cookie_t cookie;
 
 	spin_lock_bh(&td_chan->lock);
-
-	cookie = txd->chan->cookie;
-	if (++cookie < 0)
-		cookie = 1;
-	txd->chan->cookie = cookie;
-	txd->cookie = cookie;
+	cookie = dma_cookie_assign(txd);
 
 	if (list_empty(&td_chan->active_list)) {
 		dev_dbg(chan2dev(txd->chan), "%s: started %u\n", __func__,
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index db6d809..66f8fca 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -281,21 +281,6 @@ static void txx9dmac_desc_put(struct txx9dmac_chan *dc,
 	}
 }
 
-/* Called with dc->lock held and bh disabled */
-static dma_cookie_t
-txx9dmac_assign_cookie(struct txx9dmac_chan *dc, struct txx9dmac_desc *desc)
-{
-	dma_cookie_t cookie = dc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	dc->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
 /*----------------------------------------------------------------------*/
 
 static void txx9dmac_dump_regs(struct txx9dmac_chan *dc)
@@ -740,7 +725,7 @@ static dma_cookie_t txx9dmac_tx_submit(struct dma_async_tx_descriptor *tx)
 	dma_cookie_t cookie;
 
 	spin_lock_bh(&dc->lock);
-	cookie = txx9dmac_assign_cookie(dc, desc);
+	cookie = dma_cookie_assign(tx);
 
 	dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u %p\n",
 		 desc->txd.cookie, desc);
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 4/9] dmaengine: consolidate assignment of DMA cookies
@ 2012-03-06 22:34   ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:34 UTC (permalink / raw)
  To: linux-arm-kernel

Everyone deals with assigning DMA cookies in the same way (it's part of
the API so they should be), so lets consolidate the common code into a
helper function to avoid this duplication.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |    9 +++------
 drivers/dma/at_hdmac.c      |   23 +----------------------
 drivers/dma/coh901318.c     |   20 +++-----------------
 drivers/dma/dmaengine.h     |   20 ++++++++++++++++++++
 drivers/dma/dw_dmac.c       |   17 +----------------
 drivers/dma/ep93xx_dma.c    |    9 +--------
 drivers/dma/fsldma.c        |    9 +--------
 drivers/dma/imx-dma.c       |   15 +--------------
 drivers/dma/imx-sdma.c      |   15 +--------------
 drivers/dma/intel_mid_dma.c |    9 +--------
 drivers/dma/ioat/dma.c      |    7 +------
 drivers/dma/ioat/dma_v2.c   |    8 ++------
 drivers/dma/iop-adma.c      |   14 +-------------
 drivers/dma/ipu/ipu_idmac.c |    9 +--------
 drivers/dma/mpc512x_dma.c   |    8 +-------
 drivers/dma/mv_xor.c        |   14 +-------------
 drivers/dma/mxs-dma.c       |   15 +--------------
 drivers/dma/pch_dma.c       |   16 +---------------
 drivers/dma/pl330.c         |   14 ++------------
 drivers/dma/ppc4xx/adma.c   |   19 +------------------
 drivers/dma/shdma.c         |    8 +-------
 drivers/dma/sirf-dma.c      |    8 +-------
 drivers/dma/ste_dma40.c     |   13 +++----------
 drivers/dma/timb_dma.c      |    7 +------
 drivers/dma/txx9dmac.c      |   17 +----------------
 25 files changed, 52 insertions(+), 271 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 87475cb..5996386 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -921,13 +921,10 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
 	struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan);
 	struct pl08x_txd *txd = to_pl08x_txd(tx);
 	unsigned long flags;
+	dma_cookie_t cookie;
 
 	spin_lock_irqsave(&plchan->lock, flags);
-
-	plchan->chan.cookie += 1;
-	if (plchan->chan.cookie < 0)
-		plchan->chan.cookie = 1;
-	tx->cookie = plchan->chan.cookie;
+	cookie = dma_cookie_assign(tx);
 
 	/* Put this onto the pending list */
 	list_add_tail(&txd->node, &plchan->pend_list);
@@ -947,7 +944,7 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_unlock_irqrestore(&plchan->lock, flags);
 
-	return tx->cookie;
+	return cookie;
 }
 
 static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index ce26ba3..df47e7d 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -193,27 +193,6 @@ static void atc_desc_chain(struct at_desc **first, struct at_desc **prev,
 }
 
 /**
- * atc_assign_cookie - compute and assign new cookie
- * @atchan: channel we work on
- * @desc: descriptor to assign cookie for
- *
- * Called with atchan->lock held and bh disabled
- */
-static dma_cookie_t
-atc_assign_cookie(struct at_dma_chan *atchan, struct at_desc *desc)
-{
-	dma_cookie_t cookie = atchan->chan_common.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	atchan->chan_common.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
-/**
  * atc_dostart - starts the DMA engine for real
  * @atchan: the channel we want to start
  * @first: first descriptor in the list we want to begin with
@@ -548,7 +527,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
 	unsigned long		flags;
 
 	spin_lock_irqsave(&atchan->lock, flags);
-	cookie = atc_assign_cookie(atchan, desc);
+	cookie = dma_cookie_assign(tx);
 
 	if (list_empty(&atchan->active_list)) {
 		dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index fb0d124..843a1a3 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -318,20 +318,6 @@ static int coh901318_prep_linked_list(struct coh901318_chan *cohc,
 
 	return 0;
 }
-static dma_cookie_t
-coh901318_assign_cookie(struct coh901318_chan *cohc,
-			struct coh901318_desc *cohd)
-{
-	dma_cookie_t cookie = cohc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	cohc->chan.cookie = cookie;
-	cohd->desc.cookie = cookie;
-
-	return cookie;
-}
 
 static struct coh901318_desc *
 coh901318_desc_get(struct coh901318_chan *cohc)
@@ -966,16 +952,16 @@ coh901318_tx_submit(struct dma_async_tx_descriptor *tx)
 						   desc);
 	struct coh901318_chan *cohc = to_coh901318_chan(tx->chan);
 	unsigned long flags;
+	dma_cookie_t cookie;
 
 	spin_lock_irqsave(&cohc->lock, flags);
-
-	tx->cookie = coh901318_assign_cookie(cohc, cohd);
+	cookie = dma_cookie_assign(tx);
 
 	coh901318_desc_queue(cohc, cohd);
 
 	spin_unlock_irqrestore(&cohc->lock, flags);
 
-	return tx->cookie;
+	return cookie;
 }
 
 static struct dma_async_tx_descriptor *
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 968570d..7692c86 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -7,4 +7,24 @@
 
 #include <linux/dmaengine.h>
 
+/**
+ * dma_cookie_assign - assign a DMA engine cookie to the descriptor
+ * @tx: descriptor needing cookie
+ *
+ * Assign a unique non-zero per-channel cookie to the descriptor.
+ * Note: caller is expected to hold a lock to prevent concurrency.
+ */
+static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
+{
+	struct dma_chan *chan = tx->chan;
+	dma_cookie_t cookie;
+
+	cookie = chan->cookie + 1;
+	if (cookie < DMA_MIN_COOKIE)
+		cookie = DMA_MIN_COOKIE;
+	tx->cookie = chan->cookie = cookie;
+
+	return cookie;
+}
+
 #endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index f10dbe1..5ee9498 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -152,21 +152,6 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
 	}
 }
 
-/* Called with dwc->lock held and bh disabled */
-static dma_cookie_t
-dwc_assign_cookie(struct dw_dma_chan *dwc, struct dw_desc *desc)
-{
-	dma_cookie_t cookie = dwc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	dwc->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
 static void dwc_initialize(struct dw_dma_chan *dwc)
 {
 	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
@@ -616,7 +601,7 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
 	unsigned long		flags;
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	cookie = dwc_assign_cookie(dwc, desc);
+	cookie = dma_cookie_assign(tx);
 
 	/*
 	 * REVISIT: We should attempt to chain as many descriptors as
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 3260198..e5aaae8 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -783,17 +783,10 @@ static dma_cookie_t ep93xx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	unsigned long flags;
 
 	spin_lock_irqsave(&edmac->lock, flags);
-
-	cookie = edmac->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
+	cookie = dma_cookie_assign(tx);
 
 	desc = container_of(tx, struct ep93xx_dma_desc, txd);
 
-	edmac->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
 	/*
 	 * If nothing is currently prosessed, we push this descriptor
 	 * directly to the hardware. Otherwise we put the descriptor
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 2ebbe57..04b4347 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -414,17 +414,10 @@ static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	 * assign cookies to all of the software descriptors
 	 * that make up this transaction
 	 */
-	cookie = chan->common.cookie;
 	list_for_each_entry(child, &desc->tx_list, node) {
-		cookie++;
-		if (cookie < DMA_MIN_COOKIE)
-			cookie = DMA_MIN_COOKIE;
-
-		child->async_tx.cookie = cookie;
+		cookie = dma_cookie_assign(&child->async_tx);
 	}
 
-	chan->common.cookie = cookie;
-
 	/* put this transaction onto the tail of the pending queue */
 	append_ld_queue(chan, desc);
 
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 51251a6..42154b6 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -165,19 +165,6 @@ static enum dma_status imxdma_tx_status(struct dma_chan *chan,
 	return ret;
 }
 
-static dma_cookie_t imxdma_assign_cookie(struct imxdma_channel *imxdma)
-{
-	dma_cookie_t cookie = imxdma->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	imxdma->chan.cookie = cookie;
-	imxdma->desc.cookie = cookie;
-
-	return cookie;
-}
-
 static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx)
 {
 	struct imxdma_channel *imxdmac = to_imxdma_chan(tx->chan);
@@ -185,7 +172,7 @@ static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_lock_irq(&imxdmac->lock);
 
-	cookie = imxdma_assign_cookie(imxdmac);
+	cookie = dma_cookie_assign(tx);
 
 	imx_dma_enable(imxdmac->imxdma_channel);
 
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9950ec3..4e4f40e 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -817,19 +817,6 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
 	__raw_writel(1 << channel, sdma->regs + SDMA_H_START);
 }
 
-static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac)
-{
-	dma_cookie_t cookie = sdmac->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	sdmac->chan.cookie = cookie;
-	sdmac->desc.cookie = cookie;
-
-	return cookie;
-}
-
 static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
 {
 	return container_of(chan, struct sdma_channel, chan);
@@ -844,7 +831,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_lock_irqsave(&sdmac->lock, flags);
 
-	cookie = sdma_assign_cookie(sdmac);
+	cookie = dma_cookie_assign(tx);
 
 	sdma_enable_channel(sdma, sdmac->channel);
 
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index a907dd6..dfe4396 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -436,14 +436,7 @@ static dma_cookie_t intel_mid_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	dma_cookie_t		cookie;
 
 	spin_lock_bh(&midc->lock);
-	cookie = midc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	midc->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
+	cookie = dma_cookie_assign(tx);
 
 	if (list_empty(&midc->active_list))
 		list_add_tail(&desc->desc_node, &midc->active_list);
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index dfe411b..5c06117 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -237,12 +237,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	spin_lock_bh(&ioat->desc_lock);
 	/* cookie incr and addition to used_list must be atomic */
-	cookie = c->cookie;
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	c->cookie = cookie;
-	tx->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 	dev_dbg(to_dev(&ioat->base), "%s: cookie: %d\n", __func__, cookie);
 
 	/* write address into NextDescriptor field of last desc in chain */
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 6c1e675..17ecacb 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -400,13 +400,9 @@ static dma_cookie_t ioat2_tx_submit_unlock(struct dma_async_tx_descriptor *tx)
 	struct dma_chan *c = tx->chan;
 	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
 	struct ioat_chan_common *chan = &ioat->base;
-	dma_cookie_t cookie = c->cookie;
+	dma_cookie_t cookie;
 
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	tx->cookie = cookie;
-	c->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 	dev_dbg(to_dev(&ioat->base), "%s: cookie: %d\n", __func__, cookie);
 
 	if (!test_and_set_bit(IOAT_COMPLETION_PENDING, &chan->state))
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 650bf1e..f2392d5 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -440,18 +440,6 @@ iop_adma_alloc_slots(struct iop_adma_chan *iop_chan, int num_slots,
 	return NULL;
 }
 
-static dma_cookie_t
-iop_desc_assign_cookie(struct iop_adma_chan *iop_chan,
-	struct iop_adma_desc_slot *desc)
-{
-	dma_cookie_t cookie = iop_chan->common.cookie;
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	iop_chan->common.cookie = desc->async_tx.cookie = cookie;
-	return cookie;
-}
-
 static void iop_adma_check_threshold(struct iop_adma_chan *iop_chan)
 {
 	dev_dbg(iop_chan->device->common.dev, "pending: %d\n",
@@ -479,7 +467,7 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx)
 	slots_per_op = grp_start->slots_per_op;
 
 	spin_lock_bh(&iop_chan->lock);
-	cookie = iop_desc_assign_cookie(iop_chan, sw_desc);
+	cookie = dma_cookie_assign(tx);
 
 	old_chain_tail = list_entry(iop_chan->chain.prev,
 		struct iop_adma_desc_slot, chain_node);
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 0fcff65..d4620c5 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -867,14 +867,7 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
 
-	cookie = ichan->dma_chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	/* from dmaengine.h: "last cookie value returned to client" */
-	ichan->dma_chan.cookie = cookie;
-	tx->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 
 	/* ipu->lock can be taken under ichan->lock, but not v.v. */
 	spin_lock_irqsave(&ichan->lock, flags);
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index c56b3fe..0253d5a 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -439,13 +439,7 @@ static dma_cookie_t mpc_dma_tx_submit(struct dma_async_tx_descriptor *txd)
 		mpc_dma_execute(mchan);
 
 	/* Update cookie */
-	cookie = mchan->chan.cookie + 1;
-	if (cookie <= 0)
-		cookie = 1;
-
-	mchan->chan.cookie = cookie;
-	mdesc->desc.cookie = cookie;
-
+	cookie = dma_cookie_assign(txd);
 	spin_unlock_irqrestore(&mchan->lock, flags);
 
 	return cookie;
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index ee61778..d9810ce 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -536,18 +536,6 @@ mv_xor_alloc_slots(struct mv_xor_chan *mv_chan, int num_slots,
 	return NULL;
 }
 
-static dma_cookie_t
-mv_desc_assign_cookie(struct mv_xor_chan *mv_chan,
-		      struct mv_xor_desc_slot *desc)
-{
-	dma_cookie_t cookie = mv_chan->common.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-	mv_chan->common.cookie = desc->async_tx.cookie = cookie;
-	return cookie;
-}
-
 /************************ DMA engine API functions ****************************/
 static dma_cookie_t
 mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
@@ -565,7 +553,7 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
 	grp_start = sw_desc->group_head;
 
 	spin_lock_bh(&mv_chan->lock);
-	cookie = mv_desc_assign_cookie(mv_chan, sw_desc);
+	cookie = dma_cookie_assign(tx);
 
 	if (list_empty(&mv_chan->chain))
 		list_splice_init(&sw_desc->tx_list, &mv_chan->chain);
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index daa84ee..4d3b6ff 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -194,19 +194,6 @@ static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
 	mxs_chan->status = DMA_IN_PROGRESS;
 }
 
-static dma_cookie_t mxs_dma_assign_cookie(struct mxs_dma_chan *mxs_chan)
-{
-	dma_cookie_t cookie = mxs_chan->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	mxs_chan->chan.cookie = cookie;
-	mxs_chan->desc.cookie = cookie;
-
-	return cookie;
-}
-
 static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
 {
 	return container_of(chan, struct mxs_dma_chan, chan);
@@ -218,7 +205,7 @@ static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	mxs_dma_enable_chan(mxs_chan);
 
-	return mxs_dma_assign_cookie(mxs_chan);
+	return dma_cookie_assign(tx);
 }
 
 static void mxs_dma_tasklet(unsigned long data)
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 2b3479d..5218e48 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -417,20 +417,6 @@ static void pdc_advance_work(struct pch_dma_chan *pd_chan)
 	}
 }
 
-static dma_cookie_t pdc_assign_cookie(struct pch_dma_chan *pd_chan,
-				      struct pch_dma_desc *desc)
-{
-	dma_cookie_t cookie = pd_chan->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	pd_chan->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
 static dma_cookie_t pd_tx_submit(struct dma_async_tx_descriptor *txd)
 {
 	struct pch_dma_desc *desc = to_pd_desc(txd);
@@ -438,7 +424,7 @@ static dma_cookie_t pd_tx_submit(struct dma_async_tx_descriptor *txd)
 	dma_cookie_t cookie;
 
 	spin_lock(&pd_chan->lock);
-	cookie = pdc_assign_cookie(pd_chan, desc);
+	cookie = dma_cookie_assign(txd);
 
 	if (list_empty(&pd_chan->active_list)) {
 		list_add_tail(&desc->desc_node, &pd_chan->active_list);
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index d7b0af2..ec9638b 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -429,26 +429,16 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx)
 	spin_lock_irqsave(&pch->lock, flags);
 
 	/* Assign cookies to all nodes */
-	cookie = tx->chan->cookie;
-
 	while (!list_empty(&last->node)) {
 		desc = list_entry(last->node.next, struct dma_pl330_desc, node);
 
-		if (++cookie < 0)
-			cookie = 1;
-		desc->txd.cookie = cookie;
+		dma_cookie_assign(&desc->txd);
 
 		list_move_tail(&desc->node, &pch->work_list);
 	}
 
-	if (++cookie < 0)
-		cookie = 1;
-	last->txd.cookie = cookie;
-
+	cookie = dma_cookie_assign(&last->txd);
 	list_add_tail(&last->node, &pch->work_list);
-
-	tx->chan->cookie = cookie;
-
 	spin_unlock_irqrestore(&pch->lock, flags);
 
 	return cookie;
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 40082ec..12e94dd 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -2151,22 +2151,6 @@ static int ppc440spe_adma_alloc_chan_resources(struct dma_chan *chan)
 }
 
 /**
- * ppc440spe_desc_assign_cookie - assign a cookie
- */
-static dma_cookie_t ppc440spe_desc_assign_cookie(
-		struct ppc440spe_adma_chan *chan,
-		struct ppc440spe_adma_desc_slot *desc)
-{
-	dma_cookie_t cookie = chan->common.cookie;
-
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	chan->common.cookie = desc->async_tx.cookie = cookie;
-	return cookie;
-}
-
-/**
  * ppc440spe_rxor_set_region_data -
  */
 static void ppc440spe_rxor_set_region(struct ppc440spe_adma_desc_slot *desc,
@@ -2236,8 +2220,7 @@ static dma_cookie_t ppc440spe_adma_tx_submit(struct dma_async_tx_descriptor *tx)
 	slots_per_op = group_start->slots_per_op;
 
 	spin_lock_bh(&chan->lock);
-
-	cookie = ppc440spe_desc_assign_cookie(chan, sw_desc);
+	cookie = dma_cookie_assign(tx);
 
 	if (unlikely(list_empty(&chan->chain))) {
 		/* first peer */
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index c291433..96d0a4f 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -298,13 +298,7 @@ static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
 	else
 		power_up = false;
 
-	cookie = sh_chan->common.cookie;
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-
-	sh_chan->common.cookie = cookie;
-	tx->cookie = cookie;
+	cookie = dma_cookie_assign(tx);
 
 	/* Mark all chunks of this descriptor as submitted, move to the queue */
 	list_for_each_entry_safe(chunk, c, desc->node.prev, node) {
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 60473f0..7bb154a 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -257,13 +257,7 @@ static dma_cookie_t sirfsoc_dma_tx_submit(struct dma_async_tx_descriptor *txd)
 	/* Move descriptor to queue */
 	list_move_tail(&sdesc->node, &schan->queued);
 
-	/* Update cookie */
-	cookie = schan->chan.cookie + 1;
-	if (cookie <= 0)
-		cookie = 1;
-
-	schan->chan.cookie = cookie;
-	sdesc->desc.cookie = cookie;
+	cookie = dma_cookie_assign(txd);
 
 	spin_unlock_irqrestore(&schan->lock, flags);
 
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 156b98f..23e2edc 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1220,21 +1220,14 @@ static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx)
 					     chan);
 	struct d40_desc *d40d = container_of(tx, struct d40_desc, txd);
 	unsigned long flags;
+	dma_cookie_t cookie;
 
 	spin_lock_irqsave(&d40c->lock, flags);
-
-	d40c->chan.cookie++;
-
-	if (d40c->chan.cookie < 0)
-		d40c->chan.cookie = 1;
-
-	d40d->txd.cookie = d40c->chan.cookie;
-
+	cookie = dma_cookie_assign(tx);
 	d40_desc_queue(d40c, d40d);
-
 	spin_unlock_irqrestore(&d40c->lock, flags);
 
-	return tx->cookie;
+	return cookie;
 }
 
 static int d40_start(struct d40_chan *d40c)
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 4b61879..b6e83fc 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -350,12 +350,7 @@ static dma_cookie_t td_tx_submit(struct dma_async_tx_descriptor *txd)
 	dma_cookie_t cookie;
 
 	spin_lock_bh(&td_chan->lock);
-
-	cookie = txd->chan->cookie;
-	if (++cookie < 0)
-		cookie = 1;
-	txd->chan->cookie = cookie;
-	txd->cookie = cookie;
+	cookie = dma_cookie_assign(txd);
 
 	if (list_empty(&td_chan->active_list)) {
 		dev_dbg(chan2dev(txd->chan), "%s: started %u\n", __func__,
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index db6d809..66f8fca 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -281,21 +281,6 @@ static void txx9dmac_desc_put(struct txx9dmac_chan *dc,
 	}
 }
 
-/* Called with dc->lock held and bh disabled */
-static dma_cookie_t
-txx9dmac_assign_cookie(struct txx9dmac_chan *dc, struct txx9dmac_desc *desc)
-{
-	dma_cookie_t cookie = dc->chan.cookie;
-
-	if (++cookie < 0)
-		cookie = 1;
-
-	dc->chan.cookie = cookie;
-	desc->txd.cookie = cookie;
-
-	return cookie;
-}
-
 /*----------------------------------------------------------------------*/
 
 static void txx9dmac_dump_regs(struct txx9dmac_chan *dc)
@@ -740,7 +725,7 @@ static dma_cookie_t txx9dmac_tx_submit(struct dma_async_tx_descriptor *tx)
 	dma_cookie_t cookie;
 
 	spin_lock_bh(&dc->lock);
-	cookie = txx9dmac_assign_cookie(dc, desc);
+	cookie = dma_cookie_assign(tx);
 
 	dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u %p\n",
 		 desc->txd.cookie, desc);
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-06 22:35   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:35 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul
  Cc: Viresh Kumar, Stephen Warren, Linus Walleij, Srinidhi Kasagar,
	linuxppc-dev, linux-arm-kernel

Provide a common function to do the cookie mechanics for completing
a DMA descriptor.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |    2 +-
 drivers/dma/at_hdmac.c      |    2 +-
 drivers/dma/coh901318.c     |    2 +-
 drivers/dma/dmaengine.h     |   18 ++++++++++++++++++
 drivers/dma/dw_dmac.c       |    2 +-
 drivers/dma/ep93xx_dma.c    |    2 +-
 drivers/dma/fsldma.c        |    2 +-
 drivers/dma/imx-dma.c       |    2 +-
 drivers/dma/imx-sdma.c      |    2 +-
 drivers/dma/intel_mid_dma.c |    2 +-
 drivers/dma/ioat/dma.c      |    3 +--
 drivers/dma/ioat/dma_v2.c   |    3 +--
 drivers/dma/ioat/dma_v3.c   |    3 +--
 drivers/dma/ipu/ipu_idmac.c |    2 +-
 drivers/dma/mxs-dma.c       |    2 +-
 drivers/dma/pl330.c         |    2 +-
 drivers/dma/ste_dma40.c     |    2 +-
 drivers/dma/timb_dma.c      |    2 +-
 drivers/dma/txx9dmac.c      |    2 +-
 19 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 5996386..f0888c1 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1540,7 +1540,7 @@ static void pl08x_tasklet(unsigned long data)
 
 	if (txd) {
 		/* Update last completed */
-		plchan->chan.completed_cookie = txd->tx.cookie;
+		dma_cookie_complete(&txd->tx);
 	}
 
 	/* If a new descriptor is queued, set it up plchan->at is NULL here */
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index df47e7d..b282630 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -249,7 +249,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 	dev_vdbg(chan2dev(&atchan->chan_common),
 		"descriptor %u complete\n", txd->cookie);
 
-	atchan->chan_common.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 
 	/* move children to free_list */
 	list_splice_init(&desc->tx_list, &atchan->free_list);
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 843a1a3..24837d7 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -691,7 +691,7 @@ static void dma_tasklet(unsigned long data)
 	callback_param = cohd_fin->desc.callback_param;
 
 	/* sign this job as completed on the channel */
-	cohc->chan.completed_cookie = cohd_fin->desc.cookie;
+	dma_cookie_complete(&cohd_fin->desc);
 
 	/* release the lli allocation and remove the descriptor */
 	coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli);
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 7692c86..47e0997 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -5,6 +5,7 @@
 #ifndef DMAENGINE_H
 #define DMAENGINE_H
 
+#include <linux/bug.h>
 #include <linux/dmaengine.h>
 
 /**
@@ -27,4 +28,21 @@ static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
 	return cookie;
 }
 
+/**
+ * dma_cookie_complete - complete a descriptor
+ * @tx: descriptor to complete
+ *
+ * Mark this descriptor complete by updating the channels completed
+ * cookie marker.  Zero the descriptors cookie to prevent accidental
+ * repeated completions.
+ *
+ * Note: caller is expected to hold a lock to prevent concurrency.
+ */
+static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
+{
+	BUG_ON(tx->cookie < DMA_MIN_COOKIE);
+	tx->chan->completed_cookie = tx->cookie;
+	tx->cookie = 0;
+}
+
 #endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 5ee9498..a190c88 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -231,7 +231,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
 	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	dwc->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	if (callback_required) {
 		callback = txd->callback;
 		param = txd->callback_param;
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index e5aaae8..1c56f75 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -703,7 +703,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
 	desc = ep93xx_dma_get_active(edmac);
 	if (desc) {
 		if (desc->complete) {
-			edmac->chan.completed_cookie = desc->txd.cookie;
+			dma_cookie_complete(&desc->txd);
 			list_splice_init(&edmac->active, &list);
 		}
 		callback = desc->txd.callback;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 04b4347..f36e8b1 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1081,8 +1081,8 @@ static void dma_do_tasklet(unsigned long data)
 
 		desc = to_fsl_desc(chan->ld_running.prev);
 		cookie = desc->async_tx.cookie;
+		dma_cookie_complete(&desc->async_tx);
 
-		chan->common.completed_cookie = cookie;
 		chan_dbg(chan, "completed_cookie=%d\n", cookie);
 	}
 
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 42154b6..f1226ad 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -66,7 +66,7 @@ static void imxdma_handle(struct imxdma_channel *imxdmac)
 {
 	if (imxdmac->desc.callback)
 		imxdmac->desc.callback(imxdmac->desc.callback_param);
-	imxdmac->chan.completed_cookie = imxdmac->desc.cookie;
+	dma_cookie_complete(&imxdmac->desc);
 }
 
 static void imxdma_irq_handler(int channel, void *data)
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 4e4f40e..4406be2 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -524,7 +524,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
 	else
 		sdmac->status = DMA_SUCCESS;
 
-	sdmac->chan.completed_cookie = sdmac->desc.cookie;
+	dma_cookie_complete(&sdmac->desc);
 	if (sdmac->desc.callback)
 		sdmac->desc.callback(sdmac->desc.callback_param);
 }
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index dfe4396..340509e 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -290,7 +290,7 @@ static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
 	struct intel_mid_dma_lli	*llitem;
 	void *param_txd = NULL;
 
-	midc->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	callback_txd = txd->callback;
 	param_txd = txd->callback_param;
 
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 5c06117..b0517c8 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -600,8 +600,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
 		 */
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
-			chan->common.completed_cookie = tx->cookie;
-			tx->cookie = 0;
+			dma_cookie_complete(tx);
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
 			ioat->active -= desc->hw->tx_cnt;
 			if (tx->callback) {
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 17ecacb..e8e110f 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -149,8 +149,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
-			chan->common.completed_cookie = tx->cookie;
-			tx->cookie = 0;
+			dma_cookie_complete(tx);
 			if (tx->callback) {
 				tx->callback(tx->callback_param);
 				tx->callback = NULL;
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index d4afac7..1bda46c 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -277,9 +277,8 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		tx = &desc->txd;
 		if (tx->cookie) {
-			chan->common.completed_cookie = tx->cookie;
+			dma_cookie_complete(tx);
 			ioat3_dma_unmap(ioat, desc, idx + i);
-			tx->cookie = 0;
 			if (tx->callback) {
 				tx->callback(tx->callback_param);
 				tx->callback = NULL;
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index d4620c5..bff9250 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1289,7 +1289,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 	/* Flip the active buffer - even if update above failed */
 	ichan->active_buffer = !ichan->active_buffer;
 	if (done)
-		ichan->dma_chan.completed_cookie = desc->txd.cookie;
+		dma_cookie_complete(&desc->txd);
 
 	callback = desc->txd.callback;
 	callback_param = desc->txd.callback_param;
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 4d3b6ff..5f3492e 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -262,7 +262,7 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
 		stat1 &= ~(1 << channel);
 
 		if (mxs_chan->status == DMA_SUCCESS)
-			mxs_chan->chan.completed_cookie = mxs_chan->desc.cookie;
+			dma_cookie_complete(&mxs_chan->desc);
 
 		/* schedule tasklet on this channel */
 		tasklet_schedule(&mxs_chan->tasklet);
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index ec9638b..76871b8 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -233,7 +233,7 @@ static void pl330_tasklet(unsigned long data)
 	/* Pick up ripe tomatoes */
 	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
 		if (desc->status == DONE) {
-			pch->chan.completed_cookie = desc->txd.cookie;
+			dma_cookie_complete(&desc->txd);
 			list_move_tail(&desc->node, &list);
 		}
 
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 23e2edc..c246375 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1347,7 +1347,7 @@ static void dma_tasklet(unsigned long data)
 		goto err;
 
 	if (!d40d->cyclic)
-		d40c->chan.completed_cookie = d40d->txd.cookie;
+		dma_cookie_complete(&d40d->txd);
 
 	/*
 	 * If terminating a channel pending_tx is set to zero.
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index b6e83fc..1845ac9 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -285,7 +285,7 @@ static void __td_finish(struct timb_dma_chan *td_chan)
 	else
 		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR);
 */
-	td_chan->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	td_chan->ongoing = false;
 
 	callback = txd->callback;
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 66f8fca..8a5225b 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -411,7 +411,7 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
 	dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
 		 txd->cookie, desc);
 
-	dc->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	callback = txd->callback;
 	param = txd->callback_param;
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
@ 2012-03-06 22:35   ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:35 UTC (permalink / raw)
  To: linux-arm-kernel

Provide a common function to do the cookie mechanics for completing
a DMA descriptor.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |    2 +-
 drivers/dma/at_hdmac.c      |    2 +-
 drivers/dma/coh901318.c     |    2 +-
 drivers/dma/dmaengine.h     |   18 ++++++++++++++++++
 drivers/dma/dw_dmac.c       |    2 +-
 drivers/dma/ep93xx_dma.c    |    2 +-
 drivers/dma/fsldma.c        |    2 +-
 drivers/dma/imx-dma.c       |    2 +-
 drivers/dma/imx-sdma.c      |    2 +-
 drivers/dma/intel_mid_dma.c |    2 +-
 drivers/dma/ioat/dma.c      |    3 +--
 drivers/dma/ioat/dma_v2.c   |    3 +--
 drivers/dma/ioat/dma_v3.c   |    3 +--
 drivers/dma/ipu/ipu_idmac.c |    2 +-
 drivers/dma/mxs-dma.c       |    2 +-
 drivers/dma/pl330.c         |    2 +-
 drivers/dma/ste_dma40.c     |    2 +-
 drivers/dma/timb_dma.c      |    2 +-
 drivers/dma/txx9dmac.c      |    2 +-
 19 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 5996386..f0888c1 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1540,7 +1540,7 @@ static void pl08x_tasklet(unsigned long data)
 
 	if (txd) {
 		/* Update last completed */
-		plchan->chan.completed_cookie = txd->tx.cookie;
+		dma_cookie_complete(&txd->tx);
 	}
 
 	/* If a new descriptor is queued, set it up plchan->at is NULL here */
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index df47e7d..b282630 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -249,7 +249,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 	dev_vdbg(chan2dev(&atchan->chan_common),
 		"descriptor %u complete\n", txd->cookie);
 
-	atchan->chan_common.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 
 	/* move children to free_list */
 	list_splice_init(&desc->tx_list, &atchan->free_list);
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 843a1a3..24837d7 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -691,7 +691,7 @@ static void dma_tasklet(unsigned long data)
 	callback_param = cohd_fin->desc.callback_param;
 
 	/* sign this job as completed on the channel */
-	cohc->chan.completed_cookie = cohd_fin->desc.cookie;
+	dma_cookie_complete(&cohd_fin->desc);
 
 	/* release the lli allocation and remove the descriptor */
 	coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli);
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 7692c86..47e0997 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -5,6 +5,7 @@
 #ifndef DMAENGINE_H
 #define DMAENGINE_H
 
+#include <linux/bug.h>
 #include <linux/dmaengine.h>
 
 /**
@@ -27,4 +28,21 @@ static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
 	return cookie;
 }
 
+/**
+ * dma_cookie_complete - complete a descriptor
+ * @tx: descriptor to complete
+ *
+ * Mark this descriptor complete by updating the channels completed
+ * cookie marker.  Zero the descriptors cookie to prevent accidental
+ * repeated completions.
+ *
+ * Note: caller is expected to hold a lock to prevent concurrency.
+ */
+static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
+{
+	BUG_ON(tx->cookie < DMA_MIN_COOKIE);
+	tx->chan->completed_cookie = tx->cookie;
+	tx->cookie = 0;
+}
+
 #endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 5ee9498..a190c88 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -231,7 +231,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
 	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	dwc->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	if (callback_required) {
 		callback = txd->callback;
 		param = txd->callback_param;
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index e5aaae8..1c56f75 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -703,7 +703,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
 	desc = ep93xx_dma_get_active(edmac);
 	if (desc) {
 		if (desc->complete) {
-			edmac->chan.completed_cookie = desc->txd.cookie;
+			dma_cookie_complete(&desc->txd);
 			list_splice_init(&edmac->active, &list);
 		}
 		callback = desc->txd.callback;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 04b4347..f36e8b1 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1081,8 +1081,8 @@ static void dma_do_tasklet(unsigned long data)
 
 		desc = to_fsl_desc(chan->ld_running.prev);
 		cookie = desc->async_tx.cookie;
+		dma_cookie_complete(&desc->async_tx);
 
-		chan->common.completed_cookie = cookie;
 		chan_dbg(chan, "completed_cookie=%d\n", cookie);
 	}
 
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 42154b6..f1226ad 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -66,7 +66,7 @@ static void imxdma_handle(struct imxdma_channel *imxdmac)
 {
 	if (imxdmac->desc.callback)
 		imxdmac->desc.callback(imxdmac->desc.callback_param);
-	imxdmac->chan.completed_cookie = imxdmac->desc.cookie;
+	dma_cookie_complete(&imxdmac->desc);
 }
 
 static void imxdma_irq_handler(int channel, void *data)
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 4e4f40e..4406be2 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -524,7 +524,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
 	else
 		sdmac->status = DMA_SUCCESS;
 
-	sdmac->chan.completed_cookie = sdmac->desc.cookie;
+	dma_cookie_complete(&sdmac->desc);
 	if (sdmac->desc.callback)
 		sdmac->desc.callback(sdmac->desc.callback_param);
 }
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index dfe4396..340509e 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -290,7 +290,7 @@ static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
 	struct intel_mid_dma_lli	*llitem;
 	void *param_txd = NULL;
 
-	midc->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	callback_txd = txd->callback;
 	param_txd = txd->callback_param;
 
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 5c06117..b0517c8 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -600,8 +600,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
 		 */
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
-			chan->common.completed_cookie = tx->cookie;
-			tx->cookie = 0;
+			dma_cookie_complete(tx);
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
 			ioat->active -= desc->hw->tx_cnt;
 			if (tx->callback) {
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 17ecacb..e8e110f 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -149,8 +149,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		if (tx->cookie) {
 			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
-			chan->common.completed_cookie = tx->cookie;
-			tx->cookie = 0;
+			dma_cookie_complete(tx);
 			if (tx->callback) {
 				tx->callback(tx->callback_param);
 				tx->callback = NULL;
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index d4afac7..1bda46c 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -277,9 +277,8 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete)
 		dump_desc_dbg(ioat, desc);
 		tx = &desc->txd;
 		if (tx->cookie) {
-			chan->common.completed_cookie = tx->cookie;
+			dma_cookie_complete(tx);
 			ioat3_dma_unmap(ioat, desc, idx + i);
-			tx->cookie = 0;
 			if (tx->callback) {
 				tx->callback(tx->callback_param);
 				tx->callback = NULL;
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index d4620c5..bff9250 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1289,7 +1289,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 	/* Flip the active buffer - even if update above failed */
 	ichan->active_buffer = !ichan->active_buffer;
 	if (done)
-		ichan->dma_chan.completed_cookie = desc->txd.cookie;
+		dma_cookie_complete(&desc->txd);
 
 	callback = desc->txd.callback;
 	callback_param = desc->txd.callback_param;
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 4d3b6ff..5f3492e 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -262,7 +262,7 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
 		stat1 &= ~(1 << channel);
 
 		if (mxs_chan->status == DMA_SUCCESS)
-			mxs_chan->chan.completed_cookie = mxs_chan->desc.cookie;
+			dma_cookie_complete(&mxs_chan->desc);
 
 		/* schedule tasklet on this channel */
 		tasklet_schedule(&mxs_chan->tasklet);
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index ec9638b..76871b8 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -233,7 +233,7 @@ static void pl330_tasklet(unsigned long data)
 	/* Pick up ripe tomatoes */
 	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
 		if (desc->status == DONE) {
-			pch->chan.completed_cookie = desc->txd.cookie;
+			dma_cookie_complete(&desc->txd);
 			list_move_tail(&desc->node, &list);
 		}
 
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 23e2edc..c246375 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1347,7 +1347,7 @@ static void dma_tasklet(unsigned long data)
 		goto err;
 
 	if (!d40d->cyclic)
-		d40c->chan.completed_cookie = d40d->txd.cookie;
+		dma_cookie_complete(&d40d->txd);
 
 	/*
 	 * If terminating a channel pending_tx is set to zero.
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index b6e83fc..1845ac9 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -285,7 +285,7 @@ static void __td_finish(struct timb_dma_chan *td_chan)
 	else
 		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR);
 */
-	td_chan->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	td_chan->ongoing = false;
 
 	callback = txd->callback;
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 66f8fca..8a5225b 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -411,7 +411,7 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
 	dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
 		 txd->cookie, desc);
 
-	dc->chan.completed_cookie = txd->cookie;
+	dma_cookie_complete(txd);
 	callback = txd->callback;
 	param = txd->callback_param;
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 6/9] dmaengine: consolidate tx_status functions
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-06 22:35   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:35 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul
  Cc: Viresh Kumar, Stephen Warren, Linus Walleij, Srinidhi Kasagar,
	Barry Song, linuxppc-dev, linux-arm-kernel

Now that we have the completed cookie in the dma_chan structure, we
can consolidate the tx_status functions by providing a function to set
the txstate structure and returning the DMA status.  We also provide
a separate helper to set the residue for cookies which are still in
progress.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |   22 ++++------------------
 drivers/dma/at_hdmac.c      |   18 ++++++------------
 drivers/dma/coh901318.c     |   13 ++++---------
 drivers/dma/dmaengine.h     |   31 +++++++++++++++++++++++++++++++
 drivers/dma/dw_dmac.c       |   19 ++++---------------
 drivers/dma/ep93xx_dma.c    |    7 +------
 drivers/dma/fsldma.c        |   11 +++--------
 drivers/dma/imx-dma.c       |   11 +----------
 drivers/dma/intel_mid_dma.c |   19 +++----------------
 drivers/dma/ioat/dma.c      |    8 +++++---
 drivers/dma/ioat/dma.h      |   21 ---------------------
 drivers/dma/ioat/dma_v3.c   |    8 +++++---
 drivers/dma/iop-adma.c      |   16 +++-------------
 drivers/dma/mpc512x_dma.c   |    9 +++------
 drivers/dma/mv_xor.c        |   14 ++------------
 drivers/dma/pch_dma.c       |   11 ++---------
 drivers/dma/pl330.c         |   13 +------------
 drivers/dma/ppc4xx/adma.c   |   16 ++--------------
 drivers/dma/shdma.c         |   11 +----------
 drivers/dma/sirf-dma.c      |    9 +++------
 drivers/dma/ste_dma40.c     |   14 ++++----------
 drivers/dma/timb_dma.c      |   11 ++---------
 drivers/dma/txx9dmac.c      |   16 +++-------------
 23 files changed, 93 insertions(+), 235 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index f0888c1..2781a2b 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -964,31 +964,17 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
 		dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
 	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status ret;
-	u32 bytesleft = 0;
 
-	last_used = plchan->chan.cookie;
-	last_complete = plchan->chan.completed_cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
-	if (ret == DMA_SUCCESS) {
-		dma_set_tx_state(txstate, last_complete, last_used, 0);
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_SUCCESS)
 		return ret;
-	}
 
 	/*
 	 * This cookie not complete yet
+	 * Get number of bytes left in the active transactions and queue
 	 */
-	last_used = plchan->chan.cookie;
-	last_complete = plchan->chan.completed_cookie;
-
-	/* Get number of bytes left in the active transactions and queue */
-	bytesleft = pl08x_getbytes_chan(plchan);
-
-	dma_set_tx_state(txstate, last_complete, last_used,
-			 bytesleft);
+	dma_set_residue(txstate, pl08x_getbytes_chan(plchan));
 
 	if (plchan->state == PL08X_CHAN_PAUSED)
 		return DMA_PAUSED;
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index b282630..8a32974 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -996,26 +996,20 @@ atc_tx_status(struct dma_chan *chan,
 
 	spin_lock_irqsave(&atchan->lock, flags);
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		atc_cleanup_descriptors(atchan);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
+	last_complete = chan->completed_cookie;
+	last_used = chan->cookie;
+
 	spin_unlock_irqrestore(&atchan->lock, flags);
 
 	if (ret != DMA_SUCCESS)
-		dma_set_tx_state(txstate, last_complete, last_used,
-			atc_first_active(atchan)->len);
-	else
-		dma_set_tx_state(txstate, last_complete, last_used, 0);
+		dma_set_residue(txstate, atc_first_active(atchan)->len);
 
 	if (atc_chan_is_paused(atchan))
 		ret = DMA_PAUSED;
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 24837d7..f350517 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -1151,17 +1151,12 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		 struct dma_tx_state *txstate)
 {
 	struct coh901318_chan *cohc = to_coh901318_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	int ret;
-
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
+	enum dma_status ret;
 
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
+	/* FIXME: should be conditional on ret != DMA_SUCCESS? */
+	dma_set_residue(txstate, coh901318_get_bytes_left(chan));
 
-	dma_set_tx_state(txstate, last_complete, last_used,
-			 coh901318_get_bytes_left(chan));
 	if (ret == DMA_IN_PROGRESS && cohc->stopped)
 		ret = DMA_PAUSED;
 
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 47e0997..1ca5e0e 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -45,4 +45,35 @@ static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
 	tx->cookie = 0;
 }
 
+/**
+ * dma_cookie_status - report cookie status
+ * @chan: dma channel
+ * @cookie: cookie we are interested in
+ * @state: dma_tx_state structure to return last/used cookies
+ *
+ * Report the status of the cookie, filling in the state structure if
+ * non-NULL.  No locking is required.
+ */
+static inline enum dma_status dma_cookie_status(struct dma_chan *chan,
+	dma_cookie_t cookie, struct dma_tx_state *state)
+{
+	dma_cookie_t used, complete;
+
+	used = chan->cookie;
+	complete = chan->completed_cookie;
+	barrier();
+	if (state) {
+		state->last = complete;
+		state->used = used;
+		state->residue = 0;
+	}
+	return dma_async_is_complete(cookie, complete, used);
+}
+
+static inline void dma_set_residue(struct dma_tx_state *state, u32 residue)
+{
+	if (state)
+		state->residue = residue;
+}
+
 #endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index a190c88..acc3bc0 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -937,28 +937,17 @@ dwc_tx_status(struct dma_chan *chan,
 	      struct dma_tx_state *txstate)
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	dma_cookie_t		last_used;
-	dma_cookie_t		last_complete;
-	int			ret;
+	enum dma_status		ret;
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
 	if (ret != DMA_SUCCESS)
-		dma_set_tx_state(txstate, last_complete, last_used,
-				dwc_first_active(dwc)->len);
-	else
-		dma_set_tx_state(txstate, last_complete, last_used, 0);
+		dma_set_residue(txstate, dwc_first_active(dwc)->len);
 
 	if (dwc->paused)
 		return DMA_PAUSED;
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 1c56f75..142ebf0 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -1241,18 +1241,13 @@ static enum dma_status ep93xx_dma_tx_status(struct dma_chan *chan,
 					    struct dma_tx_state *state)
 {
 	struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
-	dma_cookie_t last_used, last_completed;
 	enum dma_status ret;
 	unsigned long flags;
 
 	spin_lock_irqsave(&edmac->lock, flags);
-	last_used = chan->cookie;
-	last_completed = chan->completed_cookie;
+	ret = dma_cookie_status(chan, cookie, state);
 	spin_unlock_irqrestore(&edmac->lock, flags);
 
-	ret = dma_async_is_complete(cookie, last_completed, last_used);
-	dma_set_tx_state(state, last_completed, last_used, 0);
-
 	return ret;
 }
 
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index f36e8b1..2f6c806 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -978,19 +978,14 @@ static enum dma_status fsl_tx_status(struct dma_chan *dchan,
 					struct dma_tx_state *txstate)
 {
 	struct fsldma_chan *chan = to_fsl_chan(dchan);
-	dma_cookie_t last_complete;
-	dma_cookie_t last_used;
+	enum dma_status ret;
 	unsigned long flags;
 
 	spin_lock_irqsave(&chan->desc_lock, flags);
-
-	last_complete = dchan->completed_cookie;
-	last_used = dchan->cookie;
-
+	ret = dma_cookie_status(dchan, cookie, txstate);
 	spin_unlock_irqrestore(&chan->desc_lock, flags);
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return ret;
 }
 
 /*----------------------------------------------------------------------------*/
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index f1226ad..ba317e6 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -153,16 +153,7 @@ static enum dma_status imxdma_tx_status(struct dma_chan *chan,
 					    dma_cookie_t cookie,
 					    struct dma_tx_state *txstate)
 {
-	struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
-	dma_cookie_t last_used;
-	enum dma_status ret;
-
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, chan->completed_cookie, last_used);
-	dma_set_tx_state(txstate, chan->completed_cookie, last_used, 0);
-
-	return ret;
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx)
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 340509e..69ed1e6 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -477,30 +477,17 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 						dma_cookie_t cookie,
 						struct dma_tx_state *txstate)
 {
-	dma_cookie_t		last_used;
-	dma_cookie_t		last_complete;
-	int				ret;
+	enum dma_status ret;
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		spin_lock_bh(&midc->lock);
 		midc_scan_descriptors(to_middma_device(chan->device), midc);
 		spin_unlock_bh(&midc->lock);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
-	if (txstate) {
-		txstate->last = last_complete;
-		txstate->used = last_used;
-		txstate->residue = 0;
-	}
 	return ret;
 }
 
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index b0517c8..97e100c 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -729,13 +729,15 @@ ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
 {
 	struct ioat_chan_common *chan = to_chan_common(c);
 	struct ioatdma_device *device = chan->device;
+	enum dma_status ret;
 
-	if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS)
-		return DMA_SUCCESS;
+	ret = dma_cookie_status(c, cookie, txstate);
+	if (ret == DMA_SUCCESS)
+		return ret;
 
 	device->cleanup_fn((unsigned long) c);
 
-	return ioat_tx_status(c, cookie, txstate);
+	return dma_cookie_status(c, cookie, txstate);
 }
 
 static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat)
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index 9653b6b..c7888bc 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -142,27 +142,6 @@ static inline struct ioat_dma_chan *to_ioat_chan(struct dma_chan *c)
 	return container_of(chan, struct ioat_dma_chan, base);
 }
 
-/**
- * ioat_tx_status - poll the status of an ioat transaction
- * @c: channel handle
- * @cookie: transaction identifier
- * @txstate: if set, updated with the transaction state
- */
-static inline enum dma_status
-ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie,
-		 struct dma_tx_state *txstate)
-{
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-
-	last_used = c->cookie;
-	last_complete = c->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	return dma_async_is_complete(cookie, last_complete, last_used);
-}
-
 /* wrapper around hardware descriptor format + additional software fields */
 
 /**
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 1bda46c..145eda2 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -410,13 +410,15 @@ ioat3_tx_status(struct dma_chan *c, dma_cookie_t cookie,
 		struct dma_tx_state *txstate)
 {
 	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
+	enum dma_status ret;
 
-	if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS)
-		return DMA_SUCCESS;
+	ret = dma_cookie_status(c, cookie, txstate);
+	if (ret == DMA_SUCCESS)
+		return ret;
 
 	ioat3_cleanup(ioat);
 
-	return ioat_tx_status(c, cookie, txstate);
+	return dma_cookie_status(c, cookie, txstate);
 }
 
 static struct dma_async_tx_descriptor *
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index f2392d5..b1e3be08 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -894,24 +894,14 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 					struct dma_tx_state *txstate)
 {
 	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	enum dma_status ret;
-
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS)
 		return ret;
 
 	iop_adma_slot_cleanup(iop_chan);
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static irqreturn_t iop_adma_eot_handler(int irq, void *data)
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 0253d5a..1382715 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -557,17 +557,14 @@ mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	       struct dma_tx_state *txstate)
 {
 	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+	enum dma_status ret;
 	unsigned long flags;
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 
 	spin_lock_irqsave(&mchan->lock, flags);
-	last_used = mchan->chan.cookie;
-	last_complete = mchan->chan.completed_cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
 	spin_unlock_irqrestore(&mchan->lock, flags);
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return ret;
 }
 
 /* Prepare descriptor for memory to memory copy */
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index d9810ce..486353e 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -810,26 +810,16 @@ static enum dma_status mv_xor_status(struct dma_chan *chan,
 					  struct dma_tx_state *txstate)
 {
 	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status ret;
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS) {
 		mv_xor_clean_completed_slots(mv_chan);
 		return ret;
 	}
 	mv_xor_slot_cleanup(mv_chan);
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static void mv_dump_xor_regs(struct mv_xor_chan *chan)
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 5218e48..c30f63e 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -565,19 +565,12 @@ static enum dma_status pd_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 				    struct dma_tx_state *txstate)
 {
 	struct pch_dma_chan *pd_chan = to_pd_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_completed;
-	int ret;
+	enum dma_status ret;
 
 	spin_lock_irq(&pd_chan->lock);
-	last_completed = chan->completed_cookie;
-	last_used = chan->cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
 	spin_unlock_irq(&pd_chan->lock);
 
-	ret = dma_async_is_complete(cookie, last_completed, last_used);
-
-	dma_set_tx_state(txstate, last_completed, last_used, 0);
-
 	return ret;
 }
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 76871b8..1993286 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -395,18 +395,7 @@ static enum dma_status
 pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		 struct dma_tx_state *txstate)
 {
-	struct dma_pl330_chan *pch = to_pchan(chan);
-	dma_cookie_t last_done, last_used;
-	int ret;
-
-	last_done = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_done, last_used);
-
-	dma_set_tx_state(txstate, last_done, last_used, 0);
-
-	return ret;
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static void pl330_issue_pending(struct dma_chan *chan)
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 12e94dd..86239ea 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -3928,28 +3928,16 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan,
 			dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
 	struct ppc440spe_adma_chan *ppc440spe_chan;
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status ret;
 
 	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS)
 		return ret;
 
 	ppc440spe_adma_slot_cleanup(ppc440spe_chan);
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 /**
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 96d0a4f..50510ef 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -879,23 +879,14 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
 					struct dma_tx_state *txstate)
 {
 	struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status status;
 	unsigned long flags;
 
 	sh_dmae_chan_ld_cleanup(sh_chan, false);
 
-	/* First read completed cookie to avoid a skew */
-	last_complete = chan->completed_cookie;
-	rmb();
-	last_used = chan->cookie;
-	BUG_ON(last_complete < 0);
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
 	spin_lock_irqsave(&sh_chan->desc_lock, flags);
 
-	status = dma_async_is_complete(cookie, last_complete, last_used);
+	status = dma_cookie_status(chan, cookie, txstate);
 
 	/*
 	 * If we don't find cookie on the queue, it has been aborted and we have
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 7bb154a..a760d98 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -407,16 +407,13 @@ sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 {
 	struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
 	unsigned long flags;
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
+	enum dma_status ret;
 
 	spin_lock_irqsave(&schan->lock, flags);
-	last_used = schan->chan.cookie;
-	last_complete = schan->chan.completed_cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
 	spin_unlock_irqrestore(&schan->lock, flags);
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return ret;
 }
 
 static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved(
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index c246375..07b82e3 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2332,25 +2332,19 @@ static enum dma_status d40_tx_status(struct dma_chan *chan,
 				     struct dma_tx_state *txstate)
 {
 	struct d40_chan *d40c = container_of(chan, struct d40_chan, chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	int ret;
+	enum dma_status ret;
 
 	if (d40c->phy_chan == NULL) {
 		chan_err(d40c, "Cannot read status of unallocated channel\n");
 		return -EINVAL;
 	}
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret != DMA_SUCCESS)
+		dma_set_residue(txstate, stedma40_residue(chan));
 
 	if (d40_is_paused(d40c))
 		ret = DMA_PAUSED;
-	else
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
-
-	dma_set_tx_state(txstate, last_complete, last_used,
-			 stedma40_residue(chan));
 
 	return ret;
 }
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 1845ac9..6383abb 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -513,18 +513,11 @@ static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 {
 	struct timb_dma_chan *td_chan =
 		container_of(chan, struct timb_dma_chan, chan);
-	dma_cookie_t		last_used;
-	dma_cookie_t		last_complete;
-	int			ret;
+	enum dma_status ret;
 
 	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
+	ret = dma_cookie_status(chan, cookie, txstate);
 
 	dev_dbg(chan2dev(chan),
 		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 8a5225b..bb7b3d9 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -959,27 +959,17 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		   struct dma_tx_state *txstate)
 {
 	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	int ret;
+	enum dma_status ret;
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		spin_lock_bh(&dc->lock);
 		txx9dmac_scan_descriptors(dc);
 		spin_unlock_bh(&dc->lock);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
 	return ret;
 }
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 6/9] dmaengine: consolidate tx_status functions
@ 2012-03-06 22:35   ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:35 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have the completed cookie in the dma_chan structure, we
can consolidate the tx_status functions by providing a function to set
the txstate structure and returning the DMA status.  We also provide
a separate helper to set the residue for cookies which are still in
progress.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |   22 ++++------------------
 drivers/dma/at_hdmac.c      |   18 ++++++------------
 drivers/dma/coh901318.c     |   13 ++++---------
 drivers/dma/dmaengine.h     |   31 +++++++++++++++++++++++++++++++
 drivers/dma/dw_dmac.c       |   19 ++++---------------
 drivers/dma/ep93xx_dma.c    |    7 +------
 drivers/dma/fsldma.c        |   11 +++--------
 drivers/dma/imx-dma.c       |   11 +----------
 drivers/dma/intel_mid_dma.c |   19 +++----------------
 drivers/dma/ioat/dma.c      |    8 +++++---
 drivers/dma/ioat/dma.h      |   21 ---------------------
 drivers/dma/ioat/dma_v3.c   |    8 +++++---
 drivers/dma/iop-adma.c      |   16 +++-------------
 drivers/dma/mpc512x_dma.c   |    9 +++------
 drivers/dma/mv_xor.c        |   14 ++------------
 drivers/dma/pch_dma.c       |   11 ++---------
 drivers/dma/pl330.c         |   13 +------------
 drivers/dma/ppc4xx/adma.c   |   16 ++--------------
 drivers/dma/shdma.c         |   11 +----------
 drivers/dma/sirf-dma.c      |    9 +++------
 drivers/dma/ste_dma40.c     |   14 ++++----------
 drivers/dma/timb_dma.c      |   11 ++---------
 drivers/dma/txx9dmac.c      |   16 +++-------------
 23 files changed, 93 insertions(+), 235 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index f0888c1..2781a2b 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -964,31 +964,17 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
 		dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
 	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status ret;
-	u32 bytesleft = 0;
 
-	last_used = plchan->chan.cookie;
-	last_complete = plchan->chan.completed_cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
-	if (ret == DMA_SUCCESS) {
-		dma_set_tx_state(txstate, last_complete, last_used, 0);
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_SUCCESS)
 		return ret;
-	}
 
 	/*
 	 * This cookie not complete yet
+	 * Get number of bytes left in the active transactions and queue
 	 */
-	last_used = plchan->chan.cookie;
-	last_complete = plchan->chan.completed_cookie;
-
-	/* Get number of bytes left in the active transactions and queue */
-	bytesleft = pl08x_getbytes_chan(plchan);
-
-	dma_set_tx_state(txstate, last_complete, last_used,
-			 bytesleft);
+	dma_set_residue(txstate, pl08x_getbytes_chan(plchan));
 
 	if (plchan->state == PL08X_CHAN_PAUSED)
 		return DMA_PAUSED;
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index b282630..8a32974 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -996,26 +996,20 @@ atc_tx_status(struct dma_chan *chan,
 
 	spin_lock_irqsave(&atchan->lock, flags);
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		atc_cleanup_descriptors(atchan);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
+	last_complete = chan->completed_cookie;
+	last_used = chan->cookie;
+
 	spin_unlock_irqrestore(&atchan->lock, flags);
 
 	if (ret != DMA_SUCCESS)
-		dma_set_tx_state(txstate, last_complete, last_used,
-			atc_first_active(atchan)->len);
-	else
-		dma_set_tx_state(txstate, last_complete, last_used, 0);
+		dma_set_residue(txstate, atc_first_active(atchan)->len);
 
 	if (atc_chan_is_paused(atchan))
 		ret = DMA_PAUSED;
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 24837d7..f350517 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -1151,17 +1151,12 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		 struct dma_tx_state *txstate)
 {
 	struct coh901318_chan *cohc = to_coh901318_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	int ret;
-
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
+	enum dma_status ret;
 
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
+	/* FIXME: should be conditional on ret != DMA_SUCCESS? */
+	dma_set_residue(txstate, coh901318_get_bytes_left(chan));
 
-	dma_set_tx_state(txstate, last_complete, last_used,
-			 coh901318_get_bytes_left(chan));
 	if (ret == DMA_IN_PROGRESS && cohc->stopped)
 		ret = DMA_PAUSED;
 
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 47e0997..1ca5e0e 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -45,4 +45,35 @@ static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
 	tx->cookie = 0;
 }
 
+/**
+ * dma_cookie_status - report cookie status
+ * @chan: dma channel
+ * @cookie: cookie we are interested in
+ * @state: dma_tx_state structure to return last/used cookies
+ *
+ * Report the status of the cookie, filling in the state structure if
+ * non-NULL.  No locking is required.
+ */
+static inline enum dma_status dma_cookie_status(struct dma_chan *chan,
+	dma_cookie_t cookie, struct dma_tx_state *state)
+{
+	dma_cookie_t used, complete;
+
+	used = chan->cookie;
+	complete = chan->completed_cookie;
+	barrier();
+	if (state) {
+		state->last = complete;
+		state->used = used;
+		state->residue = 0;
+	}
+	return dma_async_is_complete(cookie, complete, used);
+}
+
+static inline void dma_set_residue(struct dma_tx_state *state, u32 residue)
+{
+	if (state)
+		state->residue = residue;
+}
+
 #endif
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index a190c88..acc3bc0 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -937,28 +937,17 @@ dwc_tx_status(struct dma_chan *chan,
 	      struct dma_tx_state *txstate)
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	dma_cookie_t		last_used;
-	dma_cookie_t		last_complete;
-	int			ret;
+	enum dma_status		ret;
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
 	if (ret != DMA_SUCCESS)
-		dma_set_tx_state(txstate, last_complete, last_used,
-				dwc_first_active(dwc)->len);
-	else
-		dma_set_tx_state(txstate, last_complete, last_used, 0);
+		dma_set_residue(txstate, dwc_first_active(dwc)->len);
 
 	if (dwc->paused)
 		return DMA_PAUSED;
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 1c56f75..142ebf0 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -1241,18 +1241,13 @@ static enum dma_status ep93xx_dma_tx_status(struct dma_chan *chan,
 					    struct dma_tx_state *state)
 {
 	struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
-	dma_cookie_t last_used, last_completed;
 	enum dma_status ret;
 	unsigned long flags;
 
 	spin_lock_irqsave(&edmac->lock, flags);
-	last_used = chan->cookie;
-	last_completed = chan->completed_cookie;
+	ret = dma_cookie_status(chan, cookie, state);
 	spin_unlock_irqrestore(&edmac->lock, flags);
 
-	ret = dma_async_is_complete(cookie, last_completed, last_used);
-	dma_set_tx_state(state, last_completed, last_used, 0);
-
 	return ret;
 }
 
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index f36e8b1..2f6c806 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -978,19 +978,14 @@ static enum dma_status fsl_tx_status(struct dma_chan *dchan,
 					struct dma_tx_state *txstate)
 {
 	struct fsldma_chan *chan = to_fsl_chan(dchan);
-	dma_cookie_t last_complete;
-	dma_cookie_t last_used;
+	enum dma_status ret;
 	unsigned long flags;
 
 	spin_lock_irqsave(&chan->desc_lock, flags);
-
-	last_complete = dchan->completed_cookie;
-	last_used = dchan->cookie;
-
+	ret = dma_cookie_status(dchan, cookie, txstate);
 	spin_unlock_irqrestore(&chan->desc_lock, flags);
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return ret;
 }
 
 /*----------------------------------------------------------------------------*/
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index f1226ad..ba317e6 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -153,16 +153,7 @@ static enum dma_status imxdma_tx_status(struct dma_chan *chan,
 					    dma_cookie_t cookie,
 					    struct dma_tx_state *txstate)
 {
-	struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
-	dma_cookie_t last_used;
-	enum dma_status ret;
-
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, chan->completed_cookie, last_used);
-	dma_set_tx_state(txstate, chan->completed_cookie, last_used, 0);
-
-	return ret;
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx)
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 340509e..69ed1e6 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -477,30 +477,17 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 						dma_cookie_t cookie,
 						struct dma_tx_state *txstate)
 {
-	dma_cookie_t		last_used;
-	dma_cookie_t		last_complete;
-	int				ret;
+	enum dma_status ret;
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		spin_lock_bh(&midc->lock);
 		midc_scan_descriptors(to_middma_device(chan->device), midc);
 		spin_unlock_bh(&midc->lock);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
-	if (txstate) {
-		txstate->last = last_complete;
-		txstate->used = last_used;
-		txstate->residue = 0;
-	}
 	return ret;
 }
 
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index b0517c8..97e100c 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -729,13 +729,15 @@ ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
 {
 	struct ioat_chan_common *chan = to_chan_common(c);
 	struct ioatdma_device *device = chan->device;
+	enum dma_status ret;
 
-	if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS)
-		return DMA_SUCCESS;
+	ret = dma_cookie_status(c, cookie, txstate);
+	if (ret == DMA_SUCCESS)
+		return ret;
 
 	device->cleanup_fn((unsigned long) c);
 
-	return ioat_tx_status(c, cookie, txstate);
+	return dma_cookie_status(c, cookie, txstate);
 }
 
 static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat)
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index 9653b6b..c7888bc 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -142,27 +142,6 @@ static inline struct ioat_dma_chan *to_ioat_chan(struct dma_chan *c)
 	return container_of(chan, struct ioat_dma_chan, base);
 }
 
-/**
- * ioat_tx_status - poll the status of an ioat transaction
- * @c: channel handle
- * @cookie: transaction identifier
- * @txstate: if set, updated with the transaction state
- */
-static inline enum dma_status
-ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie,
-		 struct dma_tx_state *txstate)
-{
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-
-	last_used = c->cookie;
-	last_complete = c->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	return dma_async_is_complete(cookie, last_complete, last_used);
-}
-
 /* wrapper around hardware descriptor format + additional software fields */
 
 /**
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 1bda46c..145eda2 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -410,13 +410,15 @@ ioat3_tx_status(struct dma_chan *c, dma_cookie_t cookie,
 		struct dma_tx_state *txstate)
 {
 	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
+	enum dma_status ret;
 
-	if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS)
-		return DMA_SUCCESS;
+	ret = dma_cookie_status(c, cookie, txstate);
+	if (ret == DMA_SUCCESS)
+		return ret;
 
 	ioat3_cleanup(ioat);
 
-	return ioat_tx_status(c, cookie, txstate);
+	return dma_cookie_status(c, cookie, txstate);
 }
 
 static struct dma_async_tx_descriptor *
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index f2392d5..b1e3be08 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -894,24 +894,14 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 					struct dma_tx_state *txstate)
 {
 	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	enum dma_status ret;
-
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS)
 		return ret;
 
 	iop_adma_slot_cleanup(iop_chan);
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static irqreturn_t iop_adma_eot_handler(int irq, void *data)
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 0253d5a..1382715 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -557,17 +557,14 @@ mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	       struct dma_tx_state *txstate)
 {
 	struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+	enum dma_status ret;
 	unsigned long flags;
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 
 	spin_lock_irqsave(&mchan->lock, flags);
-	last_used = mchan->chan.cookie;
-	last_complete = mchan->chan.completed_cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
 	spin_unlock_irqrestore(&mchan->lock, flags);
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return ret;
 }
 
 /* Prepare descriptor for memory to memory copy */
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index d9810ce..486353e 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -810,26 +810,16 @@ static enum dma_status mv_xor_status(struct dma_chan *chan,
 					  struct dma_tx_state *txstate)
 {
 	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status ret;
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS) {
 		mv_xor_clean_completed_slots(mv_chan);
 		return ret;
 	}
 	mv_xor_slot_cleanup(mv_chan);
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static void mv_dump_xor_regs(struct mv_xor_chan *chan)
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 5218e48..c30f63e 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -565,19 +565,12 @@ static enum dma_status pd_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 				    struct dma_tx_state *txstate)
 {
 	struct pch_dma_chan *pd_chan = to_pd_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_completed;
-	int ret;
+	enum dma_status ret;
 
 	spin_lock_irq(&pd_chan->lock);
-	last_completed = chan->completed_cookie;
-	last_used = chan->cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
 	spin_unlock_irq(&pd_chan->lock);
 
-	ret = dma_async_is_complete(cookie, last_completed, last_used);
-
-	dma_set_tx_state(txstate, last_completed, last_used, 0);
-
 	return ret;
 }
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 76871b8..1993286 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -395,18 +395,7 @@ static enum dma_status
 pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		 struct dma_tx_state *txstate)
 {
-	struct dma_pl330_chan *pch = to_pchan(chan);
-	dma_cookie_t last_done, last_used;
-	int ret;
-
-	last_done = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_done, last_used);
-
-	dma_set_tx_state(txstate, last_done, last_used, 0);
-
-	return ret;
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 static void pl330_issue_pending(struct dma_chan *chan)
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 12e94dd..86239ea 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -3928,28 +3928,16 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan,
 			dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
 	struct ppc440spe_adma_chan *ppc440spe_chan;
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status ret;
 
 	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS)
 		return ret;
 
 	ppc440spe_adma_slot_cleanup(ppc440spe_chan);
 
-	last_used = chan->cookie;
-	last_complete = chan->completed_cookie;
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return dma_cookie_status(chan, cookie, txstate);
 }
 
 /**
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 96d0a4f..50510ef 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -879,23 +879,14 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
 					struct dma_tx_state *txstate)
 {
 	struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
 	enum dma_status status;
 	unsigned long flags;
 
 	sh_dmae_chan_ld_cleanup(sh_chan, false);
 
-	/* First read completed cookie to avoid a skew */
-	last_complete = chan->completed_cookie;
-	rmb();
-	last_used = chan->cookie;
-	BUG_ON(last_complete < 0);
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
 	spin_lock_irqsave(&sh_chan->desc_lock, flags);
 
-	status = dma_async_is_complete(cookie, last_complete, last_used);
+	status = dma_cookie_status(chan, cookie, txstate);
 
 	/*
 	 * If we don't find cookie on the queue, it has been aborted and we have
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 7bb154a..a760d98 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -407,16 +407,13 @@ sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 {
 	struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
 	unsigned long flags;
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
+	enum dma_status ret;
 
 	spin_lock_irqsave(&schan->lock, flags);
-	last_used = schan->chan.cookie;
-	last_complete = schan->chan.completed_cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
 	spin_unlock_irqrestore(&schan->lock, flags);
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	return dma_async_is_complete(cookie, last_complete, last_used);
+	return ret;
 }
 
 static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved(
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index c246375..07b82e3 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2332,25 +2332,19 @@ static enum dma_status d40_tx_status(struct dma_chan *chan,
 				     struct dma_tx_state *txstate)
 {
 	struct d40_chan *d40c = container_of(chan, struct d40_chan, chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	int ret;
+	enum dma_status ret;
 
 	if (d40c->phy_chan == NULL) {
 		chan_err(d40c, "Cannot read status of unallocated channel\n");
 		return -EINVAL;
 	}
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret != DMA_SUCCESS)
+		dma_set_residue(txstate, stedma40_residue(chan));
 
 	if (d40_is_paused(d40c))
 		ret = DMA_PAUSED;
-	else
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
-
-	dma_set_tx_state(txstate, last_complete, last_used,
-			 stedma40_residue(chan));
 
 	return ret;
 }
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 1845ac9..6383abb 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -513,18 +513,11 @@ static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 {
 	struct timb_dma_chan *td_chan =
 		container_of(chan, struct timb_dma_chan, chan);
-	dma_cookie_t		last_used;
-	dma_cookie_t		last_complete;
-	int			ret;
+	enum dma_status ret;
 
 	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
-
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
+	ret = dma_cookie_status(chan, cookie, txstate);
 
 	dev_dbg(chan2dev(chan),
 		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 8a5225b..bb7b3d9 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -959,27 +959,17 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 		   struct dma_tx_state *txstate)
 {
 	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
-	dma_cookie_t last_used;
-	dma_cookie_t last_complete;
-	int ret;
+	enum dma_status ret;
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
-
-	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret != DMA_SUCCESS) {
 		spin_lock_bh(&dc->lock);
 		txx9dmac_scan_descriptors(dc);
 		spin_unlock_bh(&dc->lock);
 
-		last_complete = chan->completed_cookie;
-		last_used = chan->cookie;
-
-		ret = dma_async_is_complete(cookie, last_complete, last_used);
+		ret = dma_cookie_status(chan, cookie, txstate);
 	}
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-
 	return ret;
 }
 
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 7/9] dmaengine: consolidate initialization of cookies
  2012-03-06 22:33 ` Russell King - ARM Linux
                   ` (6 preceding siblings ...)
  (?)
@ 2012-03-06 22:35 ` Russell King - ARM Linux
  2012-03-07  1:07   ` H Hartley Sweeten
  -1 siblings, 1 reply; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:35 UTC (permalink / raw)
  To: linux-arm-kernel

Provide a common function to initialize a channels cookie values.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/amba-pl08x.c    |    3 +--
 drivers/dma/at_hdmac.c      |    4 ++--
 drivers/dma/coh901318.c     |    2 +-
 drivers/dma/dmaengine.h     |   10 ++++++++++
 drivers/dma/dw_dmac.c       |    4 ++--
 drivers/dma/ep93xx_dma.c    |    3 +--
 drivers/dma/intel_mid_dma.c |    4 ++--
 drivers/dma/ipu/ipu_idmac.c |    6 ++----
 drivers/dma/mpc512x_dma.c   |    3 +--
 drivers/dma/pch_dma.c       |    4 ++--
 drivers/dma/pl330.c         |    2 +-
 drivers/dma/sirf-dma.c      |    3 +--
 drivers/dma/ste_dma40.c     |    2 +-
 drivers/dma/timb_dma.c      |    5 ++---
 drivers/dma/txx9dmac.c      |    4 ++--
 15 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 2781a2b..13c4d08 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1707,8 +1707,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
 			 chan->name);
 
 		chan->chan.device = dmadev;
-		chan->chan.cookie = 0;
-		chan->chan.completed_cookie = 0;
+		dma_cookie_init(&chan->chan);
 
 		spin_lock_init(&chan->lock);
 		INIT_LIST_HEAD(&chan->pend_list);
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 8a32974..5d225dd 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1103,7 +1103,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
 	spin_lock_irqsave(&atchan->lock, flags);
 	atchan->descs_allocated = i;
 	list_splice(&tmp_list, &atchan->free_list);
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 	spin_unlock_irqrestore(&atchan->lock, flags);
 
 	/* channel parameters */
@@ -1303,7 +1303,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
 		struct at_dma_chan	*atchan = &atdma->chan[i];
 
 		atchan->chan_common.device = &atdma->dma_common;
-		atchan->chan_common.cookie = atchan->chan_common.completed_cookie = 1;
+		dma_cookie_init(&atchan->chan_common);
 		list_add_tail(&atchan->chan_common.device_node,
 				&atdma->dma_common.channels);
 
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index f350517..187bb9e 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -915,7 +915,7 @@ static int coh901318_alloc_chan_resources(struct dma_chan *chan)
 	coh901318_config(cohc, NULL);
 
 	cohc->allocated = 1;
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 
 	spin_unlock_irqrestore(&cohc->lock, flags);
 
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
index 1ca5e0e..17f983a 100644
--- a/drivers/dma/dmaengine.h
+++ b/drivers/dma/dmaengine.h
@@ -9,6 +9,16 @@
 #include <linux/dmaengine.h>
 
 /**
+ * dma_cookie_init - initialize the cookies for a DMA channel
+ * @chan: dma channel to initialize
+ */
+static inline void dma_cookie_init(struct dma_chan *chan)
+{
+	chan->cookie = DMA_MIN_COOKIE;
+	chan->completed_cookie = DMA_MIN_COOKIE;
+}
+
+/**
  * dma_cookie_assign - assign a DMA engine cookie to the descriptor
  * @tx: descriptor needing cookie
  *
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index acc3bc0..8b4be42 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -979,7 +979,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
 		return -EIO;
 	}
 
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 
 	/*
 	 * NOTE: some controllers may have additional features that we
@@ -1398,7 +1398,7 @@ static int __init dw_probe(struct platform_device *pdev)
 		struct dw_dma_chan	*dwc = &dw->chan[i];
 
 		dwc->chan.device = &dw->dma;
-		dwc->chan.cookie = dwc->chan.completed_cookie = 1;
+		dma_cookie_init(&dwc->chan);
 		if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
 			list_add_tail(&dwc->chan.device_node,
 					&dw->dma.channels);
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 142ebf0..f25e83b 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -854,8 +854,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
 		goto fail_clk_disable;
 
 	spin_lock_irq(&edmac->lock);
-	edmac->chan.completed_cookie = 1;
-	edmac->chan.cookie = 1;
+	dma_cookie_init(&edmac->chan);
 	ret = edmac->edma->hw_setup(edmac);
 	spin_unlock_irq(&edmac->lock);
 
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 69ed1e6..9d82a84 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -867,7 +867,7 @@ static int intel_mid_dma_alloc_chan_resources(struct dma_chan *chan)
 		pm_runtime_put(&mid->pdev->dev);
 		return -EIO;
 	}
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 
 	spin_lock_bh(&midc->lock);
 	while (midc->descs_allocated < DESCS_PER_CHANNEL) {
@@ -1099,7 +1099,7 @@ static int mid_setup_dma(struct pci_dev *pdev)
 		struct intel_mid_dma_chan *midch = &dma->ch[i];
 
 		midch->chan.device = &dma->common;
-		midch->chan.cookie =  1;
+		dma_cookie_init(&midch->chan);
 		midch->ch_id = dma->chan_base + i;
 		pr_debug("MDMA:Init CH %d, ID %d\n", i, midch->ch_id);
 
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index bff9250..1880274 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1504,8 +1504,7 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
 	BUG_ON(chan->client_count > 1);
 	WARN_ON(ichan->status != IPU_CHANNEL_FREE);
 
-	chan->cookie		= 1;
-	chan->completed_cookie	= -ENXIO;
+	dma_cookie_init(chan);
 
 	ret = ipu_irq_map(chan->chan_id);
 	if (ret < 0)
@@ -1633,8 +1632,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
 		snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i);
 
 		dma_chan->device	= &idmac->dma;
-		dma_chan->cookie	= 1;
-		dma_chan->completed_cookie	= -ENXIO;
+		dma_cookie_init(dma_chan);
 		dma_chan->chan_id	= i;
 		list_add_tail(&dma_chan->device_node, &dma->channels);
 	}
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 1382715..2ab0a3d 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -733,8 +733,7 @@ static int __devinit mpc_dma_probe(struct platform_device *op)
 		mchan = &mdma->channels[i];
 
 		mchan->chan.device = dma;
-		mchan->chan.cookie = 1;
-		mchan->chan.completed_cookie = mchan->chan.cookie;
+		dma_cookie_init(&mchan->chan);
 
 		INIT_LIST_HEAD(&mchan->free);
 		INIT_LIST_HEAD(&mchan->prepared);
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index c30f63e..c93bb045 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -531,7 +531,7 @@ static int pd_alloc_chan_resources(struct dma_chan *chan)
 	spin_lock_irq(&pd_chan->lock);
 	list_splice(&tmp_list, &pd_chan->free_list);
 	pd_chan->descs_allocated = i;
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 	spin_unlock_irq(&pd_chan->lock);
 
 	pdc_enable_irq(chan, 1);
@@ -912,7 +912,7 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev,
 		struct pch_dma_chan *pd_chan = &pd->channels[i];
 
 		pd_chan->chan.device = &pd->dma;
-		pd_chan->chan.cookie = 1;
+		dma_cookie_init(&pd_chan->chan);
 
 		pd_chan->membase = &regs->desc[i];
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 1993286..49c123f 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -304,7 +304,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
 
 	spin_lock_irqsave(&pch->lock, flags);
 
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 	pch->cyclic = false;
 
 	pch->pl330_chid = pl330_request_channel(&pdmac->pif);
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index a760d98..a2cde85 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -625,8 +625,7 @@ static int __devinit sirfsoc_dma_probe(struct platform_device *op)
 		schan = &sdma->channels[i];
 
 		schan->chan.device = dma;
-		schan->chan.cookie = 1;
-		schan->chan.completed_cookie = schan->chan.cookie;
+		dma_cookie_init(&schan->chan);
 
 		INIT_LIST_HEAD(&schan->free);
 		INIT_LIST_HEAD(&schan->prepared);
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 07b82e3..1ea6d02 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2172,7 +2172,7 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
 	bool is_free_phy;
 	spin_lock_irqsave(&d40c->lock, flags);
 
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 
 	/* If no dma configuration is set use default configuration (memcpy) */
 	if (!d40c->configured) {
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 6383abb..7805996 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -477,8 +477,7 @@ static int td_alloc_chan_resources(struct dma_chan *chan)
 	}
 
 	spin_lock_bh(&td_chan->lock);
-	chan->completed_cookie = 1;
-	chan->cookie = 1;
+	dma_cookie_init(chan);
 	spin_unlock_bh(&td_chan->lock);
 
 	return 0;
@@ -755,7 +754,7 @@ static int __devinit td_probe(struct platform_device *pdev)
 		}
 
 		td_chan->chan.device = &td->dma;
-		td_chan->chan.cookie = 1;
+		dma_cookie_init(&td_chan->chan);
 		spin_lock_init(&td_chan->lock);
 		INIT_LIST_HEAD(&td_chan->active_list);
 		INIT_LIST_HEAD(&td_chan->queue);
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index bb7b3d9..40440f9 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -1034,7 +1034,7 @@ static int txx9dmac_alloc_chan_resources(struct dma_chan *chan)
 		return -EIO;
 	}
 
-	chan->completed_cookie = chan->cookie = 1;
+	dma_cookie_init(chan);
 
 	dc->ccr = TXX9_DMA_CCR_IMMCHN | TXX9_DMA_CCR_INTENE | CCR_LE;
 	txx9dmac_chan_set_SMPCHN(dc);
@@ -1163,7 +1163,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev)
 	dc->ddev->chan[ch] = dc;
 	dc->chan.device = &dc->dma;
 	list_add_tail(&dc->chan.device_node, &dc->chan.device->channels);
-	dc->chan.cookie = dc->chan.completed_cookie = 1;
+	dma_cookie_init(&dc->chan);
 
 	if (is_dmac64(dc))
 		dc->ch_regs = &__txx9dmac_regs(dc->ddev)->CHAN[ch];
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 8/9] dmaengine: fix cookie handling in iop-adma.c and ppc4xx/adma.c
  2012-03-06 22:33 ` Russell King - ARM Linux
                   ` (7 preceding siblings ...)
  (?)
@ 2012-03-06 22:36 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:36 UTC (permalink / raw)
  To: linux-arm-kernel

Dan Williams said:
> > Russell King wrote:
> > Firstly, we have DMA_MIN_COOKIE which has value 1 - so any cookies below
> > that aren't valid. ?That seems sane.
> >
> > We seem to have different behaviours:
> >
> > - ? ? ? cookie = c->cookie;
> > - ? ? ? cookie++;
> > - ? ? ? if (cookie < 0)
> > - ? ? ? ? ? ? ? cookie = 1;
> > - ? ? ? c->cookie = cookie;
> > - ? ? ? tx->cookie = cookie;
> >
> > c->cookie here is initialized to zero, so the first cookie given out will
> > be 1. ?This is how most DMA engine drivers implement this.
> >
> > Then we have this:
> >
> > ? ? ? ? ? ? ? ?cookie = chan->common.cookie;
> > ? ? ? ? ? ? ? ?cookie++;
> > ? ? ? ? ? ? ? ?if (cookie <= 1)
> > ? ? ? ? ? ? ? ? ? ? ? ?cookie = 2;
> >
> > ? ? ? ? ? ? ? ?/* initialize the completed cookie to be less than
> > ? ? ? ? ? ? ? ? * the most recently used cookie
> > ? ? ? ? ? ? ? ? */
> > ? ? ? ? ? ? ? ?chan->common.completed_cookie = cookie - 1;
> > ? ? ? ? ? ? ? ?chan->common.cookie = sw_desc->async_tx.cookie = cookie;
> >
> > Again, chan->common.cookie starts off at 0. ?The first cookie given out
> > will be 2, and 1 will never be used. ?There are three drivers which
> > implement it this way.
> >
> > Why is there this difference, and can these three be corrected to behave
> > the same way as the first (and therefore the assignment of cookies
> > consolidated?)
>
> Yes, they should be consolidated, and I believe they have drifted only
> because there were no good common helpers and murphy's law took over.

So lets fix this up to use the common dma_cookie_assign() helper.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/iop-adma.c    |   12 ++----------
 drivers/dma/ppc4xx/adma.c |    6 +-----
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index b1e3be08..4370b10 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -1622,16 +1622,12 @@ static void iop_chan_start_null_memcpy(struct iop_adma_chan *iop_chan)
 		iop_desc_set_dest_addr(grp_start, iop_chan, 0);
 		iop_desc_set_memcpy_src_addr(grp_start, 0);
 
-		cookie = iop_chan->common.cookie;
-		cookie++;
-		if (cookie <= 1)
-			cookie = 2;
+		cookie = dma_cookie_assign(&sw_desc->async_tx);
 
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
 		iop_chan->common.completed_cookie = cookie - 1;
-		iop_chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
 		BUG_ON(iop_chan_is_busy(iop_chan));
@@ -1679,16 +1675,12 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan)
 		iop_desc_set_xor_src_addr(grp_start, 0, 0);
 		iop_desc_set_xor_src_addr(grp_start, 1, 0);
 
-		cookie = iop_chan->common.cookie;
-		cookie++;
-		if (cookie <= 1)
-			cookie = 2;
+		cookie = dma_cookie_assign(&sw_desc->async_tx);
 
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
 		iop_chan->common.completed_cookie = cookie - 1;
-		iop_chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
 		BUG_ON(iop_chan_is_busy(iop_chan));
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 86239ea..9752062 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -4022,16 +4022,12 @@ static void ppc440spe_chan_start_null_xor(struct ppc440spe_adma_chan *chan)
 		async_tx_ack(&sw_desc->async_tx);
 		ppc440spe_desc_init_null_xor(group_start);
 
-		cookie = chan->common.cookie;
-		cookie++;
-		if (cookie <= 1)
-			cookie = 2;
+		cookie = dma_cookie_assign(&sw_desc->async_tx);
 
 		/* initialize the completed cookie to be less than
 		 * the most recently used cookie
 		 */
 		chan->common.completed_cookie = cookie - 1;
-		chan->common.cookie = sw_desc->async_tx.cookie = cookie;
 
 		/* channel should not be busy */
 		BUG_ON(ppc440spe_chan_is_busy(chan));
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 9/9] dmaengine: ensure all DMA engine drivers initialize their cookies
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-06 22:36   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:36 UTC (permalink / raw)
  To: Dan Williams, Vinod Koul; +Cc: linuxppc-dev, Stephen Warren, linux-arm-kernel

Ensure all DMA engine drivers initialize their cookies in the same way,
so that they all behave in a similar fashion.  This means their first
issued cookie will be 2 rather than 1, and will increment to INT_MAX
before returning 1 and starting over.

In connection with this, Dan Williams said:
> Russell King wrote:
> > Secondly, some DMA engine drivers initialize the dma_chan cookie to 0,
> > others to 1.  Is there a reason for this, or are these all buggy?
>
> I know that ioat and iop-adma expect 0 to mean "I have cleaned up this
> descriptor and it is idle", and would break if zero was an in-flight
> cookie value.  The reserved usage of zero is an driver internal
> concern, but I have no problem formalizing it as a reserved value.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/fsldma.c      |    1 +
 drivers/dma/imx-dma.c     |    1 +
 drivers/dma/imx-sdma.c    |    1 +
 drivers/dma/ioat/dma.c    |    1 +
 drivers/dma/iop-adma.c    |    1 +
 drivers/dma/mv_xor.c      |    1 +
 drivers/dma/mxs-dma.c     |    1 +
 drivers/dma/ppc4xx/adma.c |    1 +
 drivers/dma/shdma.c       |    1 +
 9 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 2f6c806..7d7384b 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1292,6 +1292,7 @@ static int __devinit fsl_dma_chan_probe(struct fsldma_device *fdev,
 	chan->idle = true;
 
 	chan->common.device = &fdev->common;
+	dma_cookie_init(&chan->common);
 
 	/* find the IRQ line, if it exists in the device tree */
 	chan->irq = irq_of_parse_and_map(node, 0);
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index ba317e6..4e14f51 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -348,6 +348,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
 		spin_lock_init(&imxdmac->lock);
 
 		imxdmac->chan.device = &imxdma->dma_device;
+		dma_cookie_init(&imxdmac->chan);
 		imxdmac->channel = i;
 
 		/* Add the channel to the DMAC list */
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 4406be2..0be36a4 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1356,6 +1356,7 @@ static int __init sdma_probe(struct platform_device *pdev)
 		spin_lock_init(&sdmac->lock);
 
 		sdmac->chan.device = &sdma->dma_device;
+		dma_cookie_init(&sdmac->chan);
 		sdmac->channel = i;
 
 		/*
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 97e100c..31493d8 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -109,6 +109,7 @@ void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *c
 	chan->reg_base = device->reg_base + (0x80 * (idx + 1));
 	spin_lock_init(&chan->cleanup_lock);
 	chan->common.device = dma;
+	dma_cookie_init(&chan->common);
 	list_add_tail(&chan->common.device_node, &dma->channels);
 	device->idx[idx] = chan;
 	init_timer(&chan->timer);
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 4370b10..1f3a703 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -1545,6 +1545,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&iop_chan->chain);
 	INIT_LIST_HEAD(&iop_chan->all_slots);
 	iop_chan->common.device = dma_dev;
+	dma_cookie_init(&iop_chan->common);
 	list_add_tail(&iop_chan->common.device_node, &dma_dev->channels);
 
 	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 486353e..fa5d55f 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -1193,6 +1193,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&mv_chan->completed_slots);
 	INIT_LIST_HEAD(&mv_chan->all_slots);
 	mv_chan->common.device = dma_dev;
+	dma_cookie_init(&mv_chan->common);
 
 	list_add_tail(&mv_chan->common.device_node, &dma_dev->channels);
 
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 5f3492e..a2267f9 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -618,6 +618,7 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
 
 		mxs_chan->mxs_dma = mxs_dma;
 		mxs_chan->chan.device = &mxs_dma->dma_device;
+		dma_cookie_init(&mxs_chan->chan);
 
 		tasklet_init(&mxs_chan->tasklet, mxs_dma_tasklet,
 			     (unsigned long) mxs_chan);
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 9752062..ced9882 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -4497,6 +4497,7 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev)
 	INIT_LIST_HEAD(&chan->all_slots);
 	chan->device = adev;
 	chan->common.device = &adev->common;
+	dma_cookie_init(&chan->common);
 	list_add_tail(&chan->common.device_node, &adev->common.channels);
 	tasklet_init(&chan->irq_tasklet, ppc440spe_adma_tasklet,
 		     (unsigned long)chan);
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 50510ef..5c40886 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -1089,6 +1089,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
 
 	/* reference struct dma_device */
 	new_sh_chan->common.device = &shdev->common;
+	dma_cookie_init(&new_sh_chan->common);
 
 	new_sh_chan->dev = shdev->common.dev;
 	new_sh_chan->id = id;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 9/9] dmaengine: ensure all DMA engine drivers initialize their cookies
@ 2012-03-06 22:36   ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-06 22:36 UTC (permalink / raw)
  To: linux-arm-kernel

Ensure all DMA engine drivers initialize their cookies in the same way,
so that they all behave in a similar fashion.  This means their first
issued cookie will be 2 rather than 1, and will increment to INT_MAX
before returning 1 and starting over.

In connection with this, Dan Williams said:
> Russell King wrote:
> > Secondly, some DMA engine drivers initialize the dma_chan cookie to 0,
> > others to 1. ?Is there a reason for this, or are these all buggy?
>
> I know that ioat and iop-adma expect 0 to mean "I have cleaned up this
> descriptor and it is idle", and would break if zero was an in-flight
> cookie value.  The reserved usage of zero is an driver internal
> concern, but I have no problem formalizing it as a reserved value.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/fsldma.c      |    1 +
 drivers/dma/imx-dma.c     |    1 +
 drivers/dma/imx-sdma.c    |    1 +
 drivers/dma/ioat/dma.c    |    1 +
 drivers/dma/iop-adma.c    |    1 +
 drivers/dma/mv_xor.c      |    1 +
 drivers/dma/mxs-dma.c     |    1 +
 drivers/dma/ppc4xx/adma.c |    1 +
 drivers/dma/shdma.c       |    1 +
 9 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 2f6c806..7d7384b 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1292,6 +1292,7 @@ static int __devinit fsl_dma_chan_probe(struct fsldma_device *fdev,
 	chan->idle = true;
 
 	chan->common.device = &fdev->common;
+	dma_cookie_init(&chan->common);
 
 	/* find the IRQ line, if it exists in the device tree */
 	chan->irq = irq_of_parse_and_map(node, 0);
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index ba317e6..4e14f51 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -348,6 +348,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
 		spin_lock_init(&imxdmac->lock);
 
 		imxdmac->chan.device = &imxdma->dma_device;
+		dma_cookie_init(&imxdmac->chan);
 		imxdmac->channel = i;
 
 		/* Add the channel to the DMAC list */
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 4406be2..0be36a4 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1356,6 +1356,7 @@ static int __init sdma_probe(struct platform_device *pdev)
 		spin_lock_init(&sdmac->lock);
 
 		sdmac->chan.device = &sdma->dma_device;
+		dma_cookie_init(&sdmac->chan);
 		sdmac->channel = i;
 
 		/*
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 97e100c..31493d8 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -109,6 +109,7 @@ void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *c
 	chan->reg_base = device->reg_base + (0x80 * (idx + 1));
 	spin_lock_init(&chan->cleanup_lock);
 	chan->common.device = dma;
+	dma_cookie_init(&chan->common);
 	list_add_tail(&chan->common.device_node, &dma->channels);
 	device->idx[idx] = chan;
 	init_timer(&chan->timer);
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 4370b10..1f3a703 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -1545,6 +1545,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&iop_chan->chain);
 	INIT_LIST_HEAD(&iop_chan->all_slots);
 	iop_chan->common.device = dma_dev;
+	dma_cookie_init(&iop_chan->common);
 	list_add_tail(&iop_chan->common.device_node, &dma_dev->channels);
 
 	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 486353e..fa5d55f 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -1193,6 +1193,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&mv_chan->completed_slots);
 	INIT_LIST_HEAD(&mv_chan->all_slots);
 	mv_chan->common.device = dma_dev;
+	dma_cookie_init(&mv_chan->common);
 
 	list_add_tail(&mv_chan->common.device_node, &dma_dev->channels);
 
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 5f3492e..a2267f9 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -618,6 +618,7 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
 
 		mxs_chan->mxs_dma = mxs_dma;
 		mxs_chan->chan.device = &mxs_dma->dma_device;
+		dma_cookie_init(&mxs_chan->chan);
 
 		tasklet_init(&mxs_chan->tasklet, mxs_dma_tasklet,
 			     (unsigned long) mxs_chan);
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 9752062..ced9882 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -4497,6 +4497,7 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev)
 	INIT_LIST_HEAD(&chan->all_slots);
 	chan->device = adev;
 	chan->common.device = &adev->common;
+	dma_cookie_init(&chan->common);
 	list_add_tail(&chan->common.device_node, &adev->common.channels);
 	tasklet_init(&chan->irq_tasklet, ppc440spe_adma_tasklet,
 		     (unsigned long)chan);
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 50510ef..5c40886 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -1089,6 +1089,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
 
 	/* reference struct dma_device */
 	new_sh_chan->common.device = &shdev->common;
+	dma_cookie_init(&new_sh_chan->common);
 
 	new_sh_chan->dev = shdev->common.dev;
 	new_sh_chan->id = id;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* RE: [PATCH 2/9] dmaengine: move last completed cookie into generic dma_chan structure
  2012-03-06 22:34   ` Russell King - ARM Linux
@ 2012-03-07  0:38     ` H Hartley Sweeten
  -1 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:38 UTC (permalink / raw)
  To: Russell King - ARM Linux, Dan Williams, Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	linuxppc-dev, linux-arm-kernel

On Tuesday, March 06, 2012 3:34 PM, Russell King wrote:
>
> Every DMA engine implementation declares a last completed dma cookie
> in their private dma channel structures.  This is pointless, and
> forces driver specific code.  Move this out into the common dma_chan
> structure.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

 drivers/dma/ep93xx_dma.c                 |    8 +++-----

<snip>

 include/linux/dmaengine.h                |    2 ++

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 59e7a96..bc45787 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -122,7 +122,6 @@ struct ep93xx_dma_desc {
>   * @lock: lock protecting the fields following
>   * @flags: flags for the channel
>   * @buffer: which buffer to use next (0/1)
> - * @last_completed: last completed cookie value
>   * @active: flattened chain of descriptors currently being processed
>   * @queue: pending descriptors which are handled next
>   * @free_list: list of free descriptors which can be used
> @@ -157,7 +156,6 @@ struct ep93xx_dma_chan {
>  #define EP93XX_DMA_IS_CYCLIC		0
> =20
>  	int				buffer;
> -	dma_cookie_t			last_completed;
>  	struct list_head		active;
>  	struct list_head		queue;
>  	struct list_head		free_list;
> @@ -703,7 +701,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	desc =3D ep93xx_dma_get_active(edmac);
>  	if (desc) {
>  		if (desc->complete) {
> -			edmac->last_completed =3D desc->txd.cookie;
> +			edmac->chan.completed_cookie =3D desc->txd.cookie;
>  			list_splice_init(&edmac->active, &list);
>  		}
>  		callback =3D desc->txd.callback;
> @@ -861,7 +859,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma=
_chan *chan)
>  		goto fail_clk_disable;
> =20
>  	spin_lock_irq(&edmac->lock);
> -	edmac->last_completed =3D 1;
> +	edmac->chan.completed_cookie =3D 1;
>  	edmac->chan.cookie =3D 1;
>  	ret =3D edmac->edma->hw_setup(edmac);
>  	spin_unlock_irq(&edmac->lock);
> @@ -1254,7 +1252,7 @@ static enum dma_status ep93xx_dma_tx_status(struct =
dma_chan *chan,
> =20
>  	spin_lock_irqsave(&edmac->lock, flags);
>  	last_used =3D chan->cookie;
> -	last_completed =3D edmac->last_completed;
> +	last_completed =3D chan->completed_cookie;
>  	spin_unlock_irqrestore(&edmac->lock, flags);
> =20
>  	ret =3D dma_async_is_complete(cookie, last_completed, last_used);

<snip>

> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 679b349..41d0f92 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -257,6 +257,7 @@ struct dma_chan_percpu {
>   * struct dma_chan - devices supply DMA channels, clients use them
>   * @device: ptr to the dma device who supplies this channel, always !%NU=
LL
>   * @cookie: last cookie value returned to client
> + * @completed_cookie: last completed cookie for this channel
>   * @chan_id: channel ID for sysfs
>   * @dev: class device for sysfs
>   * @device_node: used to add this to the device chan list
> @@ -268,6 +269,7 @@ struct dma_chan_percpu {
>  struct dma_chan {
>  	struct dma_device *device;
>  	dma_cookie_t cookie;
> +	dma_cookie_t completed_cookie;
> =20
>  	/* sysfs */
>  	int chan_id;

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 2/9] dmaengine: move last completed cookie into generic dma_chan structure
@ 2012-03-07  0:38     ` H Hartley Sweeten
  0 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, March 06, 2012 3:34 PM, Russell King wrote:
>
> Every DMA engine implementation declares a last completed dma cookie
> in their private dma channel structures.  This is pointless, and
> forces driver specific code.  Move this out into the common dma_chan
> structure.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

 drivers/dma/ep93xx_dma.c                 |    8 +++-----

<snip>

 include/linux/dmaengine.h                |    2 ++

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 59e7a96..bc45787 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -122,7 +122,6 @@ struct ep93xx_dma_desc {
>   * @lock: lock protecting the fields following
>   * @flags: flags for the channel
>   * @buffer: which buffer to use next (0/1)
> - * @last_completed: last completed cookie value
>   * @active: flattened chain of descriptors currently being processed
>   * @queue: pending descriptors which are handled next
>   * @free_list: list of free descriptors which can be used
> @@ -157,7 +156,6 @@ struct ep93xx_dma_chan {
>  #define EP93XX_DMA_IS_CYCLIC		0
>  
>  	int				buffer;
> -	dma_cookie_t			last_completed;
>  	struct list_head		active;
>  	struct list_head		queue;
>  	struct list_head		free_list;
> @@ -703,7 +701,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	desc = ep93xx_dma_get_active(edmac);
>  	if (desc) {
>  		if (desc->complete) {
> -			edmac->last_completed = desc->txd.cookie;
> +			edmac->chan.completed_cookie = desc->txd.cookie;
>  			list_splice_init(&edmac->active, &list);
>  		}
>  		callback = desc->txd.callback;
> @@ -861,7 +859,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
>  		goto fail_clk_disable;
>  
>  	spin_lock_irq(&edmac->lock);
> -	edmac->last_completed = 1;
> +	edmac->chan.completed_cookie = 1;
>  	edmac->chan.cookie = 1;
>  	ret = edmac->edma->hw_setup(edmac);
>  	spin_unlock_irq(&edmac->lock);
> @@ -1254,7 +1252,7 @@ static enum dma_status ep93xx_dma_tx_status(struct dma_chan *chan,
>  
>  	spin_lock_irqsave(&edmac->lock, flags);
>  	last_used = chan->cookie;
> -	last_completed = edmac->last_completed;
> +	last_completed = chan->completed_cookie;
>  	spin_unlock_irqrestore(&edmac->lock, flags);
>  
>  	ret = dma_async_is_complete(cookie, last_completed, last_used);

<snip>

> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 679b349..41d0f92 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -257,6 +257,7 @@ struct dma_chan_percpu {
>   * struct dma_chan - devices supply DMA channels, clients use them
>   * @device: ptr to the dma device who supplies this channel, always !%NULL
>   * @cookie: last cookie value returned to client
> + * @completed_cookie: last completed cookie for this channel
>   * @chan_id: channel ID for sysfs
>   * @dev: class device for sysfs
>   * @device_node: used to add this to the device chan list
> @@ -268,6 +269,7 @@ struct dma_chan_percpu {
>  struct dma_chan {
>  	struct dma_device *device;
>  	dma_cookie_t cookie;
> +	dma_cookie_t completed_cookie;
>  
>  	/* sysfs */
>  	int chan_id;

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* RE: [PATCH 3/9] dmaengine: add private header file
  2012-03-06 22:34   ` Russell King - ARM Linux
@ 2012-03-07  0:47     ` H Hartley Sweeten
  -1 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:47 UTC (permalink / raw)
  To: Russell King - ARM Linux, Dan Williams, Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, linuxppc-dev,
	linux-arm-kernel

On Tuesday, March 06, 2012 3:34 PM, Russell King wrote:
>
> Add a local private header file to contain definitions and declarations
> which should only be used by DMA engine drivers.
>
> We also fix linux/dmaengine.h to use LINUX_DMAENGINE_H to guard against
> multiple inclusion.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   10 ++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    2 ++

<snip>

>  include/linux/dmaengine.h   |    4 ++--

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> new file mode 100644
> index 0000000..968570d
> --- /dev/null
> +++ b/drivers/dma/dmaengine.h
> @@ -0,0 +1,10 @@
> +/*
> + * The contents of this file are private to DMA engine drivers, and is n=
ot
> + * part of the API to be used by DMA engine users.
> + */
> +#ifndef DMAENGINE_H
> +#define DMAENGINE_H
> +
> +#include <linux/dmaengine.h>
> +
> +#endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index bc45787..3260198 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -28,6 +28,8 @@
> =20
>  #include <mach/dma.h>
> =20
> +#include "dmaengine.h"
> +
>  /* M2P registers */
>  #define M2P_CONTROL			0x0000
>  #define M2P_CONTROL_STALLINT		BIT(0)

<snip>

> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 41d0f92..4b17ca8 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -18,8 +18,8 @@
>   * The full GNU General Public License is included in this distribution =
in the
>   * file called COPYING.
>   */
> -#ifndef DMAENGINE_H
> -#define DMAENGINE_H
> +#ifndef LINUX_DMAENGINE_H
> +#define LINUX_DMAENGINE_H
> =20
>  #include <linux/device.h>
>  #include <linux/uio.h>

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 3/9] dmaengine: add private header file
@ 2012-03-07  0:47     ` H Hartley Sweeten
  0 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, March 06, 2012 3:34 PM, Russell King wrote:
>
> Add a local private header file to contain definitions and declarations
> which should only be used by DMA engine drivers.
>
> We also fix linux/dmaengine.h to use LINUX_DMAENGINE_H to guard against
> multiple inclusion.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   10 ++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    2 ++

<snip>

>  include/linux/dmaengine.h   |    4 ++--

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> new file mode 100644
> index 0000000..968570d
> --- /dev/null
> +++ b/drivers/dma/dmaengine.h
> @@ -0,0 +1,10 @@
> +/*
> + * The contents of this file are private to DMA engine drivers, and is not
> + * part of the API to be used by DMA engine users.
> + */
> +#ifndef DMAENGINE_H
> +#define DMAENGINE_H
> +
> +#include <linux/dmaengine.h>
> +
> +#endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index bc45787..3260198 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -28,6 +28,8 @@
>  
>  #include <mach/dma.h>
>  
> +#include "dmaengine.h"
> +
>  /* M2P registers */
>  #define M2P_CONTROL			0x0000
>  #define M2P_CONTROL_STALLINT		BIT(0)

<snip>

> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 41d0f92..4b17ca8 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -18,8 +18,8 @@
>   * The full GNU General Public License is included in this distribution in the
>   * file called COPYING.
>   */
> -#ifndef DMAENGINE_H
> -#define DMAENGINE_H
> +#ifndef LINUX_DMAENGINE_H
> +#define LINUX_DMAENGINE_H
>  
>  #include <linux/device.h>
>  #include <linux/uio.h>

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* RE: [PATCH 4/9] dmaengine: consolidate assignment of DMA cookies
  2012-03-06 22:34   ` Russell King - ARM Linux
@ 2012-03-07  0:53     ` H Hartley Sweeten
  -1 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:53 UTC (permalink / raw)
  To: Russell King - ARM Linux, Dan Williams, Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	linuxppc-dev, linux-arm-kernel

On Tuesday, March 06, 2012 3:35 PM, Russell King wrote:
>
> Everyone deals with assigning DMA cookies in the same way (it's part of
> the API so they should be), so lets consolidate the common code into a
> helper function to avoid this duplication.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   20 ++++++++++++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    9 +--------

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 968570d..7692c86 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -7,4 +7,24 @@
> =20
>  #include <linux/dmaengine.h>
> =20
> +/**
> + * dma_cookie_assign - assign a DMA engine cookie to the descriptor
> + * @tx: descriptor needing cookie
> + *
> + * Assign a unique non-zero per-channel cookie to the descriptor.
> + * Note: caller is expected to hold a lock to prevent concurrency.
> + */
> +static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descrip=
tor *tx)
> +{
> +	struct dma_chan *chan =3D tx->chan;
> +	dma_cookie_t cookie;
> +
> +	cookie =3D chan->cookie + 1;
> +	if (cookie < DMA_MIN_COOKIE)
> +		cookie =3D DMA_MIN_COOKIE;
> +	tx->cookie =3D chan->cookie =3D cookie;
> +
> +	return cookie;
> +}
> +
>  #endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 3260198..e5aaae8 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -783,17 +783,10 @@ static dma_cookie_t ep93xx_dma_tx_submit(struct dma=
_async_tx_descriptor *tx)
>  	unsigned long flags;
> =20
>  	spin_lock_irqsave(&edmac->lock, flags);
> -
> -	cookie =3D edmac->chan.cookie;
> -
> -	if (++cookie < 0)
> -		cookie =3D 1;
> +	cookie =3D dma_cookie_assign(tx);
> =20
>  	desc =3D container_of(tx, struct ep93xx_dma_desc, txd);
> =20
> -	edmac->chan.cookie =3D cookie;
> -	desc->txd.cookie =3D cookie;
> -
>  	/*
>  	 * If nothing is currently prosessed, we push this descriptor
>  	 * directly to the hardware. Otherwise we put the descriptor

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 4/9] dmaengine: consolidate assignment of DMA cookies
@ 2012-03-07  0:53     ` H Hartley Sweeten
  0 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, March 06, 2012 3:35 PM, Russell King wrote:
>
> Everyone deals with assigning DMA cookies in the same way (it's part of
> the API so they should be), so lets consolidate the common code into a
> helper function to avoid this duplication.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   20 ++++++++++++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    9 +--------

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 968570d..7692c86 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -7,4 +7,24 @@
>  
>  #include <linux/dmaengine.h>
>  
> +/**
> + * dma_cookie_assign - assign a DMA engine cookie to the descriptor
> + * @tx: descriptor needing cookie
> + *
> + * Assign a unique non-zero per-channel cookie to the descriptor.
> + * Note: caller is expected to hold a lock to prevent concurrency.
> + */
> +static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
> +{
> +	struct dma_chan *chan = tx->chan;
> +	dma_cookie_t cookie;
> +
> +	cookie = chan->cookie + 1;
> +	if (cookie < DMA_MIN_COOKIE)
> +		cookie = DMA_MIN_COOKIE;
> +	tx->cookie = chan->cookie = cookie;
> +
> +	return cookie;
> +}
> +
>  #endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 3260198..e5aaae8 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -783,17 +783,10 @@ static dma_cookie_t ep93xx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&edmac->lock, flags);
> -
> -	cookie = edmac->chan.cookie;
> -
> -	if (++cookie < 0)
> -		cookie = 1;
> +	cookie = dma_cookie_assign(tx);
>  
>  	desc = container_of(tx, struct ep93xx_dma_desc, txd);
>  
> -	edmac->chan.cookie = cookie;
> -	desc->txd.cookie = cookie;
> -
>  	/*
>  	 * If nothing is currently prosessed, we push this descriptor
>  	 * directly to the hardware. Otherwise we put the descriptor

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* RE: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
  2012-03-06 22:35   ` Russell King - ARM Linux
@ 2012-03-07  0:56     ` H Hartley Sweeten
  -1 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:56 UTC (permalink / raw)
  To: Russell King - ARM Linux, Dan Williams, Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, linuxppc-dev,
	linux-arm-kernel

On Tuesday, March 06, 2012 3:35 PM, Russell King wrote:
>
> Provide a common function to do the cookie mechanics for completing
> a DMA descriptor.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   18 ++++++++++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    2 +-

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 7692c86..47e0997 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -5,6 +5,7 @@
>  #ifndef DMAENGINE_H
>  #define DMAENGINE_H
> =20
> +#include <linux/bug.h>
>  #include <linux/dmaengine.h>
> =20
>  /**
> @@ -27,4 +28,21 @@ static inline dma_cookie_t dma_cookie_assign(struct dm=
a_async_tx_descriptor *tx)
>  	return cookie;
>  }
> =20
> +/**
> + * dma_cookie_complete - complete a descriptor
> + * @tx: descriptor to complete
> + *
> + * Mark this descriptor complete by updating the channels completed
> + * cookie marker.  Zero the descriptors cookie to prevent accidental
> + * repeated completions.
> + *
> + * Note: caller is expected to hold a lock to prevent concurrency.
> + */
> +static inline void dma_cookie_complete(struct dma_async_tx_descriptor *t=
x)
> +{
> +	BUG_ON(tx->cookie < DMA_MIN_COOKIE);
> +	tx->chan->completed_cookie =3D tx->cookie;
> +	tx->cookie =3D 0;
> +}
> +
>  #endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index e5aaae8..1c56f75 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -703,7 +703,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	desc =3D ep93xx_dma_get_active(edmac);
>  	if (desc) {
>  		if (desc->complete) {
> -			edmac->chan.completed_cookie =3D desc->txd.cookie;
> +			dma_cookie_complete(&desc->txd);
>  			list_splice_init(&edmac->active, &list);
>  		}
>  		callback =3D desc->txd.callback;

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
@ 2012-03-07  0:56     ` H Hartley Sweeten
  0 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  0:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, March 06, 2012 3:35 PM, Russell King wrote:
>
> Provide a common function to do the cookie mechanics for completing
> a DMA descriptor.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   18 ++++++++++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    2 +-

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 7692c86..47e0997 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -5,6 +5,7 @@
>  #ifndef DMAENGINE_H
>  #define DMAENGINE_H
>  
> +#include <linux/bug.h>
>  #include <linux/dmaengine.h>
>  
>  /**
> @@ -27,4 +28,21 @@ static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor *tx)
>  	return cookie;
>  }
>  
> +/**
> + * dma_cookie_complete - complete a descriptor
> + * @tx: descriptor to complete
> + *
> + * Mark this descriptor complete by updating the channels completed
> + * cookie marker.  Zero the descriptors cookie to prevent accidental
> + * repeated completions.
> + *
> + * Note: caller is expected to hold a lock to prevent concurrency.
> + */
> +static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
> +{
> +	BUG_ON(tx->cookie < DMA_MIN_COOKIE);
> +	tx->chan->completed_cookie = tx->cookie;
> +	tx->cookie = 0;
> +}
> +
>  #endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index e5aaae8..1c56f75 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -703,7 +703,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	desc = ep93xx_dma_get_active(edmac);
>  	if (desc) {
>  		if (desc->complete) {
> -			edmac->chan.completed_cookie = desc->txd.cookie;
> +			dma_cookie_complete(&desc->txd);
>  			list_splice_init(&edmac->active, &list);
>  		}
>  		callback = desc->txd.callback;

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* RE: [PATCH 6/9] dmaengine: consolidate tx_status functions
  2012-03-06 22:35   ` Russell King - ARM Linux
@ 2012-03-07  1:04     ` H Hartley Sweeten
  -1 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  1:04 UTC (permalink / raw)
  To: Russell King - ARM Linux, Dan Williams, Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	linuxppc-dev, linux-arm-kernel

On Tuesday, March 06, 2012 3:35 PM, Russell King wrote:
>
> Now that we have the completed cookie in the dma_chan structure, we
> can consolidate the tx_status functions by providing a function to set
> the txstate structure and returning the DMA status.  We also provide
> a separate helper to set the residue for cookies which are still in
> progress.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   31 +++++++++++++++++++++++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    7 +------

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 47e0997..1ca5e0e 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -45,4 +45,35 @@ static inline void dma_cookie_complete(struct dma_asyn=
c_tx_descriptor *tx)
>  	tx->cookie =3D 0;
>  }
> =20
> +/**
> + * dma_cookie_status - report cookie status
> + * @chan: dma channel
> + * @cookie: cookie we are interested in
> + * @state: dma_tx_state structure to return last/used cookies
> + *
> + * Report the status of the cookie, filling in the state structure if
> + * non-NULL.  No locking is required.
> + */
> +static inline enum dma_status dma_cookie_status(struct dma_chan *chan,
> +	dma_cookie_t cookie, struct dma_tx_state *state)
> +{
> +	dma_cookie_t used, complete;
> +
> +	used =3D chan->cookie;
> +	complete =3D chan->completed_cookie;
> +	barrier();
> +	if (state) {
> +		state->last =3D complete;
> +		state->used =3D used;
> +		state->residue =3D 0;
> +	}
> +	return dma_async_is_complete(cookie, complete, used);
> +}
> +
> +static inline void dma_set_residue(struct dma_tx_state *state, u32 resid=
ue)
> +{
> +	if (state)
> +		state->residue =3D residue;
> +}
> +
>  #endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 1c56f75..142ebf0 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -1241,18 +1241,13 @@ static enum dma_status ep93xx_dma_tx_status(struc=
t dma_chan *chan,
>  					    struct dma_tx_state *state)
>  {
>  	struct ep93xx_dma_chan *edmac =3D to_ep93xx_dma_chan(chan);
> -	dma_cookie_t last_used, last_completed;
>  	enum dma_status ret;
>  	unsigned long flags;
> =20
>  	spin_lock_irqsave(&edmac->lock, flags);
> -	last_used =3D chan->cookie;
> -	last_completed =3D chan->completed_cookie;
> +	ret =3D dma_cookie_status(chan, cookie, state);
>  	spin_unlock_irqrestore(&edmac->lock, flags);
> =20
> -	ret =3D dma_async_is_complete(cookie, last_completed, last_used);
> -	dma_set_tx_state(state, last_completed, last_used, 0);
> -
>  	return ret;
>  }
> =20

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 6/9] dmaengine: consolidate tx_status functions
@ 2012-03-07  1:04     ` H Hartley Sweeten
  0 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  1:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, March 06, 2012 3:35 PM, Russell King wrote:
>
> Now that we have the completed cookie in the dma_chan structure, we
> can consolidate the tx_status functions by providing a function to set
> the txstate structure and returning the DMA status.  We also provide
> a separate helper to set the residue for cookies which are still in
> progress.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   31 +++++++++++++++++++++++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    7 +------

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 47e0997..1ca5e0e 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -45,4 +45,35 @@ static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
>  	tx->cookie = 0;
>  }
>  
> +/**
> + * dma_cookie_status - report cookie status
> + * @chan: dma channel
> + * @cookie: cookie we are interested in
> + * @state: dma_tx_state structure to return last/used cookies
> + *
> + * Report the status of the cookie, filling in the state structure if
> + * non-NULL.  No locking is required.
> + */
> +static inline enum dma_status dma_cookie_status(struct dma_chan *chan,
> +	dma_cookie_t cookie, struct dma_tx_state *state)
> +{
> +	dma_cookie_t used, complete;
> +
> +	used = chan->cookie;
> +	complete = chan->completed_cookie;
> +	barrier();
> +	if (state) {
> +		state->last = complete;
> +		state->used = used;
> +		state->residue = 0;
> +	}
> +	return dma_async_is_complete(cookie, complete, used);
> +}
> +
> +static inline void dma_set_residue(struct dma_tx_state *state, u32 residue)
> +{
> +	if (state)
> +		state->residue = residue;
> +}
> +
>  #endif

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 1c56f75..142ebf0 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -1241,18 +1241,13 @@ static enum dma_status ep93xx_dma_tx_status(struct dma_chan *chan,
>  					    struct dma_tx_state *state)
>  {
>  	struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
> -	dma_cookie_t last_used, last_completed;
>  	enum dma_status ret;
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&edmac->lock, flags);
> -	last_used = chan->cookie;
> -	last_completed = chan->completed_cookie;
> +	ret = dma_cookie_status(chan, cookie, state);
>  	spin_unlock_irqrestore(&edmac->lock, flags);
>  
> -	ret = dma_async_is_complete(cookie, last_completed, last_used);
> -	dma_set_tx_state(state, last_completed, last_used, 0);
> -
>  	return ret;
>  }
>  

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 7/9] dmaengine: consolidate initialization of cookies
  2012-03-06 22:35 ` [PATCH 7/9] dmaengine: consolidate initialization of cookies Russell King - ARM Linux
@ 2012-03-07  1:07   ` H Hartley Sweeten
  0 siblings, 0 replies; 66+ messages in thread
From: H Hartley Sweeten @ 2012-03-07  1:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, March 06, 2012 3:36 PM, Russell King wrote:
>
> Provide a common function to initialize a channels cookie values.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---

<snip>

>  drivers/dma/dmaengine.h     |   10 ++++++++++

<snip>

>  drivers/dma/ep93xx_dma.c    |    3 +--

<snip>

> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 1ca5e0e..17f983a 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -9,6 +9,16 @@
>  #include <linux/dmaengine.h>
>  
>  /**
> + * dma_cookie_init - initialize the cookies for a DMA channel
> + * @chan: dma channel to initialize
> + */
> +static inline void dma_cookie_init(struct dma_chan *chan)
> +{
> +	chan->cookie = DMA_MIN_COOKIE;
> +	chan->completed_cookie = DMA_MIN_COOKIE;
> +}
> +
> +/**
>   * dma_cookie_assign - assign a DMA engine cookie to the descriptor
>   * @tx: descriptor needing cookie
>   *

<snip>

> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index 142ebf0..f25e83b 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -854,8 +854,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
>  		goto fail_clk_disable;
>  
>  	spin_lock_irq(&edmac->lock);
> -	edmac->chan.completed_cookie = 1;
> -	edmac->chan.cookie = 1;
> +	dma_cookie_init(&edmac->chan);
>  	ret = edmac->edma->hw_setup(edmac);
>  	spin_unlock_irq(&edmac->lock);
>  

For ep93xx:

Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-07  8:33   ` Linus Walleij
  -1 siblings, 0 replies; 66+ messages in thread
From: Linus Walleij @ 2012-03-07  8:33 UTC (permalink / raw)
  To: Russell King - ARM Linux, Dan Williams, Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	linuxppc-dev, linux-arm-kernel

On Tue, Mar 6, 2012 at 11:33 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:

> This patch series cleans up the handling of cookies in DMA engine drivers.
> This is done by providing a set of inline library functions for common
> tasks:

I just applied the latest patches right off and tested with some stressy
MMC operations on the U300 and Ux500. (I had some minor hell
since patch 8/9 and 9/9 were uuencoded but managed to fix it...)

It works like a charm!

The patches look good too.

Tested-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-07  8:33   ` Linus Walleij
  0 siblings, 0 replies; 66+ messages in thread
From: Linus Walleij @ 2012-03-07  8:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 6, 2012 at 11:33 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:

> This patch series cleans up the handling of cookies in DMA engine drivers.
> This is done by providing a set of inline library functions for common
> tasks:

I just applied the latest patches right off and tested with some stressy
MMC operations on the U300 and Ux500. (I had some minor hell
since patch 8/9 and 9/9 were uuencoded but managed to fix it...)

It works like a charm!

The patches look good too.

Tested-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-07  8:33   ` Linus Walleij
@ 2012-03-07  9:06     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-07  9:06 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Vinod Koul,
	Barry Song, Dan Williams, linuxppc-dev, linux-arm-kernel

On Wed, Mar 07, 2012 at 09:33:49AM +0100, Linus Walleij wrote:
> On Tue, Mar 6, 2012 at 11:33 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> 
> > This patch series cleans up the handling of cookies in DMA engine drivers.
> > This is done by providing a set of inline library functions for common
> > tasks:
> 
> I just applied the latest patches right off and tested with some stressy
> MMC operations on the U300 and Ux500. (I had some minor hell
> since patch 8/9 and 9/9 were uuencoded but managed to fix it...)

That'll be some MTA deciding to change the encoding, probably because some
MTA spotted UTF-8 characters in the description and decided to convert to
base64.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-07  9:06     ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-07  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 07, 2012 at 09:33:49AM +0100, Linus Walleij wrote:
> On Tue, Mar 6, 2012 at 11:33 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> 
> > This patch series cleans up the handling of cookies in DMA engine drivers.
> > This is done by providing a set of inline library functions for common
> > tasks:
> 
> I just applied the latest patches right off and tested with some stressy
> MMC operations on the U300 and Ux500. (I had some minor hell
> since patch 8/9 and 9/9 were uuencoded but managed to fix it...)

That'll be some MTA deciding to change the encoding, probably because some
MTA spotted UTF-8 characters in the description and decided to convert to
base64.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-07 13:54   ` Vinod Koul
  -1 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-07 13:54 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On Tue, 2012-03-06 at 22:33 +0000, Russell King - ARM Linux wrote:
> [v2 - more or less same description.  Including lakml in cc for the full
> set]
> 
> This patch series cleans up the handling of cookies in DMA engine drivers.
> This is done by providing a set of inline library functions for common
> tasks:
> 
> - moving the 'last completed cookie' into struct dma_chan - everyone
>   has this in their driver private channel data structure
> 
> - consolidate allocation of cookies to DMA descriptors
> 
> - common way to update 'last completed cookie' value
> 
> - standard way to implement tx_status callback and update the residue
> 
> - consolidate initialization of cookies
> 
> - update implementations differing from the majority of DMA engine drivers
>   to behave the same as the majority implementation in respect of cookies
> 
> What this means is that we get to the point where all DMA engine drivers
> will hand out cookie value '2' as the first, and incrementing cookie
> values up to INT_MAX, returning to cookie '1' as the next cookie.
> 
> Think of this patch series as round 1...  I am hoping over time that more
> code can be consolidated between the DMA engine drivers and end up with a
> consistent way to handle various common themes in DMA engine hardware
> (like physical channel<->peripheral request signal selection.)
Thanks Russell,

I have tested this on atom today, and as expected works flawlessly :)
After all acks, I can merge or these can go thru your tree with my Ack.
Either way is okay.

I applied the v2 on a branch and also rebased on top of slave-dma.next.
There were few conflicts in imx-dma.c. Sacha, Javier, pls see that merge
is right.

This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am not
able to connect to infradead.org, should be done when server is back.



-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-07 13:54   ` Vinod Koul
  0 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-07 13:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-03-06 at 22:33 +0000, Russell King - ARM Linux wrote:
> [v2 - more or less same description.  Including lakml in cc for the full
> set]
> 
> This patch series cleans up the handling of cookies in DMA engine drivers.
> This is done by providing a set of inline library functions for common
> tasks:
> 
> - moving the 'last completed cookie' into struct dma_chan - everyone
>   has this in their driver private channel data structure
> 
> - consolidate allocation of cookies to DMA descriptors
> 
> - common way to update 'last completed cookie' value
> 
> - standard way to implement tx_status callback and update the residue
> 
> - consolidate initialization of cookies
> 
> - update implementations differing from the majority of DMA engine drivers
>   to behave the same as the majority implementation in respect of cookies
> 
> What this means is that we get to the point where all DMA engine drivers
> will hand out cookie value '2' as the first, and incrementing cookie
> values up to INT_MAX, returning to cookie '1' as the next cookie.
> 
> Think of this patch series as round 1...  I am hoping over time that more
> code can be consolidated between the DMA engine drivers and end up with a
> consistent way to handle various common themes in DMA engine hardware
> (like physical channel<->peripheral request signal selection.)
Thanks Russell,

I have tested this on atom today, and as expected works flawlessly :)
After all acks, I can merge or these can go thru your tree with my Ack.
Either way is okay.

I applied the v2 on a branch and also rebased on top of slave-dma.next.
There were few conflicts in imx-dma.c. Sacha, Javier, pls see that merge
is right.

This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am not
able to connect to infradead.org, should be done when server is back.



-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-07 18:09   ` Jassi Brar
  -1 siblings, 0 replies; 66+ messages in thread
From: Jassi Brar @ 2012-03-07 18:09 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Vinod Koul,
	Barry Song, Dan Williams, linuxppc-dev, linux-arm-kernel

On Wed, Mar 7, 2012 at 4:03 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> [v2 - more or less same description. =C2=A0Including lakml in cc for the =
full
> set]
>
> This patch series cleans up the handling of cookies in DMA engine drivers=
.
> This is done by providing a set of inline library functions for common
> tasks:
>
> - moving the 'last completed cookie' into struct dma_chan - everyone
> =C2=A0has this in their driver private channel data structure
>
> - consolidate allocation of cookies to DMA descriptors
>
> - common way to update 'last completed cookie' value
>
> - standard way to implement tx_status callback and update the residue
>
> - consolidate initialization of cookies
>
> - update implementations differing from the majority of DMA engine driver=
s
> =C2=A0to behave the same as the majority implementation in respect of coo=
kies
>
> What this means is that we get to the point where all DMA engine drivers
> will hand out cookie value '2' as the first, and incrementing cookie
> values up to INT_MAX, returning to cookie '1' as the next cookie.
>
> Think of this patch series as round 1... =C2=A0I am hoping over time that=
 more
> code can be consolidated between the DMA engine drivers and end up with a
> consistent way to handle various common themes in DMA engine hardware
> (like physical channel<->peripheral request signal selection.)
>
Compilation is broken without the following minor fix.
After that you may add
       Acked-by: Jassi Brar <jassisinghbrar@gmail.com>

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 49c123f..abf35a3 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -339,7 +339,6 @@ static int pl330_control(struct dma_chan *chan,
enum dma_ctrl_cmd cmd, unsigned
 		/* Mark all desc done */
 		list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
 			desc->status =3D DONE;
-			pch->completed =3D desc->txd.cookie;
 			list_move_tail(&desc->node, &list);
 		}


Thanks.

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-07 18:09   ` Jassi Brar
  0 siblings, 0 replies; 66+ messages in thread
From: Jassi Brar @ 2012-03-07 18:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 7, 2012 at 4:03 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> [v2 - more or less same description. ?Including lakml in cc for the full
> set]
>
> This patch series cleans up the handling of cookies in DMA engine drivers.
> This is done by providing a set of inline library functions for common
> tasks:
>
> - moving the 'last completed cookie' into struct dma_chan - everyone
> ?has this in their driver private channel data structure
>
> - consolidate allocation of cookies to DMA descriptors
>
> - common way to update 'last completed cookie' value
>
> - standard way to implement tx_status callback and update the residue
>
> - consolidate initialization of cookies
>
> - update implementations differing from the majority of DMA engine drivers
> ?to behave the same as the majority implementation in respect of cookies
>
> What this means is that we get to the point where all DMA engine drivers
> will hand out cookie value '2' as the first, and incrementing cookie
> values up to INT_MAX, returning to cookie '1' as the next cookie.
>
> Think of this patch series as round 1... ?I am hoping over time that more
> code can be consolidated between the DMA engine drivers and end up with a
> consistent way to handle various common themes in DMA engine hardware
> (like physical channel<->peripheral request signal selection.)
>
Compilation is broken without the following minor fix.
After that you may add
       Acked-by: Jassi Brar <jassisinghbrar@gmail.com>

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 49c123f..abf35a3 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -339,7 +339,6 @@ static int pl330_control(struct dma_chan *chan,
enum dma_ctrl_cmd cmd, unsigned
 		/* Mark all desc done */
 		list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
 			desc->status = DONE;
-			pch->completed = desc->txd.cookie;
 			list_move_tail(&desc->node, &list);
 		}


Thanks.

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-07 18:09   ` Jassi Brar
@ 2012-03-07 18:21     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-07 18:21 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Vinod Koul,
	Barry Song, Dan Williams, linuxppc-dev, linux-arm-kernel

On Wed, Mar 07, 2012 at 11:39:25PM +0530, Jassi Brar wrote:
> Compilation is broken without the following minor fix.
> After that you may add
>        Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
> 
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 49c123f..abf35a3 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -339,7 +339,6 @@ static int pl330_control(struct dma_chan *chan,
> enum dma_ctrl_cmd cmd, unsigned
>  		/* Mark all desc done */
>  		list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
>  			desc->status = DONE;
> -			pch->completed = desc->txd.cookie;

I'm not sure just removing this is sufficient.  Presumably it's
there for some reason - maybe it needs replacing with a call to
dma_cookie_complete() to preserve existing behaviour?

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-07 18:21     ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-07 18:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 07, 2012 at 11:39:25PM +0530, Jassi Brar wrote:
> Compilation is broken without the following minor fix.
> After that you may add
>        Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
> 
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 49c123f..abf35a3 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -339,7 +339,6 @@ static int pl330_control(struct dma_chan *chan,
> enum dma_ctrl_cmd cmd, unsigned
>  		/* Mark all desc done */
>  		list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
>  			desc->status = DONE;
> -			pch->completed = desc->txd.cookie;

I'm not sure just removing this is sufficient.  Presumably it's
there for some reason - maybe it needs replacing with a call to
dma_cookie_complete() to preserve existing behaviour?

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-07 18:21     ` Russell King - ARM Linux
@ 2012-03-07 18:44       ` Jassi Brar
  -1 siblings, 0 replies; 66+ messages in thread
From: Jassi Brar @ 2012-03-07 18:44 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Vinod Koul,
	Barry Song, Dan Williams, linuxppc-dev, linux-arm-kernel

On Wed, Mar 7, 2012 at 11:51 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Mar 07, 2012 at 11:39:25PM +0530, Jassi Brar wrote:
>> Compilation is broken without the following minor fix.
>> After that you may add
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0Acked-by: Jassi Brar <jassisinghbrar@gmail.co=
m>
>>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index 49c123f..abf35a3 100644
>> --- a/drivers/dma/pl330.c
>> +++ b/drivers/dma/pl330.c
>> @@ -339,7 +339,6 @@ static int pl330_control(struct dma_chan *chan,
>> enum dma_ctrl_cmd cmd, unsigned
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Mark all desc done *=
/
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 list_for_each_entry_saf=
e(desc, _dt, &pch->work_list , node) {
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 desc->status =3D DONE;
>> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
pch->completed =3D desc->txd.cookie;
>
> I'm not sure just removing this is sufficient. =C2=A0Presumably it's
> there for some reason - maybe it needs replacing with a call to
> dma_cookie_complete() to preserve existing behaviour?
>
That was anyway a redundant save in DMA_TERMINATE_ALL, so it should be ok.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-07 18:44       ` Jassi Brar
  0 siblings, 0 replies; 66+ messages in thread
From: Jassi Brar @ 2012-03-07 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 7, 2012 at 11:51 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Mar 07, 2012 at 11:39:25PM +0530, Jassi Brar wrote:
>> Compilation is broken without the following minor fix.
>> After that you may add
>> ? ? ? ?Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
>>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index 49c123f..abf35a3 100644
>> --- a/drivers/dma/pl330.c
>> +++ b/drivers/dma/pl330.c
>> @@ -339,7 +339,6 @@ static int pl330_control(struct dma_chan *chan,
>> enum dma_ctrl_cmd cmd, unsigned
>> ? ? ? ? ? ? ? /* Mark all desc done */
>> ? ? ? ? ? ? ? list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
>> ? ? ? ? ? ? ? ? ? ? ? desc->status = DONE;
>> - ? ? ? ? ? ? ? ? ? ? pch->completed = desc->txd.cookie;
>
> I'm not sure just removing this is sufficient. ?Presumably it's
> there for some reason - maybe it needs replacing with a call to
> dma_cookie_complete() to preserve existing behaviour?
>
That was anyway a redundant save in DMA_TERMINATE_ALL, so it should be ok.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-09  8:59   ` Shawn Guo
  -1 siblings, 0 replies; 66+ messages in thread
From: Shawn Guo @ 2012-03-09  8:59 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Vinod Koul,
	Barry Song, Dan Williams, linuxppc-dev, linux-arm-kernel

On Tue, Mar 06, 2012 at 10:33:21PM +0000, Russell King - ARM Linux wrote:
...
>  drivers/dma/imx-sdma.c                   |   23 ++------
...
>  drivers/dma/mxs-dma.c                    |   23 ++------

Tested-by: Shawn Guo <shawn.guo@linaro.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-09  8:59   ` Shawn Guo
  0 siblings, 0 replies; 66+ messages in thread
From: Shawn Guo @ 2012-03-09  8:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 06, 2012 at 10:33:21PM +0000, Russell King - ARM Linux wrote:
...
>  drivers/dma/imx-sdma.c                   |   23 ++------
...
>  drivers/dma/mxs-dma.c                    |   23 ++------

Tested-by: Shawn Guo <shawn.guo@linaro.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-07 13:54   ` Vinod Koul
@ 2012-03-12 16:11     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-12 16:11 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On Wed, Mar 07, 2012 at 07:24:26PM +0530, Vinod Koul wrote:
> On Tue, 2012-03-06 at 22:33 +0000, Russell King - ARM Linux wrote:
> > [v2 - more or less same description.  Including lakml in cc for the full
> > set]
> > 
> > This patch series cleans up the handling of cookies in DMA engine drivers.
> > This is done by providing a set of inline library functions for common
> > tasks:
> > 
> > - moving the 'last completed cookie' into struct dma_chan - everyone
> >   has this in their driver private channel data structure
> > 
> > - consolidate allocation of cookies to DMA descriptors
> > 
> > - common way to update 'last completed cookie' value
> > 
> > - standard way to implement tx_status callback and update the residue
> > 
> > - consolidate initialization of cookies
> > 
> > - update implementations differing from the majority of DMA engine drivers
> >   to behave the same as the majority implementation in respect of cookies
> > 
> > What this means is that we get to the point where all DMA engine drivers
> > will hand out cookie value '2' as the first, and incrementing cookie
> > values up to INT_MAX, returning to cookie '1' as the next cookie.
> > 
> > Think of this patch series as round 1...  I am hoping over time that more
> > code can be consolidated between the DMA engine drivers and end up with a
> > consistent way to handle various common themes in DMA engine hardware
> > (like physical channel<->peripheral request signal selection.)
> Thanks Russell,
> 
> I have tested this on atom today, and as expected works flawlessly :)
> After all acks, I can merge or these can go thru your tree with my Ack.
> Either way is okay.
> 
> I applied the v2 on a branch and also rebased on top of slave-dma.next.
> There were few conflicts in imx-dma.c. Sacha, Javier, pls see that merge
> is right.
> 
> This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am not
> able to connect to infradead.org, should be done when server is back.

Are you going to pick up Shawn Guo's tested-by for these patches, or are
we saying its too late for that now?

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-12 16:11     ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-12 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 07, 2012 at 07:24:26PM +0530, Vinod Koul wrote:
> On Tue, 2012-03-06 at 22:33 +0000, Russell King - ARM Linux wrote:
> > [v2 - more or less same description.  Including lakml in cc for the full
> > set]
> > 
> > This patch series cleans up the handling of cookies in DMA engine drivers.
> > This is done by providing a set of inline library functions for common
> > tasks:
> > 
> > - moving the 'last completed cookie' into struct dma_chan - everyone
> >   has this in their driver private channel data structure
> > 
> > - consolidate allocation of cookies to DMA descriptors
> > 
> > - common way to update 'last completed cookie' value
> > 
> > - standard way to implement tx_status callback and update the residue
> > 
> > - consolidate initialization of cookies
> > 
> > - update implementations differing from the majority of DMA engine drivers
> >   to behave the same as the majority implementation in respect of cookies
> > 
> > What this means is that we get to the point where all DMA engine drivers
> > will hand out cookie value '2' as the first, and incrementing cookie
> > values up to INT_MAX, returning to cookie '1' as the next cookie.
> > 
> > Think of this patch series as round 1...  I am hoping over time that more
> > code can be consolidated between the DMA engine drivers and end up with a
> > consistent way to handle various common themes in DMA engine hardware
> > (like physical channel<->peripheral request signal selection.)
> Thanks Russell,
> 
> I have tested this on atom today, and as expected works flawlessly :)
> After all acks, I can merge or these can go thru your tree with my Ack.
> Either way is okay.
> 
> I applied the v2 on a branch and also rebased on top of slave-dma.next.
> There were few conflicts in imx-dma.c. Sacha, Javier, pls see that merge
> is right.
> 
> This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am not
> able to connect to infradead.org, should be done when server is back.

Are you going to pick up Shawn Guo's tested-by for these patches, or are
we saying its too late for that now?

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-12 16:11     ` Russell King - ARM Linux
@ 2012-03-12 16:23       ` Vinod Koul
  -1 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-12 16:23 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On Mon, 2012-03-12 at 16:11 +0000, Russell King - ARM Linux wrote:
> On Wed, Mar 07, 2012 at 07:24:26PM +0530, Vinod Koul wrote:
> > On Tue, 2012-03-06 at 22:33 +0000, Russell King - ARM Linux wrote:
> > > [v2 - more or less same description.  Including lakml in cc for the full
> > > set]
> > > 
> > > This patch series cleans up the handling of cookies in DMA engine drivers.
> > > This is done by providing a set of inline library functions for common
> > > tasks:
> > > 
> > > - moving the 'last completed cookie' into struct dma_chan - everyone
> > >   has this in their driver private channel data structure
> > > 
> > > - consolidate allocation of cookies to DMA descriptors
> > > 
> > > - common way to update 'last completed cookie' value
> > > 
> > > - standard way to implement tx_status callback and update the residue
> > > 
> > > - consolidate initialization of cookies
> > > 
> > > - update implementations differing from the majority of DMA engine drivers
> > >   to behave the same as the majority implementation in respect of cookies
> > > 
> > > What this means is that we get to the point where all DMA engine drivers
> > > will hand out cookie value '2' as the first, and incrementing cookie
> > > values up to INT_MAX, returning to cookie '1' as the next cookie.
> > > 
> > > Think of this patch series as round 1...  I am hoping over time that more
> > > code can be consolidated between the DMA engine drivers and end up with a
> > > consistent way to handle various common themes in DMA engine hardware
> > > (like physical channel<->peripheral request signal selection.)
> > Thanks Russell,
> > 
> > I have tested this on atom today, and as expected works flawlessly :)
> > After all acks, I can merge or these can go thru your tree with my Ack.
> > Either way is okay.
> > 
> > I applied the v2 on a branch and also rebased on top of slave-dma.next.
> > There were few conflicts in imx-dma.c. Sacha, Javier, pls see that merge
> > is right.
> > 
> > This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am not
> > able to connect to infradead.org, should be done when server is back.
> 
> Are you going to pick up Shawn Guo's tested-by for these patches, or are
> we saying its too late for that now?
Sure, his and others we have received on this series.
Also, IIRC there was one fixup from Jassi on pl330?

I should be able to merge this tomorrow, if thats fine with you.



-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-12 16:23       ` Vinod Koul
  0 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-12 16:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2012-03-12 at 16:11 +0000, Russell King - ARM Linux wrote:
> On Wed, Mar 07, 2012 at 07:24:26PM +0530, Vinod Koul wrote:
> > On Tue, 2012-03-06 at 22:33 +0000, Russell King - ARM Linux wrote:
> > > [v2 - more or less same description.  Including lakml in cc for the full
> > > set]
> > > 
> > > This patch series cleans up the handling of cookies in DMA engine drivers.
> > > This is done by providing a set of inline library functions for common
> > > tasks:
> > > 
> > > - moving the 'last completed cookie' into struct dma_chan - everyone
> > >   has this in their driver private channel data structure
> > > 
> > > - consolidate allocation of cookies to DMA descriptors
> > > 
> > > - common way to update 'last completed cookie' value
> > > 
> > > - standard way to implement tx_status callback and update the residue
> > > 
> > > - consolidate initialization of cookies
> > > 
> > > - update implementations differing from the majority of DMA engine drivers
> > >   to behave the same as the majority implementation in respect of cookies
> > > 
> > > What this means is that we get to the point where all DMA engine drivers
> > > will hand out cookie value '2' as the first, and incrementing cookie
> > > values up to INT_MAX, returning to cookie '1' as the next cookie.
> > > 
> > > Think of this patch series as round 1...  I am hoping over time that more
> > > code can be consolidated between the DMA engine drivers and end up with a
> > > consistent way to handle various common themes in DMA engine hardware
> > > (like physical channel<->peripheral request signal selection.)
> > Thanks Russell,
> > 
> > I have tested this on atom today, and as expected works flawlessly :)
> > After all acks, I can merge or these can go thru your tree with my Ack.
> > Either way is okay.
> > 
> > I applied the v2 on a branch and also rebased on top of slave-dma.next.
> > There were few conflicts in imx-dma.c. Sacha, Javier, pls see that merge
> > is right.
> > 
> > This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am not
> > able to connect to infradead.org, should be done when server is back.
> 
> Are you going to pick up Shawn Guo's tested-by for these patches, or are
> we saying its too late for that now?
Sure, his and others we have received on this series.
Also, IIRC there was one fixup from Jassi on pl330?

I should be able to merge this tomorrow, if thats fine with you.



-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-12 16:23       ` Vinod Koul
@ 2012-03-13  8:40         ` Vinod Koul
  -1 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-13  8:40 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On Mon, 2012-03-12 at 21:53 +0530, Vinod Koul wrote:
> > > I applied the v2 on a branch and also rebased on top of
> slave-dma.next.
> > > There were few conflicts in imx-dma.c. Sacha, Javier, pls see that
> merge
> > > is right.
> > > 
> > > This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am
> not
> > > able to connect to infradead.org, should be done when server is
> back.
> > 
> > Are you going to pick up Shawn Guo's tested-by for these patches, or
> are
> > we saying its too late for that now?
> Sure, his and others we have received on this series.
> Also, IIRC there was one fixup from Jassi on pl330?
> 
> I should be able to merge this tomorrow, if thats fine with you. 
I have merged this to my next, but haven't pushed out yet. This is
available on branch next_cookie2_merge.
Also I got few (more than expected build failures) and a merge issue on
imx driver. Sascha, Russell can you see if fix on imx is right

Please see if the below patch is the right fix for build failures in
addition to one suggested by Jassi.

-------------------x-------------------------x----------------------

>From 949ff5b8d46b5e3435d21b2651ce3a2599208d44 Mon Sep 17 00:00:00 2001
From: Vinod Koul <vinod.koul@linux.intel.com>
Date: Tue, 13 Mar 2012 11:58:12 +0530
Subject: [PATCH] dmaengine: fix for cookie changes and merge

Fixed trivial issues in drivers:
	drivers/dma/imx-sdma.c
	drivers/dma/intel_mid_dma.c
	drivers/dma/ioat/dma_v3.c
	drivers/dma/iop-adma.c
	drivers/dma/sirf-dma.c
	drivers/dma/timb_dma.c

Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
---
 drivers/dma/imx-sdma.c      |    1 +
 drivers/dma/intel_mid_dma.c |    1 +
 drivers/dma/ioat/dma_v3.c   |    1 +
 drivers/dma/iop-adma.c      |    1 +
 drivers/dma/sirf-dma.c      |    2 ++
 drivers/dma/timb_dma.c      |    6 +-----
 6 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index ccfc7c4..81f9d57 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1127,6 +1127,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
 	struct sdma_engine *sdma = sdmac->sdma;
 
 	if (sdmac->status == DMA_IN_PROGRESS)
+		sdma_enable_channel(sdma, sdmac->channel);
 }
 
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index d599d96..2449812 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -477,6 +477,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 						dma_cookie_t cookie,
 						struct dma_tx_state *txstate)
 {
+	struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
 	enum dma_status ret;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 145eda2..2c4476c 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -61,6 +61,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/prefetch.h>
+#include "../dmaengine.h"
 #include "registers.h"
 #include "hw.h"
 #include "dma.h"
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 1f3a703..4499f88 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -894,6 +894,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 					struct dma_tx_state *txstate)
 {
 	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
+	int ret;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS)
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index a2cde85..45ba352 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -18,6 +18,8 @@
 #include <linux/of_platform.h>
 #include <linux/sirfsoc_dma.h>
 
+#include "dmaengine.h"
+
 #define SIRFSOC_DMA_DESCRIPTORS                 16
 #define SIRFSOC_DMA_CHANNELS                    16
 
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 7805996..d408c22 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -510,17 +510,13 @@ static void td_free_chan_resources(struct dma_chan *chan)
 static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 				    struct dma_tx_state *txstate)
 {
-	struct timb_dma_chan *td_chan =
-		container_of(chan, struct timb_dma_chan, chan);
 	enum dma_status ret;
 
 	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
 
 	ret = dma_cookie_status(chan, cookie, txstate);
 
-	dev_dbg(chan2dev(chan),
-		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
-		__func__, ret, last_complete, last_used);
+	dev_dbg(chan2dev(chan), "%s: exit, ret: %d\n", 	__func__, ret);
 
 	return ret;
 }
-- 
1.7.0.4




-- 
~Vinod

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-13  8:40         ` Vinod Koul
  0 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-13  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2012-03-12 at 21:53 +0530, Vinod Koul wrote:
> > > I applied the v2 on a branch and also rebased on top of
> slave-dma.next.
> > > There were few conflicts in imx-dma.c. Sacha, Javier, pls see that
> merge
> > > is right.
> > > 
> > > This branch (rmk_cookie_fixes2_rebased) is not yet pushed, as I am
> not
> > > able to connect to infradead.org, should be done when server is
> back.
> > 
> > Are you going to pick up Shawn Guo's tested-by for these patches, or
> are
> > we saying its too late for that now?
> Sure, his and others we have received on this series.
> Also, IIRC there was one fixup from Jassi on pl330?
> 
> I should be able to merge this tomorrow, if thats fine with you. 
I have merged this to my next, but haven't pushed out yet. This is
available on branch next_cookie2_merge.
Also I got few (more than expected build failures) and a merge issue on
imx driver. Sascha, Russell can you see if fix on imx is right

Please see if the below patch is the right fix for build failures in
addition to one suggested by Jassi.

-------------------x-------------------------x----------------------

>From 949ff5b8d46b5e3435d21b2651ce3a2599208d44 Mon Sep 17 00:00:00 2001
From: Vinod Koul <vinod.koul@linux.intel.com>
Date: Tue, 13 Mar 2012 11:58:12 +0530
Subject: [PATCH] dmaengine: fix for cookie changes and merge

Fixed trivial issues in drivers:
	drivers/dma/imx-sdma.c
	drivers/dma/intel_mid_dma.c
	drivers/dma/ioat/dma_v3.c
	drivers/dma/iop-adma.c
	drivers/dma/sirf-dma.c
	drivers/dma/timb_dma.c

Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
---
 drivers/dma/imx-sdma.c      |    1 +
 drivers/dma/intel_mid_dma.c |    1 +
 drivers/dma/ioat/dma_v3.c   |    1 +
 drivers/dma/iop-adma.c      |    1 +
 drivers/dma/sirf-dma.c      |    2 ++
 drivers/dma/timb_dma.c      |    6 +-----
 6 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index ccfc7c4..81f9d57 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1127,6 +1127,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
 	struct sdma_engine *sdma = sdmac->sdma;
 
 	if (sdmac->status == DMA_IN_PROGRESS)
+		sdma_enable_channel(sdma, sdmac->channel);
 }
 
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index d599d96..2449812 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -477,6 +477,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
 						dma_cookie_t cookie,
 						struct dma_tx_state *txstate)
 {
+	struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
 	enum dma_status ret;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 145eda2..2c4476c 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -61,6 +61,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/prefetch.h>
+#include "../dmaengine.h"
 #include "registers.h"
 #include "hw.h"
 #include "dma.h"
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 1f3a703..4499f88 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -894,6 +894,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
 					struct dma_tx_state *txstate)
 {
 	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
+	int ret;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
 	if (ret == DMA_SUCCESS)
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index a2cde85..45ba352 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -18,6 +18,8 @@
 #include <linux/of_platform.h>
 #include <linux/sirfsoc_dma.h>
 
+#include "dmaengine.h"
+
 #define SIRFSOC_DMA_DESCRIPTORS                 16
 #define SIRFSOC_DMA_CHANNELS                    16
 
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 7805996..d408c22 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -510,17 +510,13 @@ static void td_free_chan_resources(struct dma_chan *chan)
 static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 				    struct dma_tx_state *txstate)
 {
-	struct timb_dma_chan *td_chan =
-		container_of(chan, struct timb_dma_chan, chan);
 	enum dma_status ret;
 
 	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
 
 	ret = dma_cookie_status(chan, cookie, txstate);
 
-	dev_dbg(chan2dev(chan),
-		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
-		__func__, ret, last_complete, last_used);
+	dev_dbg(chan2dev(chan), "%s: exit, ret: %d\n", 	__func__, ret);
 
 	return ret;
 }
-- 
1.7.0.4




-- 
~Vinod

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-06 22:33 ` Russell King - ARM Linux
@ 2012-03-13 11:45   ` Nicolas Ferre
  -1 siblings, 0 replies; 66+ messages in thread
From: Nicolas Ferre @ 2012-03-13 11:45 UTC (permalink / raw)
  To: Russell King - ARM Linux, Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On 03/06/2012 11:33 PM, Russell King - ARM Linux :
> [v2 - more or less same description.  Including lakml in cc for the full
> set]
> 
> This patch series cleans up the handling of cookies in DMA engine drivers.
> This is done by providing a set of inline library functions for common
> tasks:
> 
> - moving the 'last completed cookie' into struct dma_chan - everyone
>   has this in their driver private channel data structure
> 
> - consolidate allocation of cookies to DMA descriptors
> 
> - common way to update 'last completed cookie' value
> 
> - standard way to implement tx_status callback and update the residue
> 
> - consolidate initialization of cookies
> 
> - update implementations differing from the majority of DMA engine drivers
>   to behave the same as the majority implementation in respect of cookies
> 
> What this means is that we get to the point where all DMA engine drivers
> will hand out cookie value '2' as the first, and incrementing cookie
> values up to INT_MAX, returning to cookie '1' as the next cookie.
> 
> Think of this patch series as round 1...  I am hoping over time that more
> code can be consolidated between the DMA engine drivers and end up with a
> consistent way to handle various common themes in DMA engine hardware
> (like physical channel<->peripheral request signal selection.)
> 
> Overall, the diffstat looks like this:
> 
>  arch/arm/include/asm/hardware/iop_adma.h |    2 -
>  drivers/dma/amba-pl08x.c                 |   38 ++++---------
>  drivers/dma/at_hdmac.c                   |   48 ++++------------
>  drivers/dma/at_hdmac_regs.h              |    2 -

For at_hdmac Atmel DMA driver:

Tested-by: Nicolas Ferre <nicolas.ferre@atmel.com>

Thanks a lot Russell.

Best regards,
-- 
Nicolas Ferre

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-13 11:45   ` Nicolas Ferre
  0 siblings, 0 replies; 66+ messages in thread
From: Nicolas Ferre @ 2012-03-13 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/06/2012 11:33 PM, Russell King - ARM Linux :
> [v2 - more or less same description.  Including lakml in cc for the full
> set]
> 
> This patch series cleans up the handling of cookies in DMA engine drivers.
> This is done by providing a set of inline library functions for common
> tasks:
> 
> - moving the 'last completed cookie' into struct dma_chan - everyone
>   has this in their driver private channel data structure
> 
> - consolidate allocation of cookies to DMA descriptors
> 
> - common way to update 'last completed cookie' value
> 
> - standard way to implement tx_status callback and update the residue
> 
> - consolidate initialization of cookies
> 
> - update implementations differing from the majority of DMA engine drivers
>   to behave the same as the majority implementation in respect of cookies
> 
> What this means is that we get to the point where all DMA engine drivers
> will hand out cookie value '2' as the first, and incrementing cookie
> values up to INT_MAX, returning to cookie '1' as the next cookie.
> 
> Think of this patch series as round 1...  I am hoping over time that more
> code can be consolidated between the DMA engine drivers and end up with a
> consistent way to handle various common themes in DMA engine hardware
> (like physical channel<->peripheral request signal selection.)
> 
> Overall, the diffstat looks like this:
> 
>  arch/arm/include/asm/hardware/iop_adma.h |    2 -
>  drivers/dma/amba-pl08x.c                 |   38 ++++---------
>  drivers/dma/at_hdmac.c                   |   48 ++++------------
>  drivers/dma/at_hdmac_regs.h              |    2 -

For at_hdmac Atmel DMA driver:

Tested-by: Nicolas Ferre <nicolas.ferre@atmel.com>

Thanks a lot Russell.

Best regards,
-- 
Nicolas Ferre

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-13  8:40         ` Vinod Koul
@ 2012-03-13 12:31           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-13 12:31 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On Tue, Mar 13, 2012 at 02:10:36PM +0530, Vinod Koul wrote:
> Please see if the below patch is the right fix for build failures in
> addition to one suggested by Jassi.

I'm not sure that Jassi's solution is correct - and I'm wondering whether
any of the DMA engine drivers do the right thing when transfers are
terminated.  Is it right for the DMA status function to return IN_PROGRESS
for a previously submitted cookie which has been terminated?

I can see two answers to that, both equally valid:

1. It allows you to find out exactly where the DMA engine got to before
   the transfer was terminated, and therefore recover from the termination
   if you wish to.

2. Returning in-progress when a cookie will never be completed is
   misleading, and could be misinterpreted by users of the tx_status
   function, especially if they are waiting for a particular transaction
   to complete.

Maybe we need to introduce a DMA_TERMINATED status?

> -------------------x-------------------------x----------------------
> 
> >From 949ff5b8d46b5e3435d21b2651ce3a2599208d44 Mon Sep 17 00:00:00 2001
> From: Vinod Koul <vinod.koul@linux.intel.com>
> Date: Tue, 13 Mar 2012 11:58:12 +0530
> Subject: [PATCH] dmaengine: fix for cookie changes and merge
> 
> Fixed trivial issues in drivers:
> 	drivers/dma/imx-sdma.c
> 	drivers/dma/intel_mid_dma.c
> 	drivers/dma/ioat/dma_v3.c
> 	drivers/dma/iop-adma.c
> 	drivers/dma/sirf-dma.c
> 	drivers/dma/timb_dma.c
> 
> Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
> ---
>  drivers/dma/imx-sdma.c      |    1 +
>  drivers/dma/intel_mid_dma.c |    1 +
>  drivers/dma/ioat/dma_v3.c   |    1 +
>  drivers/dma/iop-adma.c      |    1 +
>  drivers/dma/sirf-dma.c      |    2 ++
>  drivers/dma/timb_dma.c      |    6 +-----
>  6 files changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index ccfc7c4..81f9d57 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -1127,6 +1127,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
>  	struct sdma_engine *sdma = sdmac->sdma;
>  
>  	if (sdmac->status == DMA_IN_PROGRESS)
> +		sdma_enable_channel(sdma, sdmac->channel);
>  }
>  
>  #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34

This looks like a merge conflict resolution.  I don't see this being
caused by my patches as I haven't touched this function.

> diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
> index d599d96..2449812 100644
> --- a/drivers/dma/intel_mid_dma.c
> +++ b/drivers/dma/intel_mid_dma.c
> @@ -477,6 +477,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
>  						dma_cookie_t cookie,
>  						struct dma_tx_state *txstate)
>  {
> +	struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
>  	enum dma_status ret;
>  
>  	ret = dma_cookie_status(chan, cookie, txstate);

Ditto (my patches don't introduce new this new midc, nor do they remove
that line.)

> diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
> index 145eda2..2c4476c 100644
> --- a/drivers/dma/ioat/dma_v3.c
> +++ b/drivers/dma/ioat/dma_v3.c
> @@ -61,6 +61,7 @@
>  #include <linux/dmaengine.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/prefetch.h>
> +#include "../dmaengine.h"
>  #include "registers.h"
>  #include "hw.h"
>  #include "dma.h"
> diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
> index 1f3a703..4499f88 100644
> --- a/drivers/dma/iop-adma.c
> +++ b/drivers/dma/iop-adma.c
> @@ -894,6 +894,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
>  					struct dma_tx_state *txstate)
>  {
>  	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
> +	int ret;

This was "enum dma_status ret;" before I accidentally removed it.  It
probably should be again, rather than an int.

>  
>  	ret = dma_cookie_status(chan, cookie, txstate);
>  	if (ret == DMA_SUCCESS)
> diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
> index a2cde85..45ba352 100644
> --- a/drivers/dma/sirf-dma.c
> +++ b/drivers/dma/sirf-dma.c
> @@ -18,6 +18,8 @@
>  #include <linux/of_platform.h>
>  #include <linux/sirfsoc_dma.h>
>  
> +#include "dmaengine.h"
> +
>  #define SIRFSOC_DMA_DESCRIPTORS                 16
>  #define SIRFSOC_DMA_CHANNELS                    16
>  

Hmm, guess that's what happens when old patches are brought forward and
things from the original series are forgotten...

> diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
> index 7805996..d408c22 100644
> --- a/drivers/dma/timb_dma.c
> +++ b/drivers/dma/timb_dma.c
> @@ -510,17 +510,13 @@ static void td_free_chan_resources(struct dma_chan *chan)
>  static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
>  				    struct dma_tx_state *txstate)
>  {
> -	struct timb_dma_chan *td_chan =
> -		container_of(chan, struct timb_dma_chan, chan);
>  	enum dma_status ret;
>  
>  	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
>  
>  	ret = dma_cookie_status(chan, cookie, txstate);
>  
> -	dev_dbg(chan2dev(chan),
> -		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
> -		__func__, ret, last_complete, last_used);
> +	dev_dbg(chan2dev(chan), "%s: exit, ret: %d\n", 	__func__, ret);
>  
>  	return ret;
>  }
> -- 
> 1.7.0.4
> 
> 
> 
> 
> -- 
> ~Vinod
> 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-13 12:31           ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-03-13 12:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 13, 2012 at 02:10:36PM +0530, Vinod Koul wrote:
> Please see if the below patch is the right fix for build failures in
> addition to one suggested by Jassi.

I'm not sure that Jassi's solution is correct - and I'm wondering whether
any of the DMA engine drivers do the right thing when transfers are
terminated.  Is it right for the DMA status function to return IN_PROGRESS
for a previously submitted cookie which has been terminated?

I can see two answers to that, both equally valid:

1. It allows you to find out exactly where the DMA engine got to before
   the transfer was terminated, and therefore recover from the termination
   if you wish to.

2. Returning in-progress when a cookie will never be completed is
   misleading, and could be misinterpreted by users of the tx_status
   function, especially if they are waiting for a particular transaction
   to complete.

Maybe we need to introduce a DMA_TERMINATED status?

> -------------------x-------------------------x----------------------
> 
> >From 949ff5b8d46b5e3435d21b2651ce3a2599208d44 Mon Sep 17 00:00:00 2001
> From: Vinod Koul <vinod.koul@linux.intel.com>
> Date: Tue, 13 Mar 2012 11:58:12 +0530
> Subject: [PATCH] dmaengine: fix for cookie changes and merge
> 
> Fixed trivial issues in drivers:
> 	drivers/dma/imx-sdma.c
> 	drivers/dma/intel_mid_dma.c
> 	drivers/dma/ioat/dma_v3.c
> 	drivers/dma/iop-adma.c
> 	drivers/dma/sirf-dma.c
> 	drivers/dma/timb_dma.c
> 
> Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
> ---
>  drivers/dma/imx-sdma.c      |    1 +
>  drivers/dma/intel_mid_dma.c |    1 +
>  drivers/dma/ioat/dma_v3.c   |    1 +
>  drivers/dma/iop-adma.c      |    1 +
>  drivers/dma/sirf-dma.c      |    2 ++
>  drivers/dma/timb_dma.c      |    6 +-----
>  6 files changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index ccfc7c4..81f9d57 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -1127,6 +1127,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
>  	struct sdma_engine *sdma = sdmac->sdma;
>  
>  	if (sdmac->status == DMA_IN_PROGRESS)
> +		sdma_enable_channel(sdma, sdmac->channel);
>  }
>  
>  #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34

This looks like a merge conflict resolution.  I don't see this being
caused by my patches as I haven't touched this function.

> diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
> index d599d96..2449812 100644
> --- a/drivers/dma/intel_mid_dma.c
> +++ b/drivers/dma/intel_mid_dma.c
> @@ -477,6 +477,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
>  						dma_cookie_t cookie,
>  						struct dma_tx_state *txstate)
>  {
> +	struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
>  	enum dma_status ret;
>  
>  	ret = dma_cookie_status(chan, cookie, txstate);

Ditto (my patches don't introduce new this new midc, nor do they remove
that line.)

> diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
> index 145eda2..2c4476c 100644
> --- a/drivers/dma/ioat/dma_v3.c
> +++ b/drivers/dma/ioat/dma_v3.c
> @@ -61,6 +61,7 @@
>  #include <linux/dmaengine.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/prefetch.h>
> +#include "../dmaengine.h"
>  #include "registers.h"
>  #include "hw.h"
>  #include "dma.h"
> diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
> index 1f3a703..4499f88 100644
> --- a/drivers/dma/iop-adma.c
> +++ b/drivers/dma/iop-adma.c
> @@ -894,6 +894,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
>  					struct dma_tx_state *txstate)
>  {
>  	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
> +	int ret;

This was "enum dma_status ret;" before I accidentally removed it.  It
probably should be again, rather than an int.

>  
>  	ret = dma_cookie_status(chan, cookie, txstate);
>  	if (ret == DMA_SUCCESS)
> diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
> index a2cde85..45ba352 100644
> --- a/drivers/dma/sirf-dma.c
> +++ b/drivers/dma/sirf-dma.c
> @@ -18,6 +18,8 @@
>  #include <linux/of_platform.h>
>  #include <linux/sirfsoc_dma.h>
>  
> +#include "dmaengine.h"
> +
>  #define SIRFSOC_DMA_DESCRIPTORS                 16
>  #define SIRFSOC_DMA_CHANNELS                    16
>  

Hmm, guess that's what happens when old patches are brought forward and
things from the original series are forgotten...

> diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
> index 7805996..d408c22 100644
> --- a/drivers/dma/timb_dma.c
> +++ b/drivers/dma/timb_dma.c
> @@ -510,17 +510,13 @@ static void td_free_chan_resources(struct dma_chan *chan)
>  static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
>  				    struct dma_tx_state *txstate)
>  {
> -	struct timb_dma_chan *td_chan =
> -		container_of(chan, struct timb_dma_chan, chan);
>  	enum dma_status ret;
>  
>  	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
>  
>  	ret = dma_cookie_status(chan, cookie, txstate);
>  
> -	dev_dbg(chan2dev(chan),
> -		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
> -		__func__, ret, last_complete, last_used);
> +	dev_dbg(chan2dev(chan), "%s: exit, ret: %d\n", 	__func__, ret);
>  
>  	return ret;
>  }
> -- 
> 1.7.0.4
> 
> 
> 
> 
> -- 
> ~Vinod
> 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-13 12:31           ` Russell King - ARM Linux
@ 2012-03-13 14:38             ` Vinod Koul
  -1 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-13 14:38 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On Tue, 2012-03-13 at 12:31 +0000, Russell King - ARM Linux wrote:
> On Tue, Mar 13, 2012 at 02:10:36PM +0530, Vinod Koul wrote:
> > Please see if the below patch is the right fix for build failures in
> > addition to one suggested by Jassi.
> 
> I'm not sure that Jassi's solution is correct - and I'm wondering whether
> any of the DMA engine drivers do the right thing when transfers are
> terminated.  Is it right for the DMA status function to return IN_PROGRESS
> for a previously submitted cookie which has been terminated?
> 
> I can see two answers to that, both equally valid:
> 
> 1. It allows you to find out exactly where the DMA engine got to before
>    the transfer was terminated, and therefore recover from the termination
>    if you wish to.
> 
> 2. Returning in-progress when a cookie will never be completed is
>    misleading, and could be misinterpreted by users of the tx_status
>    function, especially if they are waiting for a particular transaction
>    to complete.
> 
> Maybe we need to introduce a DMA_TERMINATED status?
I would agree with you that DMA_TERMINATED seems to be correct option.
IN_PROGRESS would certainly confuse... 
I will drop Jassi's fix from this branch. Care to send the patch?
> 
> > -------------------x-------------------------x----------------------
> > 
> > >From 949ff5b8d46b5e3435d21b2651ce3a2599208d44 Mon Sep 17 00:00:00 2001
> > From: Vinod Koul <vinod.koul@linux.intel.com>
> > Date: Tue, 13 Mar 2012 11:58:12 +0530
> > Subject: [PATCH] dmaengine: fix for cookie changes and merge
> > 
> > Fixed trivial issues in drivers:
> > 	drivers/dma/imx-sdma.c
> > 	drivers/dma/intel_mid_dma.c
> > 	drivers/dma/ioat/dma_v3.c
> > 	drivers/dma/iop-adma.c
> > 	drivers/dma/sirf-dma.c
> > 	drivers/dma/timb_dma.c
> > 
> > Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
> > ---
> >  drivers/dma/imx-sdma.c      |    1 +
> >  drivers/dma/intel_mid_dma.c |    1 +
> >  drivers/dma/ioat/dma_v3.c   |    1 +
> >  drivers/dma/iop-adma.c      |    1 +
> >  drivers/dma/sirf-dma.c      |    2 ++
> >  drivers/dma/timb_dma.c      |    6 +-----
> >  6 files changed, 7 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> > index ccfc7c4..81f9d57 100644
> > --- a/drivers/dma/imx-sdma.c
> > +++ b/drivers/dma/imx-sdma.c
> > @@ -1127,6 +1127,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
> >  	struct sdma_engine *sdma = sdmac->sdma;
> >  
> >  	if (sdmac->status == DMA_IN_PROGRESS)
> > +		sdma_enable_channel(sdma, sdmac->channel);
> >  }
> >  
> >  #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34
> 
> This looks like a merge conflict resolution.  I don't see this being
> caused by my patches as I haven't touched this function.
> 
> > diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
> > index d599d96..2449812 100644
> > --- a/drivers/dma/intel_mid_dma.c
> > +++ b/drivers/dma/intel_mid_dma.c
> > @@ -477,6 +477,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
> >  						dma_cookie_t cookie,
> >  						struct dma_tx_state *txstate)
> >  {
> > +	struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
> >  	enum dma_status ret;
> >  
> >  	ret = dma_cookie_status(chan, cookie, txstate);
> 
> Ditto (my patches don't introduce new this new midc, nor do they remove
> that line.)
> 
> > diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
> > index 145eda2..2c4476c 100644
> > --- a/drivers/dma/ioat/dma_v3.c
> > +++ b/drivers/dma/ioat/dma_v3.c
> > @@ -61,6 +61,7 @@
> >  #include <linux/dmaengine.h>
> >  #include <linux/dma-mapping.h>
> >  #include <linux/prefetch.h>
> > +#include "../dmaengine.h"
> >  #include "registers.h"
> >  #include "hw.h"
> >  #include "dma.h"
> > diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
> > index 1f3a703..4499f88 100644
> > --- a/drivers/dma/iop-adma.c
> > +++ b/drivers/dma/iop-adma.c
> > @@ -894,6 +894,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
> >  					struct dma_tx_state *txstate)
> >  {
> >  	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
> > +	int ret;
> 
> This was "enum dma_status ret;" before I accidentally removed it.  It
> probably should be again, rather than an int.
> 
> >  
> >  	ret = dma_cookie_status(chan, cookie, txstate);
> >  	if (ret == DMA_SUCCESS)
> > diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
> > index a2cde85..45ba352 100644
> > --- a/drivers/dma/sirf-dma.c
> > +++ b/drivers/dma/sirf-dma.c
> > @@ -18,6 +18,8 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/sirfsoc_dma.h>
> >  
> > +#include "dmaengine.h"
> > +
> >  #define SIRFSOC_DMA_DESCRIPTORS                 16
> >  #define SIRFSOC_DMA_CHANNELS                    16
> >  
> 
> Hmm, guess that's what happens when old patches are brought forward and
> things from the original series are forgotten...
> 
> > diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
> > index 7805996..d408c22 100644
> > --- a/drivers/dma/timb_dma.c
> > +++ b/drivers/dma/timb_dma.c
> > @@ -510,17 +510,13 @@ static void td_free_chan_resources(struct dma_chan *chan)
> >  static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
> >  				    struct dma_tx_state *txstate)
> >  {
> > -	struct timb_dma_chan *td_chan =
> > -		container_of(chan, struct timb_dma_chan, chan);
> >  	enum dma_status ret;
> >  
> >  	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
> >  
> >  	ret = dma_cookie_status(chan, cookie, txstate);
> >  
> > -	dev_dbg(chan2dev(chan),
> > -		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
> > -		__func__, ret, last_complete, last_used);
> > +	dev_dbg(chan2dev(chan), "%s: exit, ret: %d\n", 	__func__, ret);
> >  
> >  	return ret;
> >  }
> > -- 
> > 1.7.0.4
> > 
> > 
> > 
> > 
> > -- 
> > ~Vinod
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-13 14:38             ` Vinod Koul
  0 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-13 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-03-13 at 12:31 +0000, Russell King - ARM Linux wrote:
> On Tue, Mar 13, 2012 at 02:10:36PM +0530, Vinod Koul wrote:
> > Please see if the below patch is the right fix for build failures in
> > addition to one suggested by Jassi.
> 
> I'm not sure that Jassi's solution is correct - and I'm wondering whether
> any of the DMA engine drivers do the right thing when transfers are
> terminated.  Is it right for the DMA status function to return IN_PROGRESS
> for a previously submitted cookie which has been terminated?
> 
> I can see two answers to that, both equally valid:
> 
> 1. It allows you to find out exactly where the DMA engine got to before
>    the transfer was terminated, and therefore recover from the termination
>    if you wish to.
> 
> 2. Returning in-progress when a cookie will never be completed is
>    misleading, and could be misinterpreted by users of the tx_status
>    function, especially if they are waiting for a particular transaction
>    to complete.
> 
> Maybe we need to introduce a DMA_TERMINATED status?
I would agree with you that DMA_TERMINATED seems to be correct option.
IN_PROGRESS would certainly confuse... 
I will drop Jassi's fix from this branch. Care to send the patch?
> 
> > -------------------x-------------------------x----------------------
> > 
> > >From 949ff5b8d46b5e3435d21b2651ce3a2599208d44 Mon Sep 17 00:00:00 2001
> > From: Vinod Koul <vinod.koul@linux.intel.com>
> > Date: Tue, 13 Mar 2012 11:58:12 +0530
> > Subject: [PATCH] dmaengine: fix for cookie changes and merge
> > 
> > Fixed trivial issues in drivers:
> > 	drivers/dma/imx-sdma.c
> > 	drivers/dma/intel_mid_dma.c
> > 	drivers/dma/ioat/dma_v3.c
> > 	drivers/dma/iop-adma.c
> > 	drivers/dma/sirf-dma.c
> > 	drivers/dma/timb_dma.c
> > 
> > Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
> > ---
> >  drivers/dma/imx-sdma.c      |    1 +
> >  drivers/dma/intel_mid_dma.c |    1 +
> >  drivers/dma/ioat/dma_v3.c   |    1 +
> >  drivers/dma/iop-adma.c      |    1 +
> >  drivers/dma/sirf-dma.c      |    2 ++
> >  drivers/dma/timb_dma.c      |    6 +-----
> >  6 files changed, 7 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> > index ccfc7c4..81f9d57 100644
> > --- a/drivers/dma/imx-sdma.c
> > +++ b/drivers/dma/imx-sdma.c
> > @@ -1127,6 +1127,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
> >  	struct sdma_engine *sdma = sdmac->sdma;
> >  
> >  	if (sdmac->status == DMA_IN_PROGRESS)
> > +		sdma_enable_channel(sdma, sdmac->channel);
> >  }
> >  
> >  #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34
> 
> This looks like a merge conflict resolution.  I don't see this being
> caused by my patches as I haven't touched this function.
> 
> > diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
> > index d599d96..2449812 100644
> > --- a/drivers/dma/intel_mid_dma.c
> > +++ b/drivers/dma/intel_mid_dma.c
> > @@ -477,6 +477,7 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
> >  						dma_cookie_t cookie,
> >  						struct dma_tx_state *txstate)
> >  {
> > +	struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
> >  	enum dma_status ret;
> >  
> >  	ret = dma_cookie_status(chan, cookie, txstate);
> 
> Ditto (my patches don't introduce new this new midc, nor do they remove
> that line.)
> 
> > diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
> > index 145eda2..2c4476c 100644
> > --- a/drivers/dma/ioat/dma_v3.c
> > +++ b/drivers/dma/ioat/dma_v3.c
> > @@ -61,6 +61,7 @@
> >  #include <linux/dmaengine.h>
> >  #include <linux/dma-mapping.h>
> >  #include <linux/prefetch.h>
> > +#include "../dmaengine.h"
> >  #include "registers.h"
> >  #include "hw.h"
> >  #include "dma.h"
> > diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
> > index 1f3a703..4499f88 100644
> > --- a/drivers/dma/iop-adma.c
> > +++ b/drivers/dma/iop-adma.c
> > @@ -894,6 +894,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan,
> >  					struct dma_tx_state *txstate)
> >  {
> >  	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
> > +	int ret;
> 
> This was "enum dma_status ret;" before I accidentally removed it.  It
> probably should be again, rather than an int.
> 
> >  
> >  	ret = dma_cookie_status(chan, cookie, txstate);
> >  	if (ret == DMA_SUCCESS)
> > diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
> > index a2cde85..45ba352 100644
> > --- a/drivers/dma/sirf-dma.c
> > +++ b/drivers/dma/sirf-dma.c
> > @@ -18,6 +18,8 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/sirfsoc_dma.h>
> >  
> > +#include "dmaengine.h"
> > +
> >  #define SIRFSOC_DMA_DESCRIPTORS                 16
> >  #define SIRFSOC_DMA_CHANNELS                    16
> >  
> 
> Hmm, guess that's what happens when old patches are brought forward and
> things from the original series are forgotten...
> 
> > diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
> > index 7805996..d408c22 100644
> > --- a/drivers/dma/timb_dma.c
> > +++ b/drivers/dma/timb_dma.c
> > @@ -510,17 +510,13 @@ static void td_free_chan_resources(struct dma_chan *chan)
> >  static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
> >  				    struct dma_tx_state *txstate)
> >  {
> > -	struct timb_dma_chan *td_chan =
> > -		container_of(chan, struct timb_dma_chan, chan);
> >  	enum dma_status ret;
> >  
> >  	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
> >  
> >  	ret = dma_cookie_status(chan, cookie, txstate);
> >  
> > -	dev_dbg(chan2dev(chan),
> > -		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
> > -		__func__, ret, last_complete, last_used);
> > +	dev_dbg(chan2dev(chan), "%s: exit, ret: %d\n", 	__func__, ret);
> >  
> >  	return ret;
> >  }
> > -- 
> > 1.7.0.4
> > 
> > 
> > 
> > 
> > -- 
> > ~Vinod
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 0/9] DMA engine cookie handling cleanups
  2012-03-13 14:38             ` Vinod Koul
@ 2012-03-19 14:35               ` Vinod Koul
  -1 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-19 14:35 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Stephen Warren, Linus Walleij, Srinidhi Kasagar, Barry Song,
	Dan Williams, linuxppc-dev, linux-arm-kernel

On Tue, 2012-03-13 at 20:08 +0530, Vinod Koul wrote:
> On Tue, 2012-03-13 at 12:31 +0000, Russell King - ARM Linux wrote:
> > On Tue, Mar 13, 2012 at 02:10:36PM +0530, Vinod Koul wrote:
> > > Please see if the below patch is the right fix for build failures in
> > > addition to one suggested by Jassi.
> > 
> > I'm not sure that Jassi's solution is correct - and I'm wondering whether
> > any of the DMA engine drivers do the right thing when transfers are
> > terminated.  Is it right for the DMA status function to return IN_PROGRESS
> > for a previously submitted cookie which has been terminated?
> > 
> > I can see two answers to that, both equally valid:
> > 
> > 1. It allows you to find out exactly where the DMA engine got to before
> >    the transfer was terminated, and therefore recover from the termination
> >    if you wish to.
> > 
> > 2. Returning in-progress when a cookie will never be completed is
> >    misleading, and could be misinterpreted by users of the tx_status
> >    function, especially if they are waiting for a particular transaction
> >    to complete.
> > 
> > Maybe we need to introduce a DMA_TERMINATED status?
> I would agree with you that DMA_TERMINATED seems to be correct option.
> IN_PROGRESS would certainly confuse... 
> I will drop Jassi's fix from this branch. Care to send the patch? 

Even after adding such a state in dmaengine for DMA_TERMINATED, it
doesn't make much sense. In TERMINATE_ALL we do not update the
chan->complete value. So after client has terminated the channel it can
easily test to see if cookie is completed (before terminate will return
SUCCESS) or aborted (will return DMA_IN_PROGRESS)
So at present I am leaning on 1 :)

If I don't hear any opposition I will merge this (with Jassi's fix) and
then send pull to Linus

-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 0/9] DMA engine cookie handling cleanups
@ 2012-03-19 14:35               ` Vinod Koul
  0 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-03-19 14:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-03-13 at 20:08 +0530, Vinod Koul wrote:
> On Tue, 2012-03-13 at 12:31 +0000, Russell King - ARM Linux wrote:
> > On Tue, Mar 13, 2012 at 02:10:36PM +0530, Vinod Koul wrote:
> > > Please see if the below patch is the right fix for build failures in
> > > addition to one suggested by Jassi.
> > 
> > I'm not sure that Jassi's solution is correct - and I'm wondering whether
> > any of the DMA engine drivers do the right thing when transfers are
> > terminated.  Is it right for the DMA status function to return IN_PROGRESS
> > for a previously submitted cookie which has been terminated?
> > 
> > I can see two answers to that, both equally valid:
> > 
> > 1. It allows you to find out exactly where the DMA engine got to before
> >    the transfer was terminated, and therefore recover from the termination
> >    if you wish to.
> > 
> > 2. Returning in-progress when a cookie will never be completed is
> >    misleading, and could be misinterpreted by users of the tx_status
> >    function, especially if they are waiting for a particular transaction
> >    to complete.
> > 
> > Maybe we need to introduce a DMA_TERMINATED status?
> I would agree with you that DMA_TERMINATED seems to be correct option.
> IN_PROGRESS would certainly confuse... 
> I will drop Jassi's fix from this branch. Care to send the patch? 

Even after adding such a state in dmaengine for DMA_TERMINATED, it
doesn't make much sense. In TERMINATE_ALL we do not update the
chan->complete value. So after client has terminated the channel it can
easily test to see if cookie is completed (before terminate will return
SUCCESS) or aborted (will return DMA_IN_PROGRESS)
So at present I am leaning on 1 :)

If I don't hear any opposition I will merge this (with Jassi's fix) and
then send pull to Linus

-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* RE: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
  2012-03-06 22:35   ` Russell King - ARM Linux
@ 2012-04-23  9:40     ` Boojin Kim
  -1 siblings, 0 replies; 66+ messages in thread
From: Boojin Kim @ 2012-04-23  9:40 UTC (permalink / raw)
  To: 'Russell King - ARM Linux', 'Dan Williams',
	'Vinod Koul'
  Cc: 'Stephen Warren', 'Linus Walleij',
	'Srinidhi Kasagar',
	linuxppc-dev, linux-arm-kernel

Russell King - ARM Linux wrote:
> Sent: Wednesday, March 07, 2012 7:35 AM
> To: Dan Williams; Vinod Koul
> Cc: Stephen Warren; Linus Walleij; Srinidhi Kasagar; Li Yang; linuxppc-dev@lists.ozlabs.org;
> linux-arm-kernel@lists.infradead.org
> Subject: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
>
> Provide a common function to do the cookie mechanics for completing
> a DMA descriptor.
Dear Russell,
I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
Kernel BUG occurs during DMA transfer with DMA cyclic mode.
This patch makes the cookies into zero. But, cookies should be kept during cyclic mode
because cyclic mode re-uses the cookies.
So, Error occurs on "BUG_ON(tx->cookie < DMA_MIN_COOKIE)" lines on dma_cookie_complete().
Please see following error.
------------[ cut here ]------------
kernel BUG at drivers/dma/dmaengine.h:53!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0    Tainted: G        W     (3.4.0-rc2-00596-gc7d7a63 #5)
PC is at pl330_tasklet+0x58c/0x59c
LR is at _raw_spin_lock_irqsave+0x10/0x14
pc : [<c0238a84>]    lr : [<c052a3f4>]    psr: 68000193
sp : c06efde0  ip : 00000000  fp : c06efe4c
r10: 00000000  r9 : 00000000  r8 : c06efe18
r7 : d881b414  r6 : d881b410  r5 : d881b450  r4 : 00000003
r3 : d8814bcc  r2 : d8814b60  r1 : 00000000  r0 : d8814b60
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c5387d  Table: 57eb806a  DAC: 00000015

I think the completing a dma descriptor without setting zero to cookies is required for cyclic mode.
Do I make new macro or modify dma_cookie_complete() for it?

Thanks
Boojin.


>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  drivers/dma/amba-pl08x.c    |    2 +-
>  drivers/dma/at_hdmac.c      |    2 +-
>  drivers/dma/coh901318.c     |    2 +-
>  drivers/dma/dmaengine.h     |   18 ++++++++++++++++++
>  drivers/dma/dw_dmac.c       |    2 +-
>  drivers/dma/ep93xx_dma.c    |    2 +-
>  drivers/dma/fsldma.c        |    2 +-
>  drivers/dma/imx-dma.c       |    2 +-
>  drivers/dma/imx-sdma.c      |    2 +-
>  drivers/dma/intel_mid_dma.c |    2 +-
>  drivers/dma/ioat/dma.c      |    3 +--
>  drivers/dma/ioat/dma_v2.c   |    3 +--
>  drivers/dma/ioat/dma_v3.c   |    3 +--
>  drivers/dma/ipu/ipu_idmac.c |    2 +-
>  drivers/dma/mxs-dma.c       |    2 +-
>  drivers/dma/pl330.c         |    2 +-
>  drivers/dma/ste_dma40.c     |    2 +-
>  drivers/dma/timb_dma.c      |    2 +-
>  drivers/dma/txx9dmac.c      |    2 +-
>  19 files changed, 36 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
> index 5996386..f0888c1 100644
> --- a/drivers/dma/amba-pl08x.c
> +++ b/drivers/dma/amba-pl08x.c
> @@ -1540,7 +1540,7 @@ static void pl08x_tasklet(unsigned long data)
>
>  	if (txd) {
>  		/* Update last completed */
> -		plchan->chan.completed_cookie = txd->tx.cookie;
> +		dma_cookie_complete(&txd->tx);
>  	}
>
>  	/* If a new descriptor is queued, set it up plchan->at is NULL here */
> diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
> index df47e7d..b282630 100644
> --- a/drivers/dma/at_hdmac.c
> +++ b/drivers/dma/at_hdmac.c
> @@ -249,7 +249,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
>  	dev_vdbg(chan2dev(&atchan->chan_common),
>  		"descriptor %u complete\n", txd->cookie);
>
> -	atchan->chan_common.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>
>  	/* move children to free_list */
>  	list_splice_init(&desc->tx_list, &atchan->free_list);
> diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
> index 843a1a3..24837d7 100644
> --- a/drivers/dma/coh901318.c
> +++ b/drivers/dma/coh901318.c
> @@ -691,7 +691,7 @@ static void dma_tasklet(unsigned long data)
>  	callback_param = cohd_fin->desc.callback_param;
>
>  	/* sign this job as completed on the channel */
> -	cohc->chan.completed_cookie = cohd_fin->desc.cookie;
> +	dma_cookie_complete(&cohd_fin->desc);
>
>  	/* release the lli allocation and remove the descriptor */
>  	coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli);
> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 7692c86..47e0997 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -5,6 +5,7 @@
>  #ifndef DMAENGINE_H
>  #define DMAENGINE_H
>
> +#include <linux/bug.h>
>  #include <linux/dmaengine.h>
>
>  /**
> @@ -27,4 +28,21 @@ static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor
> *tx)
>  	return cookie;
>  }
>
> +/**
> + * dma_cookie_complete - complete a descriptor
> + * @tx: descriptor to complete
> + *
> + * Mark this descriptor complete by updating the channels completed
> + * cookie marker.  Zero the descriptors cookie to prevent accidental
> + * repeated completions.
> + *
> + * Note: caller is expected to hold a lock to prevent concurrency.
> + */
> +static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
> +{
> +	BUG_ON(tx->cookie < DMA_MIN_COOKIE);
> +	tx->chan->completed_cookie = tx->cookie;
> +	tx->cookie = 0;
> +}
> +
>  #endif
> diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
> index 5ee9498..a190c88 100644
> --- a/drivers/dma/dw_dmac.c
> +++ b/drivers/dma/dw_dmac.c
> @@ -231,7 +231,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
>  	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
>
>  	spin_lock_irqsave(&dwc->lock, flags);
> -	dwc->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	if (callback_required) {
>  		callback = txd->callback;
>  		param = txd->callback_param;
> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index e5aaae8..1c56f75 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -703,7 +703,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	desc = ep93xx_dma_get_active(edmac);
>  	if (desc) {
>  		if (desc->complete) {
> -			edmac->chan.completed_cookie = desc->txd.cookie;
> +			dma_cookie_complete(&desc->txd);
>  			list_splice_init(&edmac->active, &list);
>  		}
>  		callback = desc->txd.callback;
> diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
> index 04b4347..f36e8b1 100644
> --- a/drivers/dma/fsldma.c
> +++ b/drivers/dma/fsldma.c
> @@ -1081,8 +1081,8 @@ static void dma_do_tasklet(unsigned long data)
>
>  		desc = to_fsl_desc(chan->ld_running.prev);
>  		cookie = desc->async_tx.cookie;
> +		dma_cookie_complete(&desc->async_tx);
>
> -		chan->common.completed_cookie = cookie;
>  		chan_dbg(chan, "completed_cookie=%d\n", cookie);
>  	}
>
> diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
> index 42154b6..f1226ad 100644
> --- a/drivers/dma/imx-dma.c
> +++ b/drivers/dma/imx-dma.c
> @@ -66,7 +66,7 @@ static void imxdma_handle(struct imxdma_channel *imxdmac)
>  {
>  	if (imxdmac->desc.callback)
>  		imxdmac->desc.callback(imxdmac->desc.callback_param);
> -	imxdmac->chan.completed_cookie = imxdmac->desc.cookie;
> +	dma_cookie_complete(&imxdmac->desc);
>  }
>
>  static void imxdma_irq_handler(int channel, void *data)
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 4e4f40e..4406be2 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -524,7 +524,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
>  	else
>  		sdmac->status = DMA_SUCCESS;
>
> -	sdmac->chan.completed_cookie = sdmac->desc.cookie;
> +	dma_cookie_complete(&sdmac->desc);
>  	if (sdmac->desc.callback)
>  		sdmac->desc.callback(sdmac->desc.callback_param);
>  }
> diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
> index dfe4396..340509e 100644
> --- a/drivers/dma/intel_mid_dma.c
> +++ b/drivers/dma/intel_mid_dma.c
> @@ -290,7 +290,7 @@ static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
>  	struct intel_mid_dma_lli	*llitem;
>  	void *param_txd = NULL;
>
> -	midc->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	callback_txd = txd->callback;
>  	param_txd = txd->callback_param;
>
> diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
> index 5c06117..b0517c8 100644
> --- a/drivers/dma/ioat/dma.c
> +++ b/drivers/dma/ioat/dma.c
> @@ -600,8 +600,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
>  		 */
>  		dump_desc_dbg(ioat, desc);
>  		if (tx->cookie) {
> -			chan->common.completed_cookie = tx->cookie;
> -			tx->cookie = 0;
> +			dma_cookie_complete(tx);
>  			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
>  			ioat->active -= desc->hw->tx_cnt;
>  			if (tx->callback) {
> diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
> index 17ecacb..e8e110f 100644
> --- a/drivers/dma/ioat/dma_v2.c
> +++ b/drivers/dma/ioat/dma_v2.c
> @@ -149,8 +149,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long
> phys_complete)
>  		dump_desc_dbg(ioat, desc);
>  		if (tx->cookie) {
>  			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
> -			chan->common.completed_cookie = tx->cookie;
> -			tx->cookie = 0;
> +			dma_cookie_complete(tx);
>  			if (tx->callback) {
>  				tx->callback(tx->callback_param);
>  				tx->callback = NULL;
> diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
> index d4afac7..1bda46c 100644
> --- a/drivers/dma/ioat/dma_v3.c
> +++ b/drivers/dma/ioat/dma_v3.c
> @@ -277,9 +277,8 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long
> phys_complete)
>  		dump_desc_dbg(ioat, desc);
>  		tx = &desc->txd;
>  		if (tx->cookie) {
> -			chan->common.completed_cookie = tx->cookie;
> +			dma_cookie_complete(tx);
>  			ioat3_dma_unmap(ioat, desc, idx + i);
> -			tx->cookie = 0;
>  			if (tx->callback) {
>  				tx->callback(tx->callback_param);
>  				tx->callback = NULL;
> diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
> index d4620c5..bff9250 100644
> --- a/drivers/dma/ipu/ipu_idmac.c
> +++ b/drivers/dma/ipu/ipu_idmac.c
> @@ -1289,7 +1289,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
>  	/* Flip the active buffer - even if update above failed */
>  	ichan->active_buffer = !ichan->active_buffer;
>  	if (done)
> -		ichan->dma_chan.completed_cookie = desc->txd.cookie;
> +		dma_cookie_complete(&desc->txd);
>
>  	callback = desc->txd.callback;
>  	callback_param = desc->txd.callback_param;
> diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
> index 4d3b6ff..5f3492e 100644
> --- a/drivers/dma/mxs-dma.c
> +++ b/drivers/dma/mxs-dma.c
> @@ -262,7 +262,7 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
>  		stat1 &= ~(1 << channel);
>
>  		if (mxs_chan->status == DMA_SUCCESS)
> -			mxs_chan->chan.completed_cookie = mxs_chan->desc.cookie;
> +			dma_cookie_complete(&mxs_chan->desc);
>
>  		/* schedule tasklet on this channel */
>  		tasklet_schedule(&mxs_chan->tasklet);
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index ec9638b..76871b8 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -233,7 +233,7 @@ static void pl330_tasklet(unsigned long data)
>  	/* Pick up ripe tomatoes */
>  	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
>  		if (desc->status == DONE) {
> -			pch->chan.completed_cookie = desc->txd.cookie;
> +			dma_cookie_complete(&desc->txd);
>  			list_move_tail(&desc->node, &list);
>  		}
>
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> index 23e2edc..c246375 100644
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
> @@ -1347,7 +1347,7 @@ static void dma_tasklet(unsigned long data)
>  		goto err;
>
>  	if (!d40d->cyclic)
> -		d40c->chan.completed_cookie = d40d->txd.cookie;
> +		dma_cookie_complete(&d40d->txd);
>
>  	/*
>  	 * If terminating a channel pending_tx is set to zero.
> diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
> index b6e83fc..1845ac9 100644
> --- a/drivers/dma/timb_dma.c
> +++ b/drivers/dma/timb_dma.c
> @@ -285,7 +285,7 @@ static void __td_finish(struct timb_dma_chan *td_chan)
>  	else
>  		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR);
>  */
> -	td_chan->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	td_chan->ongoing = false;
>
>  	callback = txd->callback;
> diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
> index 66f8fca..8a5225b 100644
> --- a/drivers/dma/txx9dmac.c
> +++ b/drivers/dma/txx9dmac.c
> @@ -411,7 +411,7 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
>  	dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
>  		 txd->cookie, desc);
>
> -	dc->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	callback = txd->callback;
>  	param = txd->callback_param;
>
> --
> 1.7.4.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
@ 2012-04-23  9:40     ` Boojin Kim
  0 siblings, 0 replies; 66+ messages in thread
From: Boojin Kim @ 2012-04-23  9:40 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> Sent: Wednesday, March 07, 2012 7:35 AM
> To: Dan Williams; Vinod Koul
> Cc: Stephen Warren; Linus Walleij; Srinidhi Kasagar; Li Yang; linuxppc-dev at lists.ozlabs.org;
> linux-arm-kernel at lists.infradead.org
> Subject: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
>
> Provide a common function to do the cookie mechanics for completing
> a DMA descriptor.
Dear Russell,
I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
Kernel BUG occurs during DMA transfer with DMA cyclic mode.
This patch makes the cookies into zero. But, cookies should be kept during cyclic mode
because cyclic mode re-uses the cookies.
So, Error occurs on "BUG_ON(tx->cookie < DMA_MIN_COOKIE)" lines on dma_cookie_complete().
Please see following error.
------------[ cut here ]------------
kernel BUG at drivers/dma/dmaengine.h:53!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0    Tainted: G        W     (3.4.0-rc2-00596-gc7d7a63 #5)
PC is at pl330_tasklet+0x58c/0x59c
LR is@_raw_spin_lock_irqsave+0x10/0x14
pc : [<c0238a84>]    lr : [<c052a3f4>]    psr: 68000193
sp : c06efde0  ip : 00000000  fp : c06efe4c
r10: 00000000  r9 : 00000000  r8 : c06efe18
r7 : d881b414  r6 : d881b410  r5 : d881b450  r4 : 00000003
r3 : d8814bcc  r2 : d8814b60  r1 : 00000000  r0 : d8814b60
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c5387d  Table: 57eb806a  DAC: 00000015

I think the completing a dma descriptor without setting zero to cookies is required for cyclic mode.
Do I make new macro or modify dma_cookie_complete() for it?

Thanks
Boojin.


>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  drivers/dma/amba-pl08x.c    |    2 +-
>  drivers/dma/at_hdmac.c      |    2 +-
>  drivers/dma/coh901318.c     |    2 +-
>  drivers/dma/dmaengine.h     |   18 ++++++++++++++++++
>  drivers/dma/dw_dmac.c       |    2 +-
>  drivers/dma/ep93xx_dma.c    |    2 +-
>  drivers/dma/fsldma.c        |    2 +-
>  drivers/dma/imx-dma.c       |    2 +-
>  drivers/dma/imx-sdma.c      |    2 +-
>  drivers/dma/intel_mid_dma.c |    2 +-
>  drivers/dma/ioat/dma.c      |    3 +--
>  drivers/dma/ioat/dma_v2.c   |    3 +--
>  drivers/dma/ioat/dma_v3.c   |    3 +--
>  drivers/dma/ipu/ipu_idmac.c |    2 +-
>  drivers/dma/mxs-dma.c       |    2 +-
>  drivers/dma/pl330.c         |    2 +-
>  drivers/dma/ste_dma40.c     |    2 +-
>  drivers/dma/timb_dma.c      |    2 +-
>  drivers/dma/txx9dmac.c      |    2 +-
>  19 files changed, 36 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
> index 5996386..f0888c1 100644
> --- a/drivers/dma/amba-pl08x.c
> +++ b/drivers/dma/amba-pl08x.c
> @@ -1540,7 +1540,7 @@ static void pl08x_tasklet(unsigned long data)
>
>  	if (txd) {
>  		/* Update last completed */
> -		plchan->chan.completed_cookie = txd->tx.cookie;
> +		dma_cookie_complete(&txd->tx);
>  	}
>
>  	/* If a new descriptor is queued, set it up plchan->at is NULL here */
> diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
> index df47e7d..b282630 100644
> --- a/drivers/dma/at_hdmac.c
> +++ b/drivers/dma/at_hdmac.c
> @@ -249,7 +249,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
>  	dev_vdbg(chan2dev(&atchan->chan_common),
>  		"descriptor %u complete\n", txd->cookie);
>
> -	atchan->chan_common.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>
>  	/* move children to free_list */
>  	list_splice_init(&desc->tx_list, &atchan->free_list);
> diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
> index 843a1a3..24837d7 100644
> --- a/drivers/dma/coh901318.c
> +++ b/drivers/dma/coh901318.c
> @@ -691,7 +691,7 @@ static void dma_tasklet(unsigned long data)
>  	callback_param = cohd_fin->desc.callback_param;
>
>  	/* sign this job as completed on the channel */
> -	cohc->chan.completed_cookie = cohd_fin->desc.cookie;
> +	dma_cookie_complete(&cohd_fin->desc);
>
>  	/* release the lli allocation and remove the descriptor */
>  	coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli);
> diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
> index 7692c86..47e0997 100644
> --- a/drivers/dma/dmaengine.h
> +++ b/drivers/dma/dmaengine.h
> @@ -5,6 +5,7 @@
>  #ifndef DMAENGINE_H
>  #define DMAENGINE_H
>
> +#include <linux/bug.h>
>  #include <linux/dmaengine.h>
>
>  /**
> @@ -27,4 +28,21 @@ static inline dma_cookie_t dma_cookie_assign(struct dma_async_tx_descriptor
> *tx)
>  	return cookie;
>  }
>
> +/**
> + * dma_cookie_complete - complete a descriptor
> + * @tx: descriptor to complete
> + *
> + * Mark this descriptor complete by updating the channels completed
> + * cookie marker.  Zero the descriptors cookie to prevent accidental
> + * repeated completions.
> + *
> + * Note: caller is expected to hold a lock to prevent concurrency.
> + */
> +static inline void dma_cookie_complete(struct dma_async_tx_descriptor *tx)
> +{
> +	BUG_ON(tx->cookie < DMA_MIN_COOKIE);
> +	tx->chan->completed_cookie = tx->cookie;
> +	tx->cookie = 0;
> +}
> +
>  #endif
> diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
> index 5ee9498..a190c88 100644
> --- a/drivers/dma/dw_dmac.c
> +++ b/drivers/dma/dw_dmac.c
> @@ -231,7 +231,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
>  	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
>
>  	spin_lock_irqsave(&dwc->lock, flags);
> -	dwc->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	if (callback_required) {
>  		callback = txd->callback;
>  		param = txd->callback_param;
> diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
> index e5aaae8..1c56f75 100644
> --- a/drivers/dma/ep93xx_dma.c
> +++ b/drivers/dma/ep93xx_dma.c
> @@ -703,7 +703,7 @@ static void ep93xx_dma_tasklet(unsigned long data)
>  	desc = ep93xx_dma_get_active(edmac);
>  	if (desc) {
>  		if (desc->complete) {
> -			edmac->chan.completed_cookie = desc->txd.cookie;
> +			dma_cookie_complete(&desc->txd);
>  			list_splice_init(&edmac->active, &list);
>  		}
>  		callback = desc->txd.callback;
> diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
> index 04b4347..f36e8b1 100644
> --- a/drivers/dma/fsldma.c
> +++ b/drivers/dma/fsldma.c
> @@ -1081,8 +1081,8 @@ static void dma_do_tasklet(unsigned long data)
>
>  		desc = to_fsl_desc(chan->ld_running.prev);
>  		cookie = desc->async_tx.cookie;
> +		dma_cookie_complete(&desc->async_tx);
>
> -		chan->common.completed_cookie = cookie;
>  		chan_dbg(chan, "completed_cookie=%d\n", cookie);
>  	}
>
> diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
> index 42154b6..f1226ad 100644
> --- a/drivers/dma/imx-dma.c
> +++ b/drivers/dma/imx-dma.c
> @@ -66,7 +66,7 @@ static void imxdma_handle(struct imxdma_channel *imxdmac)
>  {
>  	if (imxdmac->desc.callback)
>  		imxdmac->desc.callback(imxdmac->desc.callback_param);
> -	imxdmac->chan.completed_cookie = imxdmac->desc.cookie;
> +	dma_cookie_complete(&imxdmac->desc);
>  }
>
>  static void imxdma_irq_handler(int channel, void *data)
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 4e4f40e..4406be2 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -524,7 +524,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
>  	else
>  		sdmac->status = DMA_SUCCESS;
>
> -	sdmac->chan.completed_cookie = sdmac->desc.cookie;
> +	dma_cookie_complete(&sdmac->desc);
>  	if (sdmac->desc.callback)
>  		sdmac->desc.callback(sdmac->desc.callback_param);
>  }
> diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
> index dfe4396..340509e 100644
> --- a/drivers/dma/intel_mid_dma.c
> +++ b/drivers/dma/intel_mid_dma.c
> @@ -290,7 +290,7 @@ static void midc_descriptor_complete(struct intel_mid_dma_chan *midc,
>  	struct intel_mid_dma_lli	*llitem;
>  	void *param_txd = NULL;
>
> -	midc->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	callback_txd = txd->callback;
>  	param_txd = txd->callback_param;
>
> diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
> index 5c06117..b0517c8 100644
> --- a/drivers/dma/ioat/dma.c
> +++ b/drivers/dma/ioat/dma.c
> @@ -600,8 +600,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
>  		 */
>  		dump_desc_dbg(ioat, desc);
>  		if (tx->cookie) {
> -			chan->common.completed_cookie = tx->cookie;
> -			tx->cookie = 0;
> +			dma_cookie_complete(tx);
>  			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
>  			ioat->active -= desc->hw->tx_cnt;
>  			if (tx->callback) {
> diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
> index 17ecacb..e8e110f 100644
> --- a/drivers/dma/ioat/dma_v2.c
> +++ b/drivers/dma/ioat/dma_v2.c
> @@ -149,8 +149,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long
> phys_complete)
>  		dump_desc_dbg(ioat, desc);
>  		if (tx->cookie) {
>  			ioat_dma_unmap(chan, tx->flags, desc->len, desc->hw);
> -			chan->common.completed_cookie = tx->cookie;
> -			tx->cookie = 0;
> +			dma_cookie_complete(tx);
>  			if (tx->callback) {
>  				tx->callback(tx->callback_param);
>  				tx->callback = NULL;
> diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
> index d4afac7..1bda46c 100644
> --- a/drivers/dma/ioat/dma_v3.c
> +++ b/drivers/dma/ioat/dma_v3.c
> @@ -277,9 +277,8 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long
> phys_complete)
>  		dump_desc_dbg(ioat, desc);
>  		tx = &desc->txd;
>  		if (tx->cookie) {
> -			chan->common.completed_cookie = tx->cookie;
> +			dma_cookie_complete(tx);
>  			ioat3_dma_unmap(ioat, desc, idx + i);
> -			tx->cookie = 0;
>  			if (tx->callback) {
>  				tx->callback(tx->callback_param);
>  				tx->callback = NULL;
> diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
> index d4620c5..bff9250 100644
> --- a/drivers/dma/ipu/ipu_idmac.c
> +++ b/drivers/dma/ipu/ipu_idmac.c
> @@ -1289,7 +1289,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
>  	/* Flip the active buffer - even if update above failed */
>  	ichan->active_buffer = !ichan->active_buffer;
>  	if (done)
> -		ichan->dma_chan.completed_cookie = desc->txd.cookie;
> +		dma_cookie_complete(&desc->txd);
>
>  	callback = desc->txd.callback;
>  	callback_param = desc->txd.callback_param;
> diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
> index 4d3b6ff..5f3492e 100644
> --- a/drivers/dma/mxs-dma.c
> +++ b/drivers/dma/mxs-dma.c
> @@ -262,7 +262,7 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
>  		stat1 &= ~(1 << channel);
>
>  		if (mxs_chan->status == DMA_SUCCESS)
> -			mxs_chan->chan.completed_cookie = mxs_chan->desc.cookie;
> +			dma_cookie_complete(&mxs_chan->desc);
>
>  		/* schedule tasklet on this channel */
>  		tasklet_schedule(&mxs_chan->tasklet);
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index ec9638b..76871b8 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -233,7 +233,7 @@ static void pl330_tasklet(unsigned long data)
>  	/* Pick up ripe tomatoes */
>  	list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
>  		if (desc->status == DONE) {
> -			pch->chan.completed_cookie = desc->txd.cookie;
> +			dma_cookie_complete(&desc->txd);
>  			list_move_tail(&desc->node, &list);
>  		}
>
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> index 23e2edc..c246375 100644
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
> @@ -1347,7 +1347,7 @@ static void dma_tasklet(unsigned long data)
>  		goto err;
>
>  	if (!d40d->cyclic)
> -		d40c->chan.completed_cookie = d40d->txd.cookie;
> +		dma_cookie_complete(&d40d->txd);
>
>  	/*
>  	 * If terminating a channel pending_tx is set to zero.
> diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
> index b6e83fc..1845ac9 100644
> --- a/drivers/dma/timb_dma.c
> +++ b/drivers/dma/timb_dma.c
> @@ -285,7 +285,7 @@ static void __td_finish(struct timb_dma_chan *td_chan)
>  	else
>  		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR);
>  */
> -	td_chan->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	td_chan->ongoing = false;
>
>  	callback = txd->callback;
> diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
> index 66f8fca..8a5225b 100644
> --- a/drivers/dma/txx9dmac.c
> +++ b/drivers/dma/txx9dmac.c
> @@ -411,7 +411,7 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
>  	dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
>  		 txd->cookie, desc);
>
> -	dc->chan.completed_cookie = txd->cookie;
> +	dma_cookie_complete(txd);
>  	callback = txd->callback;
>  	param = txd->callback_param;
>
> --
> 1.7.4.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
  2012-04-23  9:40     ` Boojin Kim
@ 2012-04-23  9:50       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-04-23  9:50 UTC (permalink / raw)
  To: Boojin Kim
  Cc: 'Stephen Warren', 'Linus Walleij',
	'Srinidhi Kasagar', 'Vinod Koul',
	'Dan Williams',
	linuxppc-dev, linux-arm-kernel

On Mon, Apr 23, 2012 at 06:40:06PM +0900, Boojin Kim wrote:
> I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
> Kernel BUG occurs during DMA transfer with DMA cyclic mode.
> This patch makes the cookies into zero. But, cookies should be kept
> during cyclic mode because cyclic mode re-uses the cookies.

The protection is there to prevent cookies being accidentally re-used.
If you're running a cyclic transfer, even then you shouldn't be completing
the same cookie time and time again - I think Vinod also concurs with this.

I think our preference is for cyclic transfers to entire remain uncompleted,
or to get a new cookie each time they allegedly "complete".

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
@ 2012-04-23  9:50       ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-04-23  9:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 23, 2012 at 06:40:06PM +0900, Boojin Kim wrote:
> I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
> Kernel BUG occurs during DMA transfer with DMA cyclic mode.
> This patch makes the cookies into zero. But, cookies should be kept
> during cyclic mode because cyclic mode re-uses the cookies.

The protection is there to prevent cookies being accidentally re-used.
If you're running a cyclic transfer, even then you shouldn't be completing
the same cookie time and time again - I think Vinod also concurs with this.

I think our preference is for cyclic transfers to entire remain uncompleted,
or to get a new cookie each time they allegedly "complete".

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
  2012-04-23  9:50       ` Russell King - ARM Linux
@ 2012-04-23 10:01         ` Vinod Koul
  -1 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-04-23 10:01 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: 'Stephen Warren', 'Linus Walleij',
	'Srinidhi Kasagar', Boojin Kim, 'Dan Williams',
	linuxppc-dev, linux-arm-kernel

On Mon, 2012-04-23 at 10:50 +0100, Russell King - ARM Linux wrote:
> On Mon, Apr 23, 2012 at 06:40:06PM +0900, Boojin Kim wrote:
> > I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
> > Kernel BUG occurs during DMA transfer with DMA cyclic mode.
> > This patch makes the cookies into zero. But, cookies should be kept
> > during cyclic mode because cyclic mode re-uses the cookies.
> 
> The protection is there to prevent cookies being accidentally re-used.
> If you're running a cyclic transfer, even then you shouldn't be completing
> the same cookie time and time again - I think Vinod also concurs with this.
Right :)
I recently committed patch for imx-dma which doesn't mark the cyclic
descriptor as complete. Descriptor represents a transaction and makes no
sense to complete t if the transaction is still continuing.
> 
> I think our preference is for cyclic transfers to entire remain uncompleted,
> or to get a new cookie each time they allegedly "complete".
No it is not complete. Cyclic never completes, it aborts when user
wants. The "notification" interrupt is for updating the
counters/notifying (timestamp/periods elapsed in sound), and shouldn't
be used for anything else

-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
@ 2012-04-23 10:01         ` Vinod Koul
  0 siblings, 0 replies; 66+ messages in thread
From: Vinod Koul @ 2012-04-23 10:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2012-04-23 at 10:50 +0100, Russell King - ARM Linux wrote:
> On Mon, Apr 23, 2012 at 06:40:06PM +0900, Boojin Kim wrote:
> > I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
> > Kernel BUG occurs during DMA transfer with DMA cyclic mode.
> > This patch makes the cookies into zero. But, cookies should be kept
> > during cyclic mode because cyclic mode re-uses the cookies.
> 
> The protection is there to prevent cookies being accidentally re-used.
> If you're running a cyclic transfer, even then you shouldn't be completing
> the same cookie time and time again - I think Vinod also concurs with this.
Right :)
I recently committed patch for imx-dma which doesn't mark the cyclic
descriptor as complete. Descriptor represents a transaction and makes no
sense to complete t if the transaction is still continuing.
> 
> I think our preference is for cyclic transfers to entire remain uncompleted,
> or to get a new cookie each time they allegedly "complete".
No it is not complete. Cyclic never completes, it aborts when user
wants. The "notification" interrupt is for updating the
counters/notifying (timestamp/periods elapsed in sound), and shouldn't
be used for anything else

-- 
~Vinod

^ permalink raw reply	[flat|nested] 66+ messages in thread

* RE: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
  2012-04-23 10:01         ` Vinod Koul
@ 2012-04-23 11:06           ` Boojin Kim
  -1 siblings, 0 replies; 66+ messages in thread
From: Boojin Kim @ 2012-04-23 11:06 UTC (permalink / raw)
  To: 'Vinod Koul', 'Russell King - ARM Linux'
  Cc: 'Stephen Warren', 'Linus Walleij',
	'Srinidhi Kasagar', 'Dan Williams',
	linuxppc-dev, linux-arm-kernel

Vinod Koul wrote:
> Sent: Monday, April 23, 2012 7:01 PM
> To: Russell King - ARM Linux
> Cc: 'Stephen Warren'; 'Linus Walleij'; 'Srinidhi Kasagar'; Boojin Kim; 'Dan Williams'; 'Li Yang';
> linuxppc-dev@lists.ozlabs.org; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
>
> On Mon, 2012-04-23 at 10:50 +0100, Russell King - ARM Linux wrote:
> > On Mon, Apr 23, 2012 at 06:40:06PM +0900, Boojin Kim wrote:
> > > I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
> > > Kernel BUG occurs during DMA transfer with DMA cyclic mode.
> > > This patch makes the cookies into zero. But, cookies should be kept
> > > during cyclic mode because cyclic mode re-uses the cookies.
> >
> > The protection is there to prevent cookies being accidentally re-used.
> > If you're running a cyclic transfer, even then you shouldn't be completing
> > the same cookie time and time again - I think Vinod also concurs with this.
> Right :)
> I recently committed patch for imx-dma which doesn't mark the cyclic
> descriptor as complete. Descriptor represents a transaction and makes no
> sense to complete t if the transaction is still continuing.
Dear Vinod,
you already fixed it. :) thanks.
And I have other question. (Actually, It doesn't relate to this patch.)
I met the DMA probing fail problem on Linux 3.4.
It's because the return value on regulator_get() is changed
from ENODEV to EPROBE_DEFER in case not to supply a vcore regulator.
So, I try to change the check value about the return value of regulator_get()
in amba_get_enable_vcore()from ENODEV to EPROBE_DEFER.
How about it ? Do you already fix it too?

Thanks,
Boojin

> >
> > I think our preference is for cyclic transfers to entire remain uncompleted,
> > or to get a new cookie each time they allegedly "complete".
> No it is not complete. Cyclic never completes, it aborts when user
> wants. The "notification" interrupt is for updating the
> counters/notifying (timestamp/periods elapsed in sound), and shouldn't
> be used for anything else
>
> --
> ~Vinod
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
@ 2012-04-23 11:06           ` Boojin Kim
  0 siblings, 0 replies; 66+ messages in thread
From: Boojin Kim @ 2012-04-23 11:06 UTC (permalink / raw)
  To: linux-arm-kernel

Vinod Koul wrote:
> Sent: Monday, April 23, 2012 7:01 PM
> To: Russell King - ARM Linux
> Cc: 'Stephen Warren'; 'Linus Walleij'; 'Srinidhi Kasagar'; Boojin Kim; 'Dan Williams'; 'Li Yang';
> linuxppc-dev at lists.ozlabs.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
>
> On Mon, 2012-04-23 at 10:50 +0100, Russell King - ARM Linux wrote:
> > On Mon, Apr 23, 2012 at 06:40:06PM +0900, Boojin Kim wrote:
> > > I met a problem on DMA cyclic mode (DMA_CYCLIC) for sound playback.
> > > Kernel BUG occurs during DMA transfer with DMA cyclic mode.
> > > This patch makes the cookies into zero. But, cookies should be kept
> > > during cyclic mode because cyclic mode re-uses the cookies.
> >
> > The protection is there to prevent cookies being accidentally re-used.
> > If you're running a cyclic transfer, even then you shouldn't be completing
> > the same cookie time and time again - I think Vinod also concurs with this.
> Right :)
> I recently committed patch for imx-dma which doesn't mark the cyclic
> descriptor as complete. Descriptor represents a transaction and makes no
> sense to complete t if the transaction is still continuing.
Dear Vinod,
you already fixed it. :) thanks.
And I have other question. (Actually, It doesn't relate to this patch.)
I met the DMA probing fail problem on Linux 3.4.
It's because the return value on regulator_get() is changed
from ENODEV to EPROBE_DEFER in case not to supply a vcore regulator.
So, I try to change the check value about the return value of regulator_get()
in amba_get_enable_vcore()from ENODEV to EPROBE_DEFER.
How about it ? Do you already fix it too?

Thanks,
Boojin

> >
> > I think our preference is for cyclic transfers to entire remain uncompleted,
> > or to get a new cookie each time they allegedly "complete".
> No it is not complete. Cyclic never completes, it aborts when user
> wants. The "notification" interrupt is for updating the
> counters/notifying (timestamp/periods elapsed in sound), and shouldn't
> be used for anything else
>
> --
> ~Vinod
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
  2012-04-23 11:06           ` Boojin Kim
@ 2012-04-23 11:13             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-04-23 11:13 UTC (permalink / raw)
  To: Boojin Kim
  Cc: 'Vinod Koul', 'Stephen Warren',
	'Linus Walleij', 'Srinidhi Kasagar',
	'Dan Williams',
	linuxppc-dev, linux-arm-kernel

On Mon, Apr 23, 2012 at 08:06:36PM +0900, Boojin Kim wrote:
> I met the DMA probing fail problem on Linux 3.4.
> It's because the return value on regulator_get() is changed
> from ENODEV to EPROBE_DEFER in case not to supply a vcore regulator.
> So, I try to change the check value about the return value of regulator_get()
> in amba_get_enable_vcore()from ENODEV to EPROBE_DEFER.
> How about it ? Do you already fix it too?

A fix has already been committed and sent upstream - about a week ago.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor
@ 2012-04-23 11:13             ` Russell King - ARM Linux
  0 siblings, 0 replies; 66+ messages in thread
From: Russell King - ARM Linux @ 2012-04-23 11:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 23, 2012 at 08:06:36PM +0900, Boojin Kim wrote:
> I met the DMA probing fail problem on Linux 3.4.
> It's because the return value on regulator_get() is changed
> from ENODEV to EPROBE_DEFER in case not to supply a vcore regulator.
> So, I try to change the check value about the return value of regulator_get()
> in amba_get_enable_vcore()from ENODEV to EPROBE_DEFER.
> How about it ? Do you already fix it too?

A fix has already been committed and sent upstream - about a week ago.

^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2012-04-23 11:14 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-06 22:33 [PATCH v2 0/9] DMA engine cookie handling cleanups Russell King - ARM Linux
2012-03-06 22:33 ` Russell King - ARM Linux
2012-03-06 22:33 ` [PATCH 1/9] dmaengine: mv_xor: remove write-only is_complete_cookie Russell King - ARM Linux
2012-03-06 22:34 ` [PATCH 2/9] dmaengine: move last completed cookie into generic dma_chan structure Russell King - ARM Linux
2012-03-06 22:34   ` Russell King - ARM Linux
2012-03-07  0:38   ` H Hartley Sweeten
2012-03-07  0:38     ` H Hartley Sweeten
2012-03-06 22:34 ` [PATCH 3/9] dmaengine: add private header file Russell King - ARM Linux
2012-03-06 22:34   ` Russell King - ARM Linux
2012-03-07  0:47   ` H Hartley Sweeten
2012-03-07  0:47     ` H Hartley Sweeten
2012-03-06 22:34 ` [PATCH 4/9] dmaengine: consolidate assignment of DMA cookies Russell King - ARM Linux
2012-03-06 22:34   ` Russell King - ARM Linux
2012-03-07  0:53   ` H Hartley Sweeten
2012-03-07  0:53     ` H Hartley Sweeten
2012-03-06 22:35 ` [PATCH 5/9] dmaengine: provide a common function for completing a dma descriptor Russell King - ARM Linux
2012-03-06 22:35   ` Russell King - ARM Linux
2012-03-07  0:56   ` H Hartley Sweeten
2012-03-07  0:56     ` H Hartley Sweeten
2012-04-23  9:40   ` Boojin Kim
2012-04-23  9:40     ` Boojin Kim
2012-04-23  9:50     ` Russell King - ARM Linux
2012-04-23  9:50       ` Russell King - ARM Linux
2012-04-23 10:01       ` Vinod Koul
2012-04-23 10:01         ` Vinod Koul
2012-04-23 11:06         ` Boojin Kim
2012-04-23 11:06           ` Boojin Kim
2012-04-23 11:13           ` Russell King - ARM Linux
2012-04-23 11:13             ` Russell King - ARM Linux
2012-03-06 22:35 ` [PATCH 6/9] dmaengine: consolidate tx_status functions Russell King - ARM Linux
2012-03-06 22:35   ` Russell King - ARM Linux
2012-03-07  1:04   ` H Hartley Sweeten
2012-03-07  1:04     ` H Hartley Sweeten
2012-03-06 22:35 ` [PATCH 7/9] dmaengine: consolidate initialization of cookies Russell King - ARM Linux
2012-03-07  1:07   ` H Hartley Sweeten
2012-03-06 22:36 ` [PATCH 8/9] dmaengine: fix cookie handling in iop-adma.c and ppc4xx/adma.c Russell King - ARM Linux
2012-03-06 22:36 ` [PATCH 9/9] dmaengine: ensure all DMA engine drivers initialize their cookies Russell King - ARM Linux
2012-03-06 22:36   ` Russell King - ARM Linux
2012-03-07  8:33 ` [PATCH v2 0/9] DMA engine cookie handling cleanups Linus Walleij
2012-03-07  8:33   ` Linus Walleij
2012-03-07  9:06   ` Russell King - ARM Linux
2012-03-07  9:06     ` Russell King - ARM Linux
2012-03-07 13:54 ` Vinod Koul
2012-03-07 13:54   ` Vinod Koul
2012-03-12 16:11   ` Russell King - ARM Linux
2012-03-12 16:11     ` Russell King - ARM Linux
2012-03-12 16:23     ` Vinod Koul
2012-03-12 16:23       ` Vinod Koul
2012-03-13  8:40       ` Vinod Koul
2012-03-13  8:40         ` Vinod Koul
2012-03-13 12:31         ` Russell King - ARM Linux
2012-03-13 12:31           ` Russell King - ARM Linux
2012-03-13 14:38           ` Vinod Koul
2012-03-13 14:38             ` Vinod Koul
2012-03-19 14:35             ` Vinod Koul
2012-03-19 14:35               ` Vinod Koul
2012-03-07 18:09 ` Jassi Brar
2012-03-07 18:09   ` Jassi Brar
2012-03-07 18:21   ` Russell King - ARM Linux
2012-03-07 18:21     ` Russell King - ARM Linux
2012-03-07 18:44     ` Jassi Brar
2012-03-07 18:44       ` Jassi Brar
2012-03-09  8:59 ` Shawn Guo
2012-03-09  8:59   ` Shawn Guo
2012-03-13 11:45 ` Nicolas Ferre
2012-03-13 11:45   ` Nicolas Ferre

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.