Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee907324 authored by Tao Hu's avatar Tao Hu Committed by Tony Lindgren
Browse files

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: default avatarFei Yang <AFY095@motorola.com>
Signed-off-by: default avatarTao Hu <taohu@motorola.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent b419148e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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));