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>
This commit is contained in:
Tao Hu 2009-11-10 18:55:17 -08:00 committed by Tony Lindgren
parent b419148e56
commit ee90732456

View File

@ -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));