diff options
| author | Tao Hu <taohu@motorola.com> | 2009-11-10 18:55:17 -0800 | 
|---|---|---|
| committer | Tony Lindgren <tony@atomide.com> | 2009-11-10 18:55:17 -0800 | 
| commit | ee90732456fe8e75406fdd3cd136a4bfb7ce31f5 (patch) | |
| tree | 0c0f49d8240d595e8162fbc02939266e3c268a9e | |
| parent | b419148e567728f6af0c3b01965c1cc141e3e13a (diff) | |
| download | olio-linux-3.10-ee90732456fe8e75406fdd3cd136a4bfb7ce31f5.tar.xz olio-linux-3.10-ee90732456fe8e75406fdd3cd136a4bfb7ce31f5.zip  | |
omap: Fix race condition in omap dma driver
The bug could cause irq enable bit of one DMA channel is
cleared/set unexpectedly when 2 (or more) drivers are calling
omap_request_dma()/omap_free_dma() simultaneously
Signed-off-by: Fei Yang <AFY095@motorola.com>
Signed-off-by: Tao Hu <taohu@motorola.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
| -rw-r--r-- | arch/arm/plat-omap/dma.c | 6 | 
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index b53125f4129..02ed94526aa 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -691,13 +691,16 @@ static inline void disable_lnk(int lch)  static inline void omap2_enable_irq_lch(int lch)  {  	u32 val; +	unsigned long flags;  	if (!cpu_class_is_omap2())  		return; +	spin_lock_irqsave(&dma_chan_lock, flags);  	val = dma_read(IRQENABLE_L0);  	val |= 1 << lch;  	dma_write(val, IRQENABLE_L0); +	spin_unlock_irqrestore(&dma_chan_lock, flags);  }  int omap_request_dma(int dev_id, const char *dev_name, @@ -799,10 +802,13 @@ void omap_free_dma(int lch)  	if (cpu_class_is_omap2()) {  		u32 val; + +		spin_lock_irqsave(&dma_chan_lock, flags);  		/* Disable interrupts */  		val = dma_read(IRQENABLE_L0);  		val &= ~(1 << lch);  		dma_write(val, IRQENABLE_L0); +		spin_unlock_irqrestore(&dma_chan_lock, flags);  		/* Clear the CSR register and IRQ status register */  		dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));  |