From bd37028a3bb80c4e09b11d9eb4acd67ea175dc9e Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 6 Aug 2010 12:13:43 +0530 Subject: [arm/tegra] dma: Using the irqsave spin lock in ist. In place of using the simple spin_lock()/spi_unlock() in the interrupt thread, using the spin_lock_irqsave() and spin_unlock_irqrestore(). The lock is shared between the normal process context and interrupt context. Change-Id: I2c905b1daf31568919854b59d52620f06fdf10ea Reviewed-on: http://git-master/r/4838 Reviewed-by: Venkata (Muni) Anda Tested-by: Venkata (Muni) Anda Reviewed-by: Laxman Dewangan Tested-by: Laxman Dewangan Tested-by: Anantha Idapalapati Reviewed-by: Gary King --- arch/arm/mach-tegra/dma.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index 9e62051917ef..feaa7fdb46bf 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c @@ -576,10 +576,11 @@ static void tegra_dma_init_hw(struct tegra_dma_channel *ch) static void handle_oneshot_dma(struct tegra_dma_channel *ch) { struct tegra_dma_req *req; + unsigned long irq_flags; - spin_lock(&ch->lock); + spin_lock_irqsave(&ch->lock, irq_flags); if (list_empty(&ch->list)) { - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); return; } @@ -596,12 +597,12 @@ static void handle_oneshot_dma(struct tegra_dma_channel *ch) req->bytes_transferred = bytes_transferred; req->status = TEGRA_DMA_REQ_SUCCESS; - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); /* Callback should be called without any lock */ pr_debug("%s: transferred %d bytes\n", __func__, req->bytes_transferred); req->complete(req); - spin_lock(&ch->lock); + spin_lock_irqsave(&ch->lock, irq_flags); } if (!list_empty(&ch->list)) { @@ -611,17 +612,18 @@ static void handle_oneshot_dma(struct tegra_dma_channel *ch) if (req->status != TEGRA_DMA_REQ_INFLIGHT) tegra_dma_update_hw(ch, req); } - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); } static void handle_continuous_dma(struct tegra_dma_channel *ch) { struct tegra_dma_req *req; struct tegra_dma_req *next_req; + unsigned long irq_flags; - spin_lock(&ch->lock); + spin_lock_irqsave(&ch->lock, irq_flags); if (list_empty(&ch->list)) { - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); return; } @@ -657,7 +659,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch) list_del(&req->node); /* DMA lock is NOT held when callbak is called */ - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); req->complete(req); return; } @@ -671,7 +673,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch) req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL; req->status = TEGRA_DMA_REQ_SUCCESS; /* DMA lock is NOT held when callback is called */ - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); if (likely(req->threshold)) req->threshold(req); return; @@ -708,7 +710,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch) list_del(&req->node); /* DMA lock is NOT held when callbak is called */ - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); req->complete(req); return; @@ -718,7 +720,7 @@ static void handle_continuous_dma(struct tegra_dma_channel *ch) BUG(); } } - spin_unlock(&ch->lock); + spin_unlock_irqrestore(&ch->lock, irq_flags); } static irqreturn_t dma_isr(int irq, void *data) -- cgit v1.2.3