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