public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] dw_dmac: set of cleanups and small fixes
@ 2012-06-15  7:05 Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 1/9] dw_dmac: fix constant in the comment Andy Shevchenko
                   ` (9 more replies)
  0 siblings, 10 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

This patchset provides set of the cleanups and small fixes against the
DesignWare DMA controller driver. It's a first portion of the patches to make
the driver usable on other platforms.

Andy Shevchenko (9):
  dw_dmac: fix constant in the comment
  dw_dmac: use proper casting to print dma_addr_t values
  dw_dmac: introduce dwc_dump_chan_regs to dump registers
  dw_dmac: print correct number of scanned descriptors
  dw_dmac: use __func__ constant in the debug prints
  dw_dmac: disable dma in optimal way in probe
  dw_dmac: disable BLOCK interrupts
  dw_dmac: introduce dwc_fast_fls()
  dw_dmac: move from __init to __devinit

 drivers/dma/dw_dmac.c      |  148 ++++++++++++++++++++------------------------
 drivers/dma/dw_dmac_regs.h |    2 +-
 2 files changed, 69 insertions(+), 81 deletions(-)

-- 
1.7.10


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

* [PATCH 1/9] dw_dmac: fix constant in the comment
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 2/9] dw_dmac: use proper casting to print dma_addr_t values Andy Shevchenko
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac_regs.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index f298f69..e248481 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -82,7 +82,7 @@ struct dw_dma_regs {
 	DW_REG(ID);
 	DW_REG(TEST);
 
-	/* optional encoded params, 0x3c8..0x3 */
+	/* optional encoded params, 0x3c8..0x3f7 */
 };
 
 /* Bitfields in CTL_LO */
-- 
1.7.10


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

* [PATCH 2/9] dw_dmac: use proper casting to print dma_addr_t values
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 1/9] dw_dmac: fix constant in the comment Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 3/9] dw_dmac: introduce dwc_dump_chan_regs to dump registers Andy Shevchenko
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

dma_addr_t is sometimes 32 bit and sometimes 64. We normally cast them to
unsigned long long for printk().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index adbc616..45861b6 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -339,7 +339,8 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 		return;
 	}
 
-	dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp);
+	dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%llx\n",
+			(unsigned long long)llp);
 
 	list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
 		/* check first descriptors addr */
@@ -389,8 +390,10 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
 {
 	dev_printk(KERN_CRIT, chan2dev(&dwc->chan),
-			"  desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
-			lli->sar, lli->dar, lli->llp,
+			"  desc: s0x%llx d0x%llx l0x%llx c0x%x:%x\n",
+			(unsigned long long)lli->sar,
+			(unsigned long long)lli->dar,
+			(unsigned long long)lli->llp,
 			lli->ctlhi, lli->ctllo);
 }
 
@@ -629,8 +632,10 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 	unsigned int		dst_width;
 	u32			ctllo;
 
-	dev_vdbg(chan2dev(chan), "prep_dma_memcpy d0x%x s0x%x l0x%zx f0x%lx\n",
-			dest, src, len, flags);
+	dev_vdbg(chan2dev(chan),
+			"prep_dma_memcpy d0x%llx s0x%llx l0x%zx f0x%lx\n",
+			(unsigned long long)dest, (unsigned long long)src,
+			len, flags);
 
 	if (unlikely(!len)) {
 		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
@@ -1310,9 +1315,9 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
 	dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
 			sizeof(last->lli), DMA_TO_DEVICE);
 
-	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu "
-			"period %zu periods %d\n", buf_addr, buf_len,
-			period_len, periods);
+	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
+			"period %zu periods %d\n", (unsigned long long)buf_addr,
+			buf_len, period_len, periods);
 
 	cdesc->periods = periods;
 	dwc->cdesc = cdesc;
-- 
1.7.10


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

* [PATCH 3/9] dw_dmac: introduce dwc_dump_chan_regs to dump registers
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 1/9] dw_dmac: fix constant in the comment Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 2/9] dw_dmac: use proper casting to print dma_addr_t values Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 4/9] dw_dmac: print correct number of scanned descriptors Andy Shevchenko
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

There is three places where values of the most significant registers were
printed. Make such piece of code as separate function.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   37 ++++++++++++++++---------------------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 45861b6..b6251dc 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -193,6 +193,19 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
 
 /*----------------------------------------------------------------------*/
 
+static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
+{
+	dev_err(chan2dev(&dwc->chan),
+		"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+		channel_readl(dwc, SAR),
+		channel_readl(dwc, DAR),
+		channel_readl(dwc, LLP),
+		channel_readl(dwc, CTL_HI),
+		channel_readl(dwc, CTL_LO));
+}
+
+/*----------------------------------------------------------------------*/
+
 /* Called with dwc->lock held and bh disabled */
 static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
 {
@@ -202,13 +215,7 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
 		dev_err(chan2dev(&dwc->chan),
 			"BUG: Attempted to start non-idle channel\n");
-		dev_err(chan2dev(&dwc->chan),
-			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
-			channel_readl(dwc, SAR),
-			channel_readl(dwc, DAR),
-			channel_readl(dwc, LLP),
-			channel_readl(dwc, CTL_HI),
-			channel_readl(dwc, CTL_LO));
+		dwc_dump_chan_regs(dwc);
 
 		/* The tasklet will hopefully advance the queue... */
 		return;
@@ -492,13 +499,7 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
 
 		spin_lock_irqsave(&dwc->lock, flags);
 
-		dev_err(chan2dev(&dwc->chan),
-			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
-			channel_readl(dwc, SAR),
-			channel_readl(dwc, DAR),
-			channel_readl(dwc, LLP),
-			channel_readl(dwc, CTL_HI),
-			channel_readl(dwc, CTL_LO));
+		dwc_dump_chan_regs(dwc);
 
 		channel_clear_bit(dw, CH_EN, dwc->mask);
 		while (dma_readl(dw, CH_EN) & dwc->mask)
@@ -1133,13 +1134,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan)
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
 		dev_err(chan2dev(&dwc->chan),
 			"BUG: Attempted to start non-idle channel\n");
-		dev_err(chan2dev(&dwc->chan),
-			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
-			channel_readl(dwc, SAR),
-			channel_readl(dwc, DAR),
-			channel_readl(dwc, LLP),
-			channel_readl(dwc, CTL_HI),
-			channel_readl(dwc, CTL_LO));
+		dwc_dump_chan_regs(dwc);
 		spin_unlock_irqrestore(&dwc->lock, flags);
 		return -EBUSY;
 	}
-- 
1.7.10


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

* [PATCH 4/9] dw_dmac: print correct number of scanned descriptors
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                   ` (2 preceding siblings ...)
  2012-06-15  7:05 ` [PATCH 3/9] dw_dmac: introduce dwc_dump_chan_regs to dump registers Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 5/9] dw_dmac: use __func__ constant in the debug prints Andy Shevchenko
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

In case the first descriptor we found is available, the counter still remains 0
value which is wrong. This patch fixes the counter behaviour.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index b6251dc..763730a 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -107,13 +107,13 @@ static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
+		i++;
 		if (async_tx_test_ack(&desc->txd)) {
 			list_del(&desc->desc_node);
 			ret = desc;
 			break;
 		}
 		dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc);
-		i++;
 	}
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-- 
1.7.10


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

* [PATCH 5/9] dw_dmac: use __func__ constant in the debug prints
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                   ` (3 preceding siblings ...)
  2012-06-15  7:05 ` [PATCH 4/9] dw_dmac: print correct number of scanned descriptors Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 6/9] dw_dmac: disable dma in optimal way in probe Andy Shevchenko
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 763730a..e2ea243 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -346,7 +346,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 		return;
 	}
 
-	dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%llx\n",
+	dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
 			(unsigned long long)llp);
 
 	list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
@@ -533,7 +533,7 @@ static void dw_dma_tasklet(unsigned long data)
 	status_xfer = dma_readl(dw, RAW.XFER);
 	status_err = dma_readl(dw, RAW.ERROR);
 
-	dev_vdbg(dw->dma.dev, "tasklet: status_err=%x\n", status_err);
+	dev_vdbg(dw->dma.dev, "%s: status_err=%x\n", __func__, status_err);
 
 	for (i = 0; i < dw->dma.chancnt; i++) {
 		dwc = &dw->chan[i];
@@ -557,7 +557,7 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
 	struct dw_dma *dw = dev_id;
 	u32 status;
 
-	dev_vdbg(dw->dma.dev, "interrupt: status=0x%x\n",
+	dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__,
 			dma_readl(dw, STATUS_INT));
 
 	/*
@@ -603,12 +603,12 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
 	 * for DMA. But this is hard to do in a race-free manner.
 	 */
 	if (list_empty(&dwc->active_list)) {
-		dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
+		dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__,
 				desc->txd.cookie);
 		list_add_tail(&desc->desc_node, &dwc->active_list);
 		dwc_dostart(dwc, dwc_first_active(dwc));
 	} else {
-		dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
+		dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__,
 				desc->txd.cookie);
 
 		list_add_tail(&desc->desc_node, &dwc->queue);
@@ -634,12 +634,12 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 	u32			ctllo;
 
 	dev_vdbg(chan2dev(chan),
-			"prep_dma_memcpy d0x%llx s0x%llx l0x%zx f0x%lx\n",
+			"%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
 			(unsigned long long)dest, (unsigned long long)src,
 			len, flags);
 
 	if (unlikely(!len)) {
-		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
+		dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
 		return NULL;
 	}
 
@@ -728,7 +728,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	struct scatterlist	*sg;
 	size_t			total_len = 0;
 
-	dev_vdbg(chan2dev(chan), "prep_dma_slave\n");
+	dev_vdbg(chan2dev(chan), "%s\n", __func__);
 
 	if (unlikely(!dws || !sg_len))
 		return NULL;
@@ -1022,7 +1022,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
 	int			i;
 	unsigned long		flags;
 
-	dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
+	dev_vdbg(chan2dev(chan), "%s\n", __func__);
 
 	/* ASSERT:  channel is idle */
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
@@ -1065,8 +1065,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-	dev_dbg(chan2dev(chan),
-		"alloc_chan_resources allocated %d descriptors\n", i);
+	dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i);
 
 	return i;
 }
@@ -1079,7 +1078,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
 	unsigned long		flags;
 	LIST_HEAD(list);
 
-	dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n",
+	dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__,
 			dwc->descs_allocated);
 
 	/* ASSERT:  channel is idle */
@@ -1105,7 +1104,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
 		kfree(desc);
 	}
 
-	dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
+	dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
 }
 
 /* --------------------- Cyclic DMA API extensions -------------------- */
@@ -1342,7 +1341,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan)
 	int			i;
 	unsigned long		flags;
 
-	dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
+	dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__);
 
 	if (!cdesc)
 		return;
-- 
1.7.10


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

* [PATCH 6/9] dw_dmac: disable dma in optimal way in probe
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                   ` (4 preceding siblings ...)
  2012-06-15  7:05 ` [PATCH 5/9] dw_dmac: use __func__ constant in the debug prints Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 7/9] dw_dmac: disable BLOCK interrupts Andy Shevchenko
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

The dw_dma_off call needs to have the all_chan_mask calculated. So, done this
calculations before the call. Moreover, remove duplicate code that masks the
DMA interrupts.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index e2ea243..cffe630 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1433,6 +1433,9 @@ static int __init dw_probe(struct platform_device *pdev)
 	}
 	clk_prepare_enable(dw->clk);
 
+	/* Calculate all channel mask before DMA setup */
+	dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
+
 	/* force dma off, just in case */
 	dw_dma_off(dw);
 
@@ -1444,8 +1447,6 @@ static int __init dw_probe(struct platform_device *pdev)
 
 	tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
 
-	dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
-
 	INIT_LIST_HEAD(&dw->dma.channels);
 	for (i = 0; i < pdata->nr_channels; i++) {
 		struct dw_dma_chan	*dwc = &dw->chan[i];
@@ -1481,11 +1482,6 @@ static int __init dw_probe(struct platform_device *pdev)
 	dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
 
-	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
-
 	dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
 	dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
 	if (pdata->is_private)
-- 
1.7.10


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

* [PATCH 7/9] dw_dmac: disable BLOCK interrupts
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                   ` (5 preceding siblings ...)
  2012-06-15  7:05 ` [PATCH 6/9] dw_dmac: disable dma in optimal way in probe Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 8/9] dw_dmac: introduce dwc_fast_fls() Andy Shevchenko
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

Just to be sure we are in known state we disable the BLOCK interupts.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index cffe630..b2586bd 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -575,6 +575,7 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
 
 		/* Try to recover */
 		channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1);
+		channel_clear_bit(dw, MASK.BLOCK, (1 << 8) - 1);
 		channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1);
 		channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1);
 		channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1);
@@ -1376,6 +1377,7 @@ static void dw_dma_off(struct dw_dma *dw)
 	dma_writel(dw, CFG, 0);
 
 	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
@@ -1478,6 +1480,7 @@ static int __init dw_probe(struct platform_device *pdev)
 
 	/* Clear/disable all interrupts on all channels. */
 	dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
+	dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
-- 
1.7.10


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

* [PATCH 8/9] dw_dmac: introduce dwc_fast_fls()
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                   ` (6 preceding siblings ...)
  2012-06-15  7:05 ` [PATCH 7/9] dw_dmac: disable BLOCK interrupts Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-15  7:05 ` [PATCH 9/9] dw_dmac: move from __init to __devinit Andy Shevchenko
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

There were three places where such function is used. We still avoid to use
native fls() because in one case it requires to use 64bit version which is
suboptimal in our case.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   46 ++++++++++++++++++----------------------------
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index b2586bd..5d025d3 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -193,6 +193,21 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
 
 /*----------------------------------------------------------------------*/
 
+static inline unsigned int dwc_fast_fls(unsigned long long v)
+{
+	/*
+	 * We can be a lot more clever here, but this should take care
+	 * of the most common optimization.
+	 */
+	if (!(v & 7))
+		return 3;
+	else if (!(v & 3))
+		return 2;
+	else if (!(v & 1))
+		return 1;
+	return 0;
+}
+
 static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
 {
 	dev_err(chan2dev(&dwc->chan),
@@ -644,18 +659,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 		return NULL;
 	}
 
-	/*
-	 * We can be a lot more clever here, but this should take care
-	 * of the most common optimization.
-	 */
-	if (!((src | dest  | len) & 7))
-		src_width = dst_width = 3;
-	else if (!((src | dest  | len) & 3))
-		src_width = dst_width = 2;
-	else if (!((src | dest | len) & 1))
-		src_width = dst_width = 1;
-	else
-		src_width = dst_width = 0;
+	src_width = dst_width = dwc_fast_fls(src | dest | len);
 
 	ctllo = DWC_DEFAULT_CTLLO(chan)
 			| DWC_CTLL_DST_WIDTH(dst_width)
@@ -755,14 +759,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
-			if (!((mem | len) & 7))
-				mem_width = 3;
-			else if (!((mem | len) & 3))
-				mem_width = 2;
-			else if (!((mem | len) & 1))
-				mem_width = 1;
-			else
-				mem_width = 0;
+			mem_width = dwc_fast_fls(mem | len);
 
 slave_sg_todev_fill_desc:
 			desc = dwc_desc_get(dwc);
@@ -822,14 +819,7 @@ slave_sg_todev_fill_desc:
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
-			if (!((mem | len) & 7))
-				mem_width = 3;
-			else if (!((mem | len) & 3))
-				mem_width = 2;
-			else if (!((mem | len) & 1))
-				mem_width = 1;
-			else
-				mem_width = 0;
+			mem_width = dwc_fast_fls(mem | len);
 
 slave_sg_fromdev_fill_desc:
 			desc = dwc_desc_get(dwc);
-- 
1.7.10


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

* [PATCH 9/9] dw_dmac: move from __init to __devinit
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                   ` (7 preceding siblings ...)
  2012-06-15  7:05 ` [PATCH 8/9] dw_dmac: introduce dwc_fast_fls() Andy Shevchenko
@ 2012-06-15  7:05 ` Andy Shevchenko
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
  9 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-15  7:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Andy Shevchenko

We usually have more than one DMA device. Thus, the probe function should serve
for all of them in case when the driver is built as a module.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 5d025d3..5217f71 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1379,7 +1379,7 @@ static void dw_dma_off(struct dw_dma *dw)
 		dw->chan[i].initialized = false;
 }
 
-static int __init dw_probe(struct platform_device *pdev)
+static int __devinit dw_probe(struct platform_device *pdev)
 {
 	struct dw_dma_platform_data *pdata;
 	struct resource		*io;
@@ -1513,7 +1513,7 @@ err_kfree:
 	return err;
 }
 
-static int __exit dw_remove(struct platform_device *pdev)
+static int __devexit dw_remove(struct platform_device *pdev)
 {
 	struct dw_dma		*dw = platform_get_drvdata(pdev);
 	struct dw_dma_chan	*dwc, *_dwc;
@@ -1592,7 +1592,7 @@ MODULE_DEVICE_TABLE(of, dw_dma_id_table);
 #endif
 
 static struct platform_driver dw_driver = {
-	.remove		= __exit_p(dw_remove),
+	.remove		= __devexit_p(dw_remove),
 	.shutdown	= dw_shutdown,
 	.driver = {
 		.name	= "dw_dmac",
-- 
1.7.10


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

* [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes
  2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                   ` (8 preceding siblings ...)
  2012-06-15  7:05 ` [PATCH 9/9] dw_dmac: move from __init to __devinit Andy Shevchenko
@ 2012-06-19 10:34 ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 01/10] dw_dmac: fix constant in the comment Andy Shevchenko
                     ` (11 more replies)
  9 siblings, 12 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

This patchset provides set of the cleanups and small fixes against the
DesignWare DMA controller driver. It's a first portion of the patches to make
the driver usable on other platforms.

since v1:
 - add dwc_chan_reset
 - disable block interrupts only in probe (discussed with Viresh Kumar)
 - fix comment line in probe in patch 6

Andy Shevchenko (10):
  dw_dmac: fix constant in the comment
  dw_dmac: use proper casting to print dma_addr_t values
  dw_dmac: introduce dwc_dump_chan_regs to dump registers
  dw_dmac: print correct number of scanned descriptors
  dw_dmac: use __func__ constant in the debug prints
  dw_dmac: disable dma in optimal way in probe
  dw_dmac: disable BLOCK interrupts
  dw_dmac: introduce dwc_fast_fls()
  dw_dmac: move from __init to __devinit
  dw_dmac: introduce dwc_chan_reset

 drivers/dma/dw_dmac.c      |  183 ++++++++++++++++++++------------------------
 drivers/dma/dw_dmac_regs.h |    2 +-
 2 files changed, 85 insertions(+), 100 deletions(-)

-- 
1.7.10


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

* [PATCHv2 01/10] dw_dmac: fix constant in the comment
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 02/10] dw_dmac: use proper casting to print dma_addr_t values Andy Shevchenko
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac_regs.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index f298f69..e248481 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -82,7 +82,7 @@ struct dw_dma_regs {
 	DW_REG(ID);
 	DW_REG(TEST);
 
-	/* optional encoded params, 0x3c8..0x3 */
+	/* optional encoded params, 0x3c8..0x3f7 */
 };
 
 /* Bitfields in CTL_LO */
-- 
1.7.10


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

* [PATCHv2 02/10] dw_dmac: use proper casting to print dma_addr_t values
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 01/10] dw_dmac: fix constant in the comment Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 03/10] dw_dmac: introduce dwc_dump_chan_regs to dump registers Andy Shevchenko
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

dma_addr_t is sometimes 32 bit and sometimes 64. We normally cast them to
unsigned long long for printk().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index adbc616..45861b6 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -339,7 +339,8 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 		return;
 	}
 
-	dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp);
+	dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%llx\n",
+			(unsigned long long)llp);
 
 	list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
 		/* check first descriptors addr */
@@ -389,8 +390,10 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
 {
 	dev_printk(KERN_CRIT, chan2dev(&dwc->chan),
-			"  desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
-			lli->sar, lli->dar, lli->llp,
+			"  desc: s0x%llx d0x%llx l0x%llx c0x%x:%x\n",
+			(unsigned long long)lli->sar,
+			(unsigned long long)lli->dar,
+			(unsigned long long)lli->llp,
 			lli->ctlhi, lli->ctllo);
 }
 
@@ -629,8 +632,10 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 	unsigned int		dst_width;
 	u32			ctllo;
 
-	dev_vdbg(chan2dev(chan), "prep_dma_memcpy d0x%x s0x%x l0x%zx f0x%lx\n",
-			dest, src, len, flags);
+	dev_vdbg(chan2dev(chan),
+			"prep_dma_memcpy d0x%llx s0x%llx l0x%zx f0x%lx\n",
+			(unsigned long long)dest, (unsigned long long)src,
+			len, flags);
 
 	if (unlikely(!len)) {
 		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
@@ -1310,9 +1315,9 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
 	dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
 			sizeof(last->lli), DMA_TO_DEVICE);
 
-	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu "
-			"period %zu periods %d\n", buf_addr, buf_len,
-			period_len, periods);
+	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
+			"period %zu periods %d\n", (unsigned long long)buf_addr,
+			buf_len, period_len, periods);
 
 	cdesc->periods = periods;
 	dwc->cdesc = cdesc;
-- 
1.7.10


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

* [PATCHv2 03/10] dw_dmac: introduce dwc_dump_chan_regs to dump registers
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 01/10] dw_dmac: fix constant in the comment Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 02/10] dw_dmac: use proper casting to print dma_addr_t values Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 04/10] dw_dmac: print correct number of scanned descriptors Andy Shevchenko
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

There is three places where values of the most significant registers were
printed. Make such piece of code as separate function.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   37 ++++++++++++++++---------------------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 45861b6..b6251dc 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -193,6 +193,19 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
 
 /*----------------------------------------------------------------------*/
 
+static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
+{
+	dev_err(chan2dev(&dwc->chan),
+		"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+		channel_readl(dwc, SAR),
+		channel_readl(dwc, DAR),
+		channel_readl(dwc, LLP),
+		channel_readl(dwc, CTL_HI),
+		channel_readl(dwc, CTL_LO));
+}
+
+/*----------------------------------------------------------------------*/
+
 /* Called with dwc->lock held and bh disabled */
 static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
 {
@@ -202,13 +215,7 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
 		dev_err(chan2dev(&dwc->chan),
 			"BUG: Attempted to start non-idle channel\n");
-		dev_err(chan2dev(&dwc->chan),
-			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
-			channel_readl(dwc, SAR),
-			channel_readl(dwc, DAR),
-			channel_readl(dwc, LLP),
-			channel_readl(dwc, CTL_HI),
-			channel_readl(dwc, CTL_LO));
+		dwc_dump_chan_regs(dwc);
 
 		/* The tasklet will hopefully advance the queue... */
 		return;
@@ -492,13 +499,7 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
 
 		spin_lock_irqsave(&dwc->lock, flags);
 
-		dev_err(chan2dev(&dwc->chan),
-			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
-			channel_readl(dwc, SAR),
-			channel_readl(dwc, DAR),
-			channel_readl(dwc, LLP),
-			channel_readl(dwc, CTL_HI),
-			channel_readl(dwc, CTL_LO));
+		dwc_dump_chan_regs(dwc);
 
 		channel_clear_bit(dw, CH_EN, dwc->mask);
 		while (dma_readl(dw, CH_EN) & dwc->mask)
@@ -1133,13 +1134,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan)
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
 		dev_err(chan2dev(&dwc->chan),
 			"BUG: Attempted to start non-idle channel\n");
-		dev_err(chan2dev(&dwc->chan),
-			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
-			channel_readl(dwc, SAR),
-			channel_readl(dwc, DAR),
-			channel_readl(dwc, LLP),
-			channel_readl(dwc, CTL_HI),
-			channel_readl(dwc, CTL_LO));
+		dwc_dump_chan_regs(dwc);
 		spin_unlock_irqrestore(&dwc->lock, flags);
 		return -EBUSY;
 	}
-- 
1.7.10


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

* [PATCHv2 04/10] dw_dmac: print correct number of scanned descriptors
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (2 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 03/10] dw_dmac: introduce dwc_dump_chan_regs to dump registers Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 05/10] dw_dmac: use __func__ constant in the debug prints Andy Shevchenko
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

In case the first descriptor we found is available, the counter still remains 0
value which is wrong. This patch fixes the counter behaviour.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index b6251dc..763730a 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -107,13 +107,13 @@ static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
+		i++;
 		if (async_tx_test_ack(&desc->txd)) {
 			list_del(&desc->desc_node);
 			ret = desc;
 			break;
 		}
 		dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc);
-		i++;
 	}
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-- 
1.7.10


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

* [PATCHv2 05/10] dw_dmac: use __func__ constant in the debug prints
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (3 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 04/10] dw_dmac: print correct number of scanned descriptors Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 06/10] dw_dmac: disable dma in optimal way in probe Andy Shevchenko
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 763730a..e2ea243 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -346,7 +346,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 		return;
 	}
 
-	dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%llx\n",
+	dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
 			(unsigned long long)llp);
 
 	list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
@@ -533,7 +533,7 @@ static void dw_dma_tasklet(unsigned long data)
 	status_xfer = dma_readl(dw, RAW.XFER);
 	status_err = dma_readl(dw, RAW.ERROR);
 
-	dev_vdbg(dw->dma.dev, "tasklet: status_err=%x\n", status_err);
+	dev_vdbg(dw->dma.dev, "%s: status_err=%x\n", __func__, status_err);
 
 	for (i = 0; i < dw->dma.chancnt; i++) {
 		dwc = &dw->chan[i];
@@ -557,7 +557,7 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
 	struct dw_dma *dw = dev_id;
 	u32 status;
 
-	dev_vdbg(dw->dma.dev, "interrupt: status=0x%x\n",
+	dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__,
 			dma_readl(dw, STATUS_INT));
 
 	/*
@@ -603,12 +603,12 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
 	 * for DMA. But this is hard to do in a race-free manner.
 	 */
 	if (list_empty(&dwc->active_list)) {
-		dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
+		dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__,
 				desc->txd.cookie);
 		list_add_tail(&desc->desc_node, &dwc->active_list);
 		dwc_dostart(dwc, dwc_first_active(dwc));
 	} else {
-		dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
+		dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__,
 				desc->txd.cookie);
 
 		list_add_tail(&desc->desc_node, &dwc->queue);
@@ -634,12 +634,12 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 	u32			ctllo;
 
 	dev_vdbg(chan2dev(chan),
-			"prep_dma_memcpy d0x%llx s0x%llx l0x%zx f0x%lx\n",
+			"%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
 			(unsigned long long)dest, (unsigned long long)src,
 			len, flags);
 
 	if (unlikely(!len)) {
-		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
+		dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
 		return NULL;
 	}
 
@@ -728,7 +728,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 	struct scatterlist	*sg;
 	size_t			total_len = 0;
 
-	dev_vdbg(chan2dev(chan), "prep_dma_slave\n");
+	dev_vdbg(chan2dev(chan), "%s\n", __func__);
 
 	if (unlikely(!dws || !sg_len))
 		return NULL;
@@ -1022,7 +1022,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
 	int			i;
 	unsigned long		flags;
 
-	dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
+	dev_vdbg(chan2dev(chan), "%s\n", __func__);
 
 	/* ASSERT:  channel is idle */
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
@@ -1065,8 +1065,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-	dev_dbg(chan2dev(chan),
-		"alloc_chan_resources allocated %d descriptors\n", i);
+	dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i);
 
 	return i;
 }
@@ -1079,7 +1078,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
 	unsigned long		flags;
 	LIST_HEAD(list);
 
-	dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n",
+	dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__,
 			dwc->descs_allocated);
 
 	/* ASSERT:  channel is idle */
@@ -1105,7 +1104,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
 		kfree(desc);
 	}
 
-	dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
+	dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
 }
 
 /* --------------------- Cyclic DMA API extensions -------------------- */
@@ -1342,7 +1341,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan)
 	int			i;
 	unsigned long		flags;
 
-	dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
+	dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__);
 
 	if (!cdesc)
 		return;
-- 
1.7.10


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

* [PATCHv2 06/10] dw_dmac: disable dma in optimal way in probe
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (4 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 05/10] dw_dmac: use __func__ constant in the debug prints Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 07/10] dw_dmac: disable BLOCK interrupts Andy Shevchenko
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

The dw_dma_off call needs to have the all_chan_mask calculated. So, done this
calculations before the call. Moreover, remove duplicate code that masks the
DMA interrupts.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index e2ea243..23a409b 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1433,6 +1433,9 @@ static int __init dw_probe(struct platform_device *pdev)
 	}
 	clk_prepare_enable(dw->clk);
 
+	/* Calculate all channel mask before DMA setup */
+	dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
+
 	/* force dma off, just in case */
 	dw_dma_off(dw);
 
@@ -1444,8 +1447,6 @@ static int __init dw_probe(struct platform_device *pdev)
 
 	tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
 
-	dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
-
 	INIT_LIST_HEAD(&dw->dma.channels);
 	for (i = 0; i < pdata->nr_channels; i++) {
 		struct dw_dma_chan	*dwc = &dw->chan[i];
@@ -1475,17 +1476,12 @@ static int __init dw_probe(struct platform_device *pdev)
 		channel_clear_bit(dw, CH_EN, dwc->mask);
 	}
 
-	/* Clear/disable all interrupts on all channels. */
+	/* Clear all interrupts on all channels. */
 	dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
 
-	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
-
 	dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
 	dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
 	if (pdata->is_private)
-- 
1.7.10


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

* [PATCHv2 07/10] dw_dmac: disable BLOCK interrupts
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (5 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 06/10] dw_dmac: disable dma in optimal way in probe Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 08/10] dw_dmac: introduce dwc_fast_fls() Andy Shevchenko
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

Just to be sure we are in known state we disable the BLOCK interupts.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 23a409b..42cffe8 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1439,6 +1439,9 @@ static int __init dw_probe(struct platform_device *pdev)
 	/* force dma off, just in case */
 	dw_dma_off(dw);
 
+	/* disable BLOCK interrupts as well */
+	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+
 	err = request_irq(irq, dw_dma_interrupt, 0, "dw_dmac", dw);
 	if (err)
 		goto err_irq;
@@ -1478,6 +1481,7 @@ static int __init dw_probe(struct platform_device *pdev)
 
 	/* Clear all interrupts on all channels. */
 	dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
+	dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
 	dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
-- 
1.7.10


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

* [PATCHv2 08/10] dw_dmac: introduce dwc_fast_fls()
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (6 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 07/10] dw_dmac: disable BLOCK interrupts Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 09/10] dw_dmac: move from __init to __devinit Andy Shevchenko
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

There were three places where such function is used. We still avoid to use
native fls() because in one case it requires to use 64bit version which is
suboptimal in our case.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   46 ++++++++++++++++++----------------------------
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 42cffe8..9c47279 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -193,6 +193,21 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
 
 /*----------------------------------------------------------------------*/
 
+static inline unsigned int dwc_fast_fls(unsigned long long v)
+{
+	/*
+	 * We can be a lot more clever here, but this should take care
+	 * of the most common optimization.
+	 */
+	if (!(v & 7))
+		return 3;
+	else if (!(v & 3))
+		return 2;
+	else if (!(v & 1))
+		return 1;
+	return 0;
+}
+
 static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
 {
 	dev_err(chan2dev(&dwc->chan),
@@ -643,18 +658,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 		return NULL;
 	}
 
-	/*
-	 * We can be a lot more clever here, but this should take care
-	 * of the most common optimization.
-	 */
-	if (!((src | dest  | len) & 7))
-		src_width = dst_width = 3;
-	else if (!((src | dest  | len) & 3))
-		src_width = dst_width = 2;
-	else if (!((src | dest | len) & 1))
-		src_width = dst_width = 1;
-	else
-		src_width = dst_width = 0;
+	src_width = dst_width = dwc_fast_fls(src | dest | len);
 
 	ctllo = DWC_DEFAULT_CTLLO(chan)
 			| DWC_CTLL_DST_WIDTH(dst_width)
@@ -754,14 +758,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
-			if (!((mem | len) & 7))
-				mem_width = 3;
-			else if (!((mem | len) & 3))
-				mem_width = 2;
-			else if (!((mem | len) & 1))
-				mem_width = 1;
-			else
-				mem_width = 0;
+			mem_width = dwc_fast_fls(mem | len);
 
 slave_sg_todev_fill_desc:
 			desc = dwc_desc_get(dwc);
@@ -821,14 +818,7 @@ slave_sg_todev_fill_desc:
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
-			if (!((mem | len) & 7))
-				mem_width = 3;
-			else if (!((mem | len) & 3))
-				mem_width = 2;
-			else if (!((mem | len) & 1))
-				mem_width = 1;
-			else
-				mem_width = 0;
+			mem_width = dwc_fast_fls(mem | len);
 
 slave_sg_fromdev_fill_desc:
 			desc = dwc_desc_get(dwc);
-- 
1.7.10


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

* [PATCHv2 09/10] dw_dmac: move from __init to __devinit
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (7 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 08/10] dw_dmac: introduce dwc_fast_fls() Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:34   ` [PATCHv2 10/10] dw_dmac: introduce dwc_chan_reset Andy Shevchenko
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

We usually have more than one DMA device. Thus, the probe function should serve
for all of them in case when the driver is built as a module.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 9c47279..d3845ef 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1377,7 +1377,7 @@ static void dw_dma_off(struct dw_dma *dw)
 		dw->chan[i].initialized = false;
 }
 
-static int __init dw_probe(struct platform_device *pdev)
+static int __devinit dw_probe(struct platform_device *pdev)
 {
 	struct dw_dma_platform_data *pdata;
 	struct resource		*io;
@@ -1514,7 +1514,7 @@ err_kfree:
 	return err;
 }
 
-static int __exit dw_remove(struct platform_device *pdev)
+static int __devexit dw_remove(struct platform_device *pdev)
 {
 	struct dw_dma		*dw = platform_get_drvdata(pdev);
 	struct dw_dma_chan	*dwc, *_dwc;
@@ -1593,7 +1593,7 @@ MODULE_DEVICE_TABLE(of, dw_dma_id_table);
 #endif
 
 static struct platform_driver dw_driver = {
-	.remove		= __exit_p(dw_remove),
+	.remove		= __devexit_p(dw_remove),
 	.shutdown	= dw_shutdown,
 	.driver = {
 		.name	= "dw_dmac",
-- 
1.7.10


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

* [PATCHv2 10/10] dw_dmac: introduce dwc_chan_reset
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (8 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 09/10] dw_dmac: move from __init to __devinit Andy Shevchenko
@ 2012-06-19 10:34   ` Andy Shevchenko
  2012-06-19 10:39     ` viresh kumar
  2012-06-19 10:40   ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes viresh kumar
  2012-06-21  2:39   ` Vinod Koul
  11 siblings, 1 reply; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

This piece of code is used often. Make it as a separate function.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index d3845ef..14fbee4 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -219,6 +219,14 @@ static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
 		channel_readl(dwc, CTL_LO));
 }
 
+
+static inline void dwc_chan_reset(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+	channel_clear_bit(dw, CH_EN, dwc->mask);
+	while (dma_readl(dw, CH_EN) & dwc->mask)
+		cpu_relax();
+}
+
 /*----------------------------------------------------------------------*/
 
 /* Called with dwc->lock held and bh disabled */
@@ -314,9 +322,7 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
 			"BUG: XFER bit set, but channel not idle!\n");
 
 		/* Try to continue after resetting the channel... */
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-		while (dma_readl(dw, CH_EN) & dwc->mask)
-			cpu_relax();
+		dwc_chan_reset(dw, dwc);
 	}
 
 	/*
@@ -398,9 +404,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 		"BUG: All descriptors done, but channel not idle!\n");
 
 	/* Try to continue after resetting the channel... */
-	channel_clear_bit(dw, CH_EN, dwc->mask);
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
+	dwc_chan_reset(dw, dwc);
 
 	if (!list_empty(&dwc->queue)) {
 		list_move(dwc->queue.next, &dwc->active_list);
@@ -516,9 +520,7 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
 
 		dwc_dump_chan_regs(dwc);
 
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-		while (dma_readl(dw, CH_EN) & dwc->mask)
-			cpu_relax();
+		dwc_chan_reset(dw, dwc);
 
 		/* make sure DMA does not restart by loading a new list */
 		channel_writel(dwc, LLP, 0);
@@ -948,9 +950,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 	} else if (cmd == DMA_TERMINATE_ALL) {
 		spin_lock_irqsave(&dwc->lock, flags);
 
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-		while (dma_readl(dw, CH_EN) & dwc->mask)
-			cpu_relax();
+		dwc_chan_reset(dw, dwc);
 
 		dwc->paused = false;
 
@@ -1158,9 +1158,7 @@ void dw_dma_cyclic_stop(struct dma_chan *chan)
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	channel_clear_bit(dw, CH_EN, dwc->mask);
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
+	dwc_chan_reset(dw, dwc);
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
 }
@@ -1338,9 +1336,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan)
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	channel_clear_bit(dw, CH_EN, dwc->mask);
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
+	dwc_chan_reset(dw, dwc);
 
 	dma_writel(dw, CLEAR.ERROR, dwc->mask);
 	dma_writel(dw, CLEAR.XFER, dwc->mask);
-- 
1.7.10


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

* Re: [PATCHv2 10/10] dw_dmac: introduce dwc_chan_reset
  2012-06-19 10:34   ` [PATCHv2 10/10] dw_dmac: introduce dwc_chan_reset Andy Shevchenko
@ 2012-06-19 10:39     ` viresh kumar
  2012-06-19 10:46       ` [PATCHv2.1] dw_dmac: introduce dwc_chan_disable Andy Shevchenko
  0 siblings, 1 reply; 27+ messages in thread
From: viresh kumar @ 2012-06-19 10:39 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-kernel, Vinod Koul, Dan Williams, spear-devel

On Tue, Jun 19, 2012 at 11:34 AM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> This piece of code is used often. Make it as a separate function.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/dma/dw_dmac.c |   32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
> index d3845ef..14fbee4 100644
> --- a/drivers/dma/dw_dmac.c
> +++ b/drivers/dma/dw_dmac.c
> @@ -219,6 +219,14 @@ static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
>                channel_readl(dwc, CTL_LO));
>  }
>
> +
> +static inline void dwc_chan_reset(struct dw_dma *dw, struct dw_dma_chan *dwc)
> +{
> +       channel_clear_bit(dw, CH_EN, dwc->mask);
> +       while (dma_readl(dw, CH_EN) & dwc->mask)
> +               cpu_relax();
> +}

Hmm... This is not really a reset but disable.

Can you consider naming it more closer to what it is doing?

--
viresh

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

* Re: [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (9 preceding siblings ...)
  2012-06-19 10:34   ` [PATCHv2 10/10] dw_dmac: introduce dwc_chan_reset Andy Shevchenko
@ 2012-06-19 10:40   ` viresh kumar
  2012-06-21  2:39   ` Vinod Koul
  11 siblings, 0 replies; 27+ messages in thread
From: viresh kumar @ 2012-06-19 10:40 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-kernel, Vinod Koul, Dan Williams, spear-devel

On Tue, Jun 19, 2012 at 11:34 AM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> This patchset provides set of the cleanups and small fixes against the
> DesignWare DMA controller driver. It's a first portion of the patches to make
> the driver usable on other platforms.
>
> since v1:
>  - add dwc_chan_reset
>  - disable block interrupts only in probe (discussed with Viresh Kumar)
>  - fix comment line in probe in patch 6
>
> Andy Shevchenko (10):
>  dw_dmac: fix constant in the comment
>  dw_dmac: use proper casting to print dma_addr_t values
>  dw_dmac: introduce dwc_dump_chan_regs to dump registers
>  dw_dmac: print correct number of scanned descriptors
>  dw_dmac: use __func__ constant in the debug prints
>  dw_dmac: disable dma in optimal way in probe
>  dw_dmac: disable BLOCK interrupts
>  dw_dmac: introduce dwc_fast_fls()
>  dw_dmac: move from __init to __devinit
>  dw_dmac: introduce dwc_chan_reset

Leaving minor comment on Patch 10/10, It Looks good.

Acked-by: Viresh Kumar <viresh.linux@gmail.com>

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

* [PATCHv2.1] dw_dmac: introduce dwc_chan_disable
  2012-06-19 10:39     ` viresh kumar
@ 2012-06-19 10:46       ` Andy Shevchenko
  2012-06-19 10:52         ` viresh kumar
  2012-06-21  2:39         ` Vinod Koul
  0 siblings, 2 replies; 27+ messages in thread
From: Andy Shevchenko @ 2012-06-19 10:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: Viresh Kumar, Vinod Koul, Dan Williams, Andy Shevchenko

This piece of code is used often. Make it as a separate function.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw_dmac.c |   32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index d3845ef..cefc2c3b 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -219,6 +219,14 @@ static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
 		channel_readl(dwc, CTL_LO));
 }
 
+
+static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+	channel_clear_bit(dw, CH_EN, dwc->mask);
+	while (dma_readl(dw, CH_EN) & dwc->mask)
+		cpu_relax();
+}
+
 /*----------------------------------------------------------------------*/
 
 /* Called with dwc->lock held and bh disabled */
@@ -314,9 +322,7 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
 			"BUG: XFER bit set, but channel not idle!\n");
 
 		/* Try to continue after resetting the channel... */
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-		while (dma_readl(dw, CH_EN) & dwc->mask)
-			cpu_relax();
+		dwc_chan_disable(dw, dwc);
 	}
 
 	/*
@@ -398,9 +404,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
 		"BUG: All descriptors done, but channel not idle!\n");
 
 	/* Try to continue after resetting the channel... */
-	channel_clear_bit(dw, CH_EN, dwc->mask);
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
+	dwc_chan_disable(dw, dwc);
 
 	if (!list_empty(&dwc->queue)) {
 		list_move(dwc->queue.next, &dwc->active_list);
@@ -516,9 +520,7 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
 
 		dwc_dump_chan_regs(dwc);
 
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-		while (dma_readl(dw, CH_EN) & dwc->mask)
-			cpu_relax();
+		dwc_chan_disable(dw, dwc);
 
 		/* make sure DMA does not restart by loading a new list */
 		channel_writel(dwc, LLP, 0);
@@ -948,9 +950,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 	} else if (cmd == DMA_TERMINATE_ALL) {
 		spin_lock_irqsave(&dwc->lock, flags);
 
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-		while (dma_readl(dw, CH_EN) & dwc->mask)
-			cpu_relax();
+		dwc_chan_disable(dw, dwc);
 
 		dwc->paused = false;
 
@@ -1158,9 +1158,7 @@ void dw_dma_cyclic_stop(struct dma_chan *chan)
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	channel_clear_bit(dw, CH_EN, dwc->mask);
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
+	dwc_chan_disable(dw, dwc);
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
 }
@@ -1338,9 +1336,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan)
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	channel_clear_bit(dw, CH_EN, dwc->mask);
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
+	dwc_chan_disable(dw, dwc);
 
 	dma_writel(dw, CLEAR.ERROR, dwc->mask);
 	dma_writel(dw, CLEAR.XFER, dwc->mask);
-- 
1.7.10


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

* Re: [PATCHv2.1] dw_dmac: introduce dwc_chan_disable
  2012-06-19 10:46       ` [PATCHv2.1] dw_dmac: introduce dwc_chan_disable Andy Shevchenko
@ 2012-06-19 10:52         ` viresh kumar
  2012-06-21  2:39         ` Vinod Koul
  1 sibling, 0 replies; 27+ messages in thread
From: viresh kumar @ 2012-06-19 10:52 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-kernel, Vinod Koul, Dan Williams, spear-devel

On Tue, Jun 19, 2012 at 11:46 AM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> This piece of code is used often. Make it as a separate function.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/dma/dw_dmac.c |   32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)

Perfect.

Acked-by: Viresh Kumar <viresh.linux@gmail.com>

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

* Re: [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes
  2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
                     ` (10 preceding siblings ...)
  2012-06-19 10:40   ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes viresh kumar
@ 2012-06-21  2:39   ` Vinod Koul
  11 siblings, 0 replies; 27+ messages in thread
From: Vinod Koul @ 2012-06-21  2:39 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-kernel, Viresh Kumar, Dan Williams

On Tue, 2012-06-19 at 13:34 +0300, Andy Shevchenko wrote:
> This patchset provides set of the cleanups and small fixes against the
> DesignWare DMA controller driver. It's a first portion of the patches to make
> the driver usable on other platforms.
Applied 1-9 in this. Thanks


-- 
~Vinod


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

* Re: [PATCHv2.1] dw_dmac: introduce dwc_chan_disable
  2012-06-19 10:46       ` [PATCHv2.1] dw_dmac: introduce dwc_chan_disable Andy Shevchenko
  2012-06-19 10:52         ` viresh kumar
@ 2012-06-21  2:39         ` Vinod Koul
  1 sibling, 0 replies; 27+ messages in thread
From: Vinod Koul @ 2012-06-21  2:39 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-kernel, Viresh Kumar, Dan Williams

On Tue, 2012-06-19 at 13:46 +0300, Andy Shevchenko wrote:
> This piece of code is used often. Make it as a separate function.
> 
Applied, Thanks

-- 
~Vinod


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

end of thread, other threads:[~2012-06-21  2:47 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-15  7:05 [PATCH 0/9] dw_dmac: set of cleanups and small fixes Andy Shevchenko
2012-06-15  7:05 ` [PATCH 1/9] dw_dmac: fix constant in the comment Andy Shevchenko
2012-06-15  7:05 ` [PATCH 2/9] dw_dmac: use proper casting to print dma_addr_t values Andy Shevchenko
2012-06-15  7:05 ` [PATCH 3/9] dw_dmac: introduce dwc_dump_chan_regs to dump registers Andy Shevchenko
2012-06-15  7:05 ` [PATCH 4/9] dw_dmac: print correct number of scanned descriptors Andy Shevchenko
2012-06-15  7:05 ` [PATCH 5/9] dw_dmac: use __func__ constant in the debug prints Andy Shevchenko
2012-06-15  7:05 ` [PATCH 6/9] dw_dmac: disable dma in optimal way in probe Andy Shevchenko
2012-06-15  7:05 ` [PATCH 7/9] dw_dmac: disable BLOCK interrupts Andy Shevchenko
2012-06-15  7:05 ` [PATCH 8/9] dw_dmac: introduce dwc_fast_fls() Andy Shevchenko
2012-06-15  7:05 ` [PATCH 9/9] dw_dmac: move from __init to __devinit Andy Shevchenko
2012-06-19 10:34 ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 01/10] dw_dmac: fix constant in the comment Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 02/10] dw_dmac: use proper casting to print dma_addr_t values Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 03/10] dw_dmac: introduce dwc_dump_chan_regs to dump registers Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 04/10] dw_dmac: print correct number of scanned descriptors Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 05/10] dw_dmac: use __func__ constant in the debug prints Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 06/10] dw_dmac: disable dma in optimal way in probe Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 07/10] dw_dmac: disable BLOCK interrupts Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 08/10] dw_dmac: introduce dwc_fast_fls() Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 09/10] dw_dmac: move from __init to __devinit Andy Shevchenko
2012-06-19 10:34   ` [PATCHv2 10/10] dw_dmac: introduce dwc_chan_reset Andy Shevchenko
2012-06-19 10:39     ` viresh kumar
2012-06-19 10:46       ` [PATCHv2.1] dw_dmac: introduce dwc_chan_disable Andy Shevchenko
2012-06-19 10:52         ` viresh kumar
2012-06-21  2:39         ` Vinod Koul
2012-06-19 10:40   ` [PATCHv2 00/10] dw_dmac: set of cleanups and small fixes viresh kumar
2012-06-21  2:39   ` Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox