summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/dma.c
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2010-06-03 23:09:06 -0700
committerGary King <gking@nvidia.com>2010-06-09 09:00:17 -0700
commit95ad71e06c0e129f2c587f28beb052936d19cf78 (patch)
tree3d9e0494db9b06696c3ebdf35b1db05a413a6beb /arch/arm/mach-tegra/dma.c
parent1622e31b0b9d52d37accab6c8556b577ad171c79 (diff)
[ARM] tegra: dma: Prevent double-queued requests
Change-Id: I08165ea202530bc65be9d418a889dd0622a3ac4f Signed-off-by: Colin Cross <ccross@android.com> Reviewed-on: http://git-master/r/2285 Reviewed-by: Gary King <gking@nvidia.com> Tested-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/dma.c')
-rw-r--r--arch/arm/mach-tegra/dma.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index 1d44073ce541..306c8e85be9f 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -432,6 +432,8 @@ static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
}
writel(ch->apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
writel(ch->ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
+
+ req->status = TEGRA_DMA_REQ_INFLIGHT;
return;
}
@@ -544,6 +546,8 @@ static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
csr = ch->csr | CSR_ENB;
writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ req->status = TEGRA_DMA_REQ_INFLIGHT;
}
static void tegra_dma_init_hw(struct tegra_dma_channel *ch)
@@ -587,7 +591,10 @@ static void handle_oneshot_dma(struct tegra_dma_channel *ch)
if (!list_empty(&ch->list)) {
req = list_entry(ch->list.next, typeof(*req), node);
- tegra_dma_update_hw(ch, req);
+ /* the complete function we just called may have enqueued another
+ req, in which case dma has already started */
+ if (req->status != TEGRA_DMA_REQ_INFLIGHT)
+ tegra_dma_update_hw(ch, req);
}
spin_unlock(&ch->lock);
}