aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/pl330.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 1ecd4674aa23..030fe05ed43b 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2272,7 +2272,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
2272{ 2272{
2273 enum dma_status ret; 2273 enum dma_status ret;
2274 unsigned long flags; 2274 unsigned long flags;
2275 struct dma_pl330_desc *desc, *running = NULL; 2275 struct dma_pl330_desc *desc, *running = NULL, *last_enq = NULL;
2276 struct dma_pl330_chan *pch = to_pchan(chan); 2276 struct dma_pl330_chan *pch = to_pchan(chan);
2277 unsigned int transferred, residual = 0; 2277 unsigned int transferred, residual = 0;
2278 2278
@@ -2285,10 +2285,13 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
2285 goto out; 2285 goto out;
2286 2286
2287 spin_lock_irqsave(&pch->lock, flags); 2287 spin_lock_irqsave(&pch->lock, flags);
2288 spin_lock(&pch->thread->dmac->lock);
2288 2289
2289 if (pch->thread->req_running != -1) 2290 if (pch->thread->req_running != -1)
2290 running = pch->thread->req[pch->thread->req_running].desc; 2291 running = pch->thread->req[pch->thread->req_running].desc;
2291 2292
2293 last_enq = pch->thread->req[pch->thread->lstenq].desc;
2294
2292 /* Check in pending list */ 2295 /* Check in pending list */
2293 list_for_each_entry(desc, &pch->work_list, node) { 2296 list_for_each_entry(desc, &pch->work_list, node) {
2294 if (desc->status == DONE) 2297 if (desc->status == DONE)
@@ -2296,6 +2299,15 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
2296 else if (running && desc == running) 2299 else if (running && desc == running)
2297 transferred = 2300 transferred =
2298 pl330_get_current_xferred_count(pch, desc); 2301 pl330_get_current_xferred_count(pch, desc);
2302 else if (desc->status == BUSY)
2303 /*
2304 * Busy but not running means either just enqueued,
2305 * or finished and not yet marked done
2306 */
2307 if (desc == last_enq)
2308 transferred = 0;
2309 else
2310 transferred = desc->bytes_requested;
2299 else 2311 else
2300 transferred = 0; 2312 transferred = 0;
2301 residual += desc->bytes_requested - transferred; 2313 residual += desc->bytes_requested - transferred;
@@ -2316,6 +2328,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
2316 if (desc->last) 2328 if (desc->last)
2317 residual = 0; 2329 residual = 0;
2318 } 2330 }
2331 spin_unlock(&pch->thread->dmac->lock);
2319 spin_unlock_irqrestore(&pch->lock, flags); 2332 spin_unlock_irqrestore(&pch->lock, flags);
2320 2333
2321out: 2334out: