linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Minor DMA fixes
@ 2010-11-30 13:23 Adrian Hunter
  2010-11-30 13:23 ` [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby Adrian Hunter
  2010-11-30 13:23 ` [PATCH 2/2] OMAP: DMA: clear interrupt status correctly Adrian Hunter
  0 siblings, 2 replies; 15+ messages in thread
From: Adrian Hunter @ 2010-11-30 13:23 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Santosh Shilimkar, Manjunatha GK, Adrian Hunter,
	linux-omap Mailing List

Hi

Adrian Hunter (2):
      OMAP: DMA: prevent races while setting M idle mode to nostandby
      OMAP: DMA: clear interrupt status correctly

 arch/arm/plat-omap/dma.c |   66 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 47 insertions(+), 19 deletions(-)
 
Regards
Adrian


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

* [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby
  2010-11-30 13:23 [PATCH 0/2] Minor DMA fixes Adrian Hunter
@ 2010-11-30 13:23 ` Adrian Hunter
  2010-11-30 14:24   ` Santosh Shilimkar
                     ` (2 more replies)
  2010-11-30 13:23 ` [PATCH 2/2] OMAP: DMA: clear interrupt status correctly Adrian Hunter
  1 sibling, 3 replies; 15+ messages in thread
From: Adrian Hunter @ 2010-11-30 13:23 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Adrian Hunter, Manjunatha GK, Santosh Shilimkar,
	linux-omap Mailing List

>From 8c0f4490d93b67326ff24f6ce1c7e925b08d96b3 Mon Sep 17 00:00:00 2001
From: Adrian Hunter <adrian.hunter@nokia.com>
Date: Mon, 22 Nov 2010 11:32:48 +0200
Subject: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby

In a couple of OMAP errata cases, sDMA M idle mode must be
set temporarily to nostandby.  If two DMA users were to do
that at the same time, a race condition would arise.
Prevent that by using a spin lock and counting up/down the
number of times nostandby is set/reset.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
---
 arch/arm/plat-omap/dma.c |   59 ++++++++++++++++++++++++++++++++++-----------
 1 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index a863f55..6158c99 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -139,6 +139,9 @@ static spinlock_t dma_chan_lock;
 static struct omap_dma_lch *dma_chan;
 static void __iomem *omap_dma_base;
 
+static u32 midlemode_saved;
+static int midlemode_save_cnt;
+
 static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
 	INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
 	INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
@@ -1016,6 +1019,41 @@ void omap_start_dma(int lch)
 }
 EXPORT_SYMBOL(omap_start_dma);
 
+static void midlemode_nostandby(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma_chan_lock, flags);
+	if (!midlemode_save_cnt) {
+		u32 l;
+
+		midlemode_saved = dma_read(OCP_SYSCONFIG);
+		l = midlemode_saved;
+		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
+		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
+		dma_write(l, OCP_SYSCONFIG);
+	}
+	midlemode_save_cnt += 1;
+	spin_unlock_irqrestore(&dma_chan_lock, flags);
+}
+
+static void midlemode_restore(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma_chan_lock, flags);
+	midlemode_save_cnt -= 1;
+	if (!midlemode_save_cnt) {
+		u32 l;
+
+		l = dma_read(OCP_SYSCONFIG);
+		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
+		l |= midlemode_saved & DMA_SYSCONFIG_MIDLEMODE_MASK;
+		dma_write(l, OCP_SYSCONFIG);
+	}
+	spin_unlock_irqrestore(&dma_chan_lock, flags);
+}
+
 void omap_stop_dma(int lch)
 {
 	u32 l;
@@ -1028,16 +1066,10 @@ void omap_stop_dma(int lch)
 	/* OMAP3 Errata i541: sDMA FIFO draining does not finish */
 	if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
 		int i = 0;
-		u32 sys_cf;
 
 		/* Configure No-Standby */
-		l = dma_read(OCP_SYSCONFIG);
-		sys_cf = l;
-		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
-		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
-		dma_write(l , OCP_SYSCONFIG);
+		midlemode_nostandby();
 
-		l = dma_read(CCR(lch));
 		l &= ~OMAP_DMA_CCR_EN;
 		dma_write(l, CCR(lch));
 
@@ -1053,7 +1085,7 @@ void omap_stop_dma(int lch)
 			printk(KERN_ERR "DMA drain did not complete on "
 					"lch %d\n", lch);
 		/* Restore OCP_SYSCONFIG */
-		dma_write(sys_cf, OCP_SYSCONFIG);
+		midlemode_restore();
 	} else {
 		l &= ~OMAP_DMA_CCR_EN;
 		dma_write(l, CCR(lch));
@@ -1711,7 +1743,6 @@ int omap_stop_dma_chain_transfers(int chain_id)
 {
 	int *channels;
 	u32 l, i;
-	u32 sys_cf;
 
 	/* Check for input params */
 	if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
@@ -1730,11 +1761,9 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	 * DMA Errata:
 	 * Special programming model needed to disable DMA before end of block
 	 */
-	sys_cf = dma_read(OCP_SYSCONFIG);
-	l = sys_cf;
-	/* Middle mode reg set no Standby */
-	l &= ~((1 << 12)|(1 << 13));
-	dma_write(l, OCP_SYSCONFIG);
+
+	/* M idle mode reg set no Standby */
+	midlemode_nostandby();
 
 	for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
 
@@ -1754,7 +1783,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	OMAP_DMA_CHAIN_QINIT(chain_id);
 
 	/* Errata - put in the old value */
-	dma_write(sys_cf, OCP_SYSCONFIG);
+	midlemode_restore();
 
 	return 0;
 }
-- 
1.7.0.4


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

* [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
  2010-11-30 13:23 [PATCH 0/2] Minor DMA fixes Adrian Hunter
  2010-11-30 13:23 ` [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby Adrian Hunter
@ 2010-11-30 13:23 ` Adrian Hunter
  2010-11-30 14:25   ` Santosh Shilimkar
  1 sibling, 1 reply; 15+ messages in thread
From: Adrian Hunter @ 2010-11-30 13:23 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Santosh Shilimkar, Manjunatha GK, Adrian Hunter,
	linux-omap Mailing List

>From 85934ded48552fde84b083575ac2006f1542324b Mon Sep 17 00:00:00 2001
From: Adrian Hunter <adrian.hunter@nokia.com>
Date: Wed, 24 Nov 2010 13:23:21 +0200
Subject: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly

When clearing the DMA channel, clear all status bits.

When handling a DMA interrupt, clear only the interrupt
status bits that have been read and are passed to the
channel's interrupt handler, not every status bit.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
---
 arch/arm/plat-omap/dma.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 6158c99..3300e67 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -49,7 +49,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
 #endif
 
 #define OMAP_DMA_ACTIVE			0x01
-#define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
+#define OMAP2_DMA_CSR_CLEAR_MASK	0xffffffff
 
 #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
 
@@ -2010,7 +2010,7 @@ static int omap2_dma_handle_ch(int ch)
 		printk(KERN_INFO "DMA misaligned error with device %d\n",
 		       dma_chan[ch].dev_id);
 
-	dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch));
+	dma_write(status, CSR(ch));
 	dma_write(1 << ch, IRQSTATUS_L0);
 	/* read back the register to flush the write */
 	dma_read(IRQSTATUS_L0);
@@ -2030,10 +2030,9 @@ static int omap2_dma_handle_ch(int ch)
 			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
 
 		status = dma_read(CSR(ch));
+		dma_write(status, CSR(ch));
 	}
 
-	dma_write(status, CSR(ch));
-
 	if (likely(dma_chan[ch].callback != NULL))
 		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
 
-- 
1.7.0.4


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

* RE: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby
  2010-11-30 13:23 ` [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby Adrian Hunter
@ 2010-11-30 14:24   ` Santosh Shilimkar
  2010-12-01 12:21   ` Peter Ujfalusi
  2010-12-01 19:11   ` G, Manjunath Kondaiah
  2 siblings, 0 replies; 15+ messages in thread
From: Santosh Shilimkar @ 2010-11-30 14:24 UTC (permalink / raw)
  To: Adrian Hunter, Tony Lindgren
  Cc: Manjunath Kondaiah G, linux-omap Mailing List

> -----Original Message-----
> From: Adrian Hunter [mailto:adrian.hunter@nokia.com]
> Sent: Tuesday, November 30, 2010 6:54 PM
> To: Tony Lindgren
> Cc: Adrian Hunter; Manjunatha GK; Santosh Shilimkar; linux-omap Mailing
> List
> Subject: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode
to
> nostandby
>
> From 8c0f4490d93b67326ff24f6ce1c7e925b08d96b3 Mon Sep 17 00:00:00 2001
> From: Adrian Hunter <adrian.hunter@nokia.com>
> Date: Mon, 22 Nov 2010 11:32:48 +0200
> Subject: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode
to
> nostandby
>
> In a couple of OMAP errata cases, sDMA M idle mode must be
> set temporarily to nostandby.  If two DMA users were to do
> that at the same time, a race condition would arise.
> Prevent that by using a spin lock and counting up/down the
> number of times nostandby is set/reset.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/plat-omap/dma.c |   59
++++++++++++++++++++++++++++++++++-------
> ----
>  1 files changed, 44 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
> index a863f55..6158c99 100644
> --- a/arch/arm/plat-omap/dma.c
> +++ b/arch/arm/plat-omap/dma.c
> @@ -139,6 +139,9 @@ static spinlock_t dma_chan_lock;
>  static struct omap_dma_lch *dma_chan;
>  static void __iomem *omap_dma_base;
>
> +static u32 midlemode_saved;
> +static int midlemode_save_cnt;
> +
>  static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
>  	INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
>  	INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
> @@ -1016,6 +1019,41 @@ void omap_start_dma(int lch)
>  }
>  EXPORT_SYMBOL(omap_start_dma);
>
> +static void midlemode_nostandby(void)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dma_chan_lock, flags);
> +	if (!midlemode_save_cnt) {
> +		u32 l;
> +
> +		midlemode_saved = dma_read(OCP_SYSCONFIG);
> +		l = midlemode_saved;
> +		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
> +		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
> +		dma_write(l, OCP_SYSCONFIG);
> +	}
> +	midlemode_save_cnt += 1;
> +	spin_unlock_irqrestore(&dma_chan_lock, flags);
> +}
> +
> +static void midlemode_restore(void)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dma_chan_lock, flags);
> +	midlemode_save_cnt -= 1;
> +	if (!midlemode_save_cnt) {
> +		u32 l;
> +
> +		l = dma_read(OCP_SYSCONFIG);
> +		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
> +		l |= midlemode_saved & DMA_SYSCONFIG_MIDLEMODE_MASK;
> +		dma_write(l, OCP_SYSCONFIG);
> +	}
> +	spin_unlock_irqrestore(&dma_chan_lock, flags);
> +}
> +
>  void omap_stop_dma(int lch)
>  {
>  	u32 l;
> @@ -1028,16 +1066,10 @@ void omap_stop_dma(int lch)
>  	/* OMAP3 Errata i541: sDMA FIFO draining does not finish */
>  	if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
>  		int i = 0;
> -		u32 sys_cf;
>
>  		/* Configure No-Standby */
> -		l = dma_read(OCP_SYSCONFIG);
> -		sys_cf = l;
> -		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
> -		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
> -		dma_write(l , OCP_SYSCONFIG);
> +		midlemode_nostandby();
>
> -		l = dma_read(CCR(lch));
>  		l &= ~OMAP_DMA_CCR_EN;
>  		dma_write(l, CCR(lch));
>
> @@ -1053,7 +1085,7 @@ void omap_stop_dma(int lch)
>  			printk(KERN_ERR "DMA drain did not complete on "
>  					"lch %d\n", lch);
>  		/* Restore OCP_SYSCONFIG */
> -		dma_write(sys_cf, OCP_SYSCONFIG);
> +		midlemode_restore();
>  	} else {
>  		l &= ~OMAP_DMA_CCR_EN;
>  		dma_write(l, CCR(lch));
> @@ -1711,7 +1743,6 @@ int omap_stop_dma_chain_transfers(int chain_id)
>  {
>  	int *channels;
>  	u32 l, i;
> -	u32 sys_cf;
>
>  	/* Check for input params */
>  	if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
> @@ -1730,11 +1761,9 @@ int omap_stop_dma_chain_transfers(int chain_id)
>  	 * DMA Errata:
>  	 * Special programming model needed to disable DMA before end of
> block
>  	 */
> -	sys_cf = dma_read(OCP_SYSCONFIG);
> -	l = sys_cf;
> -	/* Middle mode reg set no Standby */
> -	l &= ~((1 << 12)|(1 << 13));
> -	dma_write(l, OCP_SYSCONFIG);
> +
> +	/* M idle mode reg set no Standby */
> +	midlemode_nostandby();
>
>  	for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
>
> @@ -1754,7 +1783,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
>  	OMAP_DMA_CHAIN_QINIT(chain_id);
>
>  	/* Errata - put in the old value */
> -	dma_write(sys_cf, OCP_SYSCONFIG);
> +	midlemode_restore();
>
>  	return 0;
>  }
> --
> 1.7.0.4

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

* RE: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
  2010-11-30 13:23 ` [PATCH 2/2] OMAP: DMA: clear interrupt status correctly Adrian Hunter
@ 2010-11-30 14:25   ` Santosh Shilimkar
  2010-12-21 20:29     ` Tony Lindgren
  0 siblings, 1 reply; 15+ messages in thread
From: Santosh Shilimkar @ 2010-11-30 14:25 UTC (permalink / raw)
  To: Adrian Hunter, Tony Lindgren
  Cc: Manjunath Kondaiah G, linux-omap Mailing List

> -----Original Message-----
> From: Adrian Hunter [mailto:adrian.hunter@nokia.com]
> Sent: Tuesday, November 30, 2010 6:54 PM
> To: Tony Lindgren
> Cc: Santosh Shilimkar; Manjunatha GK; Adrian Hunter; linux-omap Mailing
> List
> Subject: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
>
> From 85934ded48552fde84b083575ac2006f1542324b Mon Sep 17 00:00:00 2001
> From: Adrian Hunter <adrian.hunter@nokia.com>
> Date: Wed, 24 Nov 2010 13:23:21 +0200
> Subject: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
>
> When clearing the DMA channel, clear all status bits.
>
> When handling a DMA interrupt, clear only the interrupt
> status bits that have been read and are passed to the
> channel's interrupt handler, not every status bit.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/plat-omap/dma.c |    7 +++----
>  1 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
> index 6158c99..3300e67 100644
> --- a/arch/arm/plat-omap/dma.c
> +++ b/arch/arm/plat-omap/dma.c
> @@ -49,7 +49,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
>  #endif
>
>  #define OMAP_DMA_ACTIVE			0x01
> -#define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
> +#define OMAP2_DMA_CSR_CLEAR_MASK	0xffffffff
>
>  #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
>
> @@ -2010,7 +2010,7 @@ static int omap2_dma_handle_ch(int ch)
>  		printk(KERN_INFO "DMA misaligned error with device %d\n",
>  		       dma_chan[ch].dev_id);
>
> -	dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch));
> +	dma_write(status, CSR(ch));
>  	dma_write(1 << ch, IRQSTATUS_L0);
>  	/* read back the register to flush the write */
>  	dma_read(IRQSTATUS_L0);
> @@ -2030,10 +2030,9 @@ static int omap2_dma_handle_ch(int ch)
>  			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
>
>  		status = dma_read(CSR(ch));
> +		dma_write(status, CSR(ch));
>  	}
>
> -	dma_write(status, CSR(ch));
> -
>  	if (likely(dma_chan[ch].callback != NULL))
>  		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
>
> --
> 1.7.0.4

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

* Re: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby
  2010-11-30 13:23 ` [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby Adrian Hunter
  2010-11-30 14:24   ` Santosh Shilimkar
@ 2010-12-01 12:21   ` Peter Ujfalusi
  2010-12-01 19:11   ` G, Manjunath Kondaiah
  2 siblings, 0 replies; 15+ messages in thread
From: Peter Ujfalusi @ 2010-12-01 12:21 UTC (permalink / raw)
  To: Hunter Adrian (Nokia-MS/Helsinki)
  Cc: Tony Lindgren, Manjunatha GK, Santosh Shilimkar,
	linux-omap Mailing List

On Tuesday 30 November 2010 15:23:47 Hunter Adrian (Nokia-MS/Helsinki) wrote:
> From 8c0f4490d93b67326ff24f6ce1c7e925b08d96b3 Mon Sep 17 00:00:00 2001
> From: Adrian Hunter <adrian.hunter@nokia.com>
> Date: Mon, 22 Nov 2010 11:32:48 +0200
> Subject: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to
> nostandby
> 
> In a couple of OMAP errata cases, sDMA M idle mode must be
> set temporarily to nostandby.  If two DMA users were to do
> that at the same time, a race condition would arise.
> Prevent that by using a spin lock and counting up/down the
> number of times nostandby is set/reset.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>

Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>

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

* Re: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby
  2010-11-30 13:23 ` [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby Adrian Hunter
  2010-11-30 14:24   ` Santosh Shilimkar
  2010-12-01 12:21   ` Peter Ujfalusi
@ 2010-12-01 19:11   ` G, Manjunath Kondaiah
  2 siblings, 0 replies; 15+ messages in thread
From: G, Manjunath Kondaiah @ 2010-12-01 19:11 UTC (permalink / raw)
  To: Adrian Hunter; +Cc: Tony Lindgren, Santosh Shilimkar, linux-omap Mailing List

Hi Adrian,

* Adrian Hunter <adrian.hunter@nokia.com> [2010-11-30 15:23:47 +0200]:

> From 8c0f4490d93b67326ff24f6ce1c7e925b08d96b3 Mon Sep 17 00:00:00 2001
> From: Adrian Hunter <adrian.hunter@nokia.com>
> Date: Mon, 22 Nov 2010 11:32:48 +0200
> Subject: [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby
> 
> In a couple of OMAP errata cases, sDMA M idle mode must be
> set temporarily to nostandby.  If two DMA users were to do
> that at the same time, a race condition would arise.
> Prevent that by using a spin lock and counting up/down the
> number of times nostandby is set/reset.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
> ---
>  arch/arm/plat-omap/dma.c |   59 ++++++++++++++++++++++++++++++++++-----------
>  1 files changed, 44 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
> index a863f55..6158c99 100644
> --- a/arch/arm/plat-omap/dma.c
> +++ b/arch/arm/plat-omap/dma.c
> @@ -139,6 +139,9 @@ static spinlock_t dma_chan_lock;
>  static struct omap_dma_lch *dma_chan;
>  static void __iomem *omap_dma_base;
>  
> +static u32 midlemode_saved;
> +static int midlemode_save_cnt;
> +
>  static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
>  	INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
>  	INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
> @@ -1016,6 +1019,41 @@ void omap_start_dma(int lch)
>  }
>  EXPORT_SYMBOL(omap_start_dma);
>  
> +static void midlemode_nostandby(void)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dma_chan_lock, flags);
> +	if (!midlemode_save_cnt) {
> +		u32 l;
> +
> +		midlemode_saved = dma_read(OCP_SYSCONFIG);
> +		l = midlemode_saved;
> +		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
> +		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
> +		dma_write(l, OCP_SYSCONFIG);
> +	}
> +	midlemode_save_cnt += 1;
> +	spin_unlock_irqrestore(&dma_chan_lock, flags);

The latest DMA hwmod patch series is already taken care of this
issue through the API's:
https://patchwork.kernel.org/patch/372231/

-Manjunath
[...]

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

* Re: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
  2010-11-30 14:25   ` Santosh Shilimkar
@ 2010-12-21 20:29     ` Tony Lindgren
  2011-01-05  9:58       ` Adrian Hunter
  0 siblings, 1 reply; 15+ messages in thread
From: Tony Lindgren @ 2010-12-21 20:29 UTC (permalink / raw)
  To: Santosh Shilimkar
  Cc: Adrian Hunter, Manjunath Kondaiah G, linux-omap Mailing List

* Santosh Shilimkar <santosh.shilimkar@ti.com> [101130 06:15]:
> > -----Original Message-----
> > From: Adrian Hunter [mailto:adrian.hunter@nokia.com]
> > Sent: Tuesday, November 30, 2010 6:54 PM
> > To: Tony Lindgren
> > Cc: Santosh Shilimkar; Manjunatha GK; Adrian Hunter; linux-omap Mailing
> > List
> > Subject: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
> >
> > From 85934ded48552fde84b083575ac2006f1542324b Mon Sep 17 00:00:00 2001
> > From: Adrian Hunter <adrian.hunter@nokia.com>
> > Date: Wed, 24 Nov 2010 13:23:21 +0200
> > Subject: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
> >
> > When clearing the DMA channel, clear all status bits.
> >
> > When handling a DMA interrupt, clear only the interrupt
> > status bits that have been read and are passed to the
> > channel's interrupt handler, not every status bit.
> >
> > Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Adrian, care to refresh this one against the devel-dma
branch that has the hwmod changes?

Looks like at least the CSR_CLEAR_MASK is still wrong
in the current code.

Regards,

Tony

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

* Re: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
  2010-12-21 20:29     ` Tony Lindgren
@ 2011-01-05  9:58       ` Adrian Hunter
  2011-01-05 17:27         ` Kevin Hilman
  0 siblings, 1 reply; 15+ messages in thread
From: Adrian Hunter @ 2011-01-05  9:58 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Santosh Shilimkar, Manjunath Kondaiah G, linux-omap Mailing List


 From fffa19df17d73c1ed2e8c65c0b6604ee1dddff84 Mon Sep 17 00:00:00 2001
From: Adrian Hunter <adrian.hunter@nokia.com>
Date: Wed, 24 Nov 2010 13:23:21 +0200
Subject: [PATCH] OMAP: DMA: clear interrupt status correctly

When clearing the DMA channel, clear all status bits.

When handling a DMA interrupt, clear only the interrupt
status bits that have been read and are passed to the
channel's interrupt handler, not every status bit.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
  arch/arm/plat-omap/dma.c |    7 +++----
  1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c4b2b47..8536308 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -53,7 +53,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
  #endif
  
  #define OMAP_DMA_ACTIVE			0x01
-#define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
+#define OMAP2_DMA_CSR_CLEAR_MASK	0xffffffff
  
  #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
  
@@ -1873,7 +1873,7 @@ static int omap2_dma_handle_ch(int ch)
  		printk(KERN_INFO "DMA misaligned error with device %d\n",
  		       dma_chan[ch].dev_id);
  
-	p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, ch);
+	p->dma_write(status, CSR, ch);
  	p->dma_write(1 << ch, IRQSTATUS_L0, ch);
  	/* read back the register to flush the write */
  	p->dma_read(IRQSTATUS_L0, ch);
@@ -1893,10 +1893,9 @@ static int omap2_dma_handle_ch(int ch)
  			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
  
  		status = p->dma_read(CSR, ch);
+		p->dma_write(status, CSR, ch);
  	}
  
-	p->dma_write(status, CSR, ch);
-
  	if (likely(dma_chan[ch].callback != NULL))
  		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
  
-- 
1.7.0.4

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

* Re: [PATCH 2/2] OMAP: DMA: clear interrupt status correctly
  2011-01-05  9:58       ` Adrian Hunter
@ 2011-01-05 17:27         ` Kevin Hilman
  2011-01-19 10:24           ` [PATCH] " Adrian Hunter
  0 siblings, 1 reply; 15+ messages in thread
From: Kevin Hilman @ 2011-01-05 17:27 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Tony Lindgren, Santosh Shilimkar, Manjunath Kondaiah G,
	linux-omap Mailing List

Adrian Hunter <adrian.hunter@nokia.com> writes:

> From fffa19df17d73c1ed2e8c65c0b6604ee1dddff84 Mon Sep 17 00:00:00 2001
> From: Adrian Hunter <adrian.hunter@nokia.com>
> Date: Wed, 24 Nov 2010 13:23:21 +0200
> Subject: [PATCH] OMAP: DMA: clear interrupt status correctly
>
> When clearing the DMA channel, clear all status bits.
>
> When handling a DMA interrupt, clear only the interrupt
> status bits that have been read and are passed to the
> channel's interrupt handler, not every status bit.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Looks like a fix that should go into 2.6.38-rc2.  Can you repost and Cc
linux-arm-kernel as well?

Thanks,

Kevin

> ---
>  arch/arm/plat-omap/dma.c |    7 +++----
>  1 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
> index c4b2b47..8536308 100644
> --- a/arch/arm/plat-omap/dma.c
> +++ b/arch/arm/plat-omap/dma.c
> @@ -53,7 +53,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
>  #endif
>  #define OMAP_DMA_ACTIVE			0x01
> -#define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
> +#define OMAP2_DMA_CSR_CLEAR_MASK	0xffffffff
>  #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
>  @@ -1873,7 +1873,7 @@ static int omap2_dma_handle_ch(int ch)
>  		printk(KERN_INFO "DMA misaligned error with device %d\n",
>  		       dma_chan[ch].dev_id);
>  -	p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, ch);
> +	p->dma_write(status, CSR, ch);
>  	p->dma_write(1 << ch, IRQSTATUS_L0, ch);
>  	/* read back the register to flush the write */
>  	p->dma_read(IRQSTATUS_L0, ch);
> @@ -1893,10 +1893,9 @@ static int omap2_dma_handle_ch(int ch)
>  			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
>  		status = p->dma_read(CSR, ch);
> +		p->dma_write(status, CSR, ch);
>  	}
>  -	p->dma_write(status, CSR, ch);
> -
>  	if (likely(dma_chan[ch].callback != NULL))
>  		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
>  -- 
> 1.7.0.4
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH] OMAP: DMA: clear interrupt status correctly
  2011-01-05 17:27         ` Kevin Hilman
@ 2011-01-19 10:24           ` Adrian Hunter
  2011-01-19 22:23             ` Tony Lindgren
  0 siblings, 1 reply; 15+ messages in thread
From: Adrian Hunter @ 2011-01-19 10:24 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Tony Lindgren, Santosh Shilimkar, Manjunath Kondaiah G,
	linux-omap Mailing List, linux-arm-kernel@lists.infradead.org


 From fffa19df17d73c1ed2e8c65c0b6604ee1dddff84 Mon Sep 17 00:00:00 2001
From: Adrian Hunter <adrian.hunter@nokia.com>
Date: Wed, 24 Nov 2010 13:23:21 +0200
Subject: [PATCH] OMAP: DMA: clear interrupt status correctly

When clearing the DMA channel, clear all status bits.

When handling a DMA interrupt, clear only the interrupt
status bits that have been read and are passed to the
channel's interrupt handler, not every status bit.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
---
  arch/arm/plat-omap/dma.c |    7 +++----
  1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c4b2b47..8536308 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -53,7 +53,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
  #endif
  
  #define OMAP_DMA_ACTIVE			0x01
-#define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
+#define OMAP2_DMA_CSR_CLEAR_MASK	0xffffffff
  
  #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
  
@@ -1873,7 +1873,7 @@ static int omap2_dma_handle_ch(int ch)
  		printk(KERN_INFO "DMA misaligned error with device %d\n",
  		       dma_chan[ch].dev_id);
  
-	p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, ch);
+	p->dma_write(status, CSR, ch);
  	p->dma_write(1 << ch, IRQSTATUS_L0, ch);
  	/* read back the register to flush the write */
  	p->dma_read(IRQSTATUS_L0, ch);
@@ -1893,10 +1893,9 @@ static int omap2_dma_handle_ch(int ch)
  			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
  
  		status = p->dma_read(CSR, ch);
+		p->dma_write(status, CSR, ch);
  	}
  
-	p->dma_write(status, CSR, ch);
-
  	if (likely(dma_chan[ch].callback != NULL))
  		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
  
-- 
1.7.0.4


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

* Re: [PATCH] OMAP: DMA: clear interrupt status correctly
  2011-01-19 10:24           ` [PATCH] " Adrian Hunter
@ 2011-01-19 22:23             ` Tony Lindgren
  2011-01-19 22:44               ` Tony Lindgren
  0 siblings, 1 reply; 15+ messages in thread
From: Tony Lindgren @ 2011-01-19 22:23 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Kevin Hilman, Santosh Shilimkar, Manjunath Kondaiah G,
	linux-omap Mailing List, linux-arm-kernel@lists.infradead.org

* Adrian Hunter <adrian.hunter@nokia.com> [110119 02:23]:
> 
> From fffa19df17d73c1ed2e8c65c0b6604ee1dddff84 Mon Sep 17 00:00:00 2001
> From: Adrian Hunter <adrian.hunter@nokia.com>
> Date: Wed, 24 Nov 2010 13:23:21 +0200
> Subject: [PATCH] OMAP: DMA: clear interrupt status correctly
> 
> When clearing the DMA channel, clear all status bits.
> 
> When handling a DMA interrupt, clear only the interrupt
> status bits that have been read and are passed to the
> channel's interrupt handler, not every status bit.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>

Thanks, will queue as a fix.

Tony

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

* Re: [PATCH] OMAP: DMA: clear interrupt status correctly
  2011-01-19 22:23             ` Tony Lindgren
@ 2011-01-19 22:44               ` Tony Lindgren
  2011-01-20  3:44                 ` G, Manjunath Kondaiah
  2011-01-20 11:10                 ` Adrian Hunter
  0 siblings, 2 replies; 15+ messages in thread
From: Tony Lindgren @ 2011-01-19 22:44 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Kevin Hilman, Santosh Shilimkar, Manjunath Kondaiah G,
	linux-omap Mailing List, linux-arm-kernel@lists.infradead.org

* Tony Lindgren <tony@atomide.com> [110119 14:23]:
> * Adrian Hunter <adrian.hunter@nokia.com> [110119 02:23]:
> > 
> > From fffa19df17d73c1ed2e8c65c0b6604ee1dddff84 Mon Sep 17 00:00:00 2001
> > From: Adrian Hunter <adrian.hunter@nokia.com>
> > Date: Wed, 24 Nov 2010 13:23:21 +0200
> > Subject: [PATCH] OMAP: DMA: clear interrupt status correctly
> > 
> > When clearing the DMA channel, clear all status bits.
> > 
> > When handling a DMA interrupt, clear only the interrupt
> > status bits that have been read and are passed to the
> > channel's interrupt handler, not every status bit.
> > 
> > Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
> 
> Thanks, will queue as a fix.

This did not apply for some reason, I've applied it manually.
Please check that I got it right in omap-fixes branch soonish.
Let me know if it needs updating.

Tony

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

* Re: [PATCH] OMAP: DMA: clear interrupt status correctly
  2011-01-19 22:44               ` Tony Lindgren
@ 2011-01-20  3:44                 ` G, Manjunath Kondaiah
  2011-01-20 11:10                 ` Adrian Hunter
  1 sibling, 0 replies; 15+ messages in thread
From: G, Manjunath Kondaiah @ 2011-01-20  3:44 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Adrian Hunter, Kevin Hilman, Santosh Shilimkar,
	linux-omap Mailing List, linux-arm-kernel@lists.infradead.org

On Wed, Jan 19, 2011 at 02:44:07PM -0800, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [110119 14:23]:
> > * Adrian Hunter <adrian.hunter@nokia.com> [110119 02:23]:
> > > 
> > > From fffa19df17d73c1ed2e8c65c0b6604ee1dddff84 Mon Sep 17 00:00:00 2001
> > > From: Adrian Hunter <adrian.hunter@nokia.com>
> > > Date: Wed, 24 Nov 2010 13:23:21 +0200
> > > Subject: [PATCH] OMAP: DMA: clear interrupt status correctly
> > > 
> > > When clearing the DMA channel, clear all status bits.
> > > 
> > > When handling a DMA interrupt, clear only the interrupt
> > > status bits that have been read and are passed to the
> > > channel's interrupt handler, not every status bit.
> > > 
> > > Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
> > 
> > Thanks, will queue as a fix.
> 
> This did not apply for some reason, I've applied it manually.
> Please check that I got it right in omap-fixes branch soonish.
> Let me know if it needs updating.
Looks like the commit message is missing:
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

you can also add:
Acked-by: G, Manjunath Kondaiah <manjugk@ti.com>

-Manjunath

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

* Re: [PATCH] OMAP: DMA: clear interrupt status correctly
  2011-01-19 22:44               ` Tony Lindgren
  2011-01-20  3:44                 ` G, Manjunath Kondaiah
@ 2011-01-20 11:10                 ` Adrian Hunter
  1 sibling, 0 replies; 15+ messages in thread
From: Adrian Hunter @ 2011-01-20 11:10 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kevin Hilman, Santosh Shilimkar, Manjunath Kondaiah G,
	linux-omap Mailing List, linux-arm-kernel@lists.infradead.org

On 20/01/11 00:44, Tony Lindgren wrote:
> * Tony Lindgren<tony@atomide.com>  [110119 14:23]:
>> * Adrian Hunter<adrian.hunter@nokia.com>  [110119 02:23]:
>>>
>>>  From fffa19df17d73c1ed2e8c65c0b6604ee1dddff84 Mon Sep 17 00:00:00 2001
>>> From: Adrian Hunter<adrian.hunter@nokia.com>
>>> Date: Wed, 24 Nov 2010 13:23:21 +0200
>>> Subject: [PATCH] OMAP: DMA: clear interrupt status correctly
>>>
>>> When clearing the DMA channel, clear all status bits.
>>>
>>> When handling a DMA interrupt, clear only the interrupt
>>> status bits that have been read and are passed to the
>>> channel's interrupt handler, not every status bit.
>>>
>>> Signed-off-by: Adrian Hunter<adrian.hunter@nokia.com>
>>
>> Thanks, will queue as a fix.
>
> This did not apply for some reason, I've applied it manually.
> Please check that I got it right in omap-fixes branch soonish.
> Let me know if it needs updating.

Looks fine

>
> Tony
>


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

end of thread, other threads:[~2011-01-20 11:10 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-30 13:23 [PATCH 0/2] Minor DMA fixes Adrian Hunter
2010-11-30 13:23 ` [PATCH 1/2] OMAP: DMA: prevent races while setting M idle mode to nostandby Adrian Hunter
2010-11-30 14:24   ` Santosh Shilimkar
2010-12-01 12:21   ` Peter Ujfalusi
2010-12-01 19:11   ` G, Manjunath Kondaiah
2010-11-30 13:23 ` [PATCH 2/2] OMAP: DMA: clear interrupt status correctly Adrian Hunter
2010-11-30 14:25   ` Santosh Shilimkar
2010-12-21 20:29     ` Tony Lindgren
2011-01-05  9:58       ` Adrian Hunter
2011-01-05 17:27         ` Kevin Hilman
2011-01-19 10:24           ` [PATCH] " Adrian Hunter
2011-01-19 22:23             ` Tony Lindgren
2011-01-19 22:44               ` Tony Lindgren
2011-01-20  3:44                 ` G, Manjunath Kondaiah
2011-01-20 11:10                 ` Adrian Hunter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).