From 024b23753469758289a4f8c318d726341eacbfcf Mon Sep 17 00:00:00 2001 From: Huibin Hong Date: Mon, 23 Mar 2015 17:11:09 +0800 Subject: [PATCH] DMA: pl330: add chan_status to mutex between pl330_tasklet and pl330_control DMA_TERMINATE_ALL Signed-off-by: Huibin Hong --- drivers/dma/pl330.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 3310b50fafec..8605a5e6b97d 100755 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -574,6 +574,8 @@ struct dma_pl330_chan { /* for cyclic capability */ bool cyclic; + + enum dma_status chan_status; }; struct dma_pl330_dmac { @@ -2408,11 +2410,18 @@ static inline void handle_cyclic_desc_list(struct list_head *list) } /* pch will be unset if list was empty */ - if (!pch) + if (!pch || !pch->dmac) return; spin_lock_irqsave(&pch->lock, flags); - list_splice_tail_init(list, &pch->work_list); + if (pch->chan_status == DMA_PAUSED) { + list_for_each_entry(desc, list, node) { + desc->status = DONE; + } + list_splice_tail_init(list, &pch->dmac->desc_pool); + } else { + list_splice_tail_init(list, &pch->work_list); + } spin_unlock_irqrestore(&pch->lock, flags); } @@ -2453,6 +2462,7 @@ static void pl330_tasklet(unsigned long data) spin_lock_irqsave(&pch->lock, flags); + pch->chan_status = DMA_SUCCESS; /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { @@ -2587,6 +2597,7 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned } list_splice_tail_init(&list, &pdmac->desc_pool); + pch->chan_status = DMA_PAUSED; spin_unlock_irqrestore(&pch->lock, flags); break; case DMA_SLAVE_CONFIG: -- 2.34.1