Skip to content

Commit

Permalink
omap: Fix race condition in omap dma driver
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tao Hu authored and Tony Lindgren committed Nov 11, 2009
1 parent b419148 commit ee90732
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions arch/arm/plat-omap/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down

0 comments on commit ee90732

Please sign in to comment.