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>

authored by Tao Hu and committed by Tony Lindgren ee907324 b419148e

+6
+6
arch/arm/plat-omap/dma.c
··· 691 691 static inline void omap2_enable_irq_lch(int lch) 692 692 { 693 693 u32 val; 694 + unsigned long flags; 694 695 695 696 if (!cpu_class_is_omap2()) 696 697 return; 697 698 699 + spin_lock_irqsave(&dma_chan_lock, flags); 698 700 val = dma_read(IRQENABLE_L0); 699 701 val |= 1 << lch; 700 702 dma_write(val, IRQENABLE_L0); 703 + spin_unlock_irqrestore(&dma_chan_lock, flags); 701 704 } 702 705 703 706 int omap_request_dma(int dev_id, const char *dev_name, ··· 802 799 803 800 if (cpu_class_is_omap2()) { 804 801 u32 val; 802 + 803 + spin_lock_irqsave(&dma_chan_lock, flags); 805 804 /* Disable interrupts */ 806 805 val = dma_read(IRQENABLE_L0); 807 806 val &= ~(1 << lch); 808 807 dma_write(val, IRQENABLE_L0); 808 + spin_unlock_irqrestore(&dma_chan_lock, flags); 809 809 810 810 /* Clear the CSR register and IRQ status register */ 811 811 dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));