aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorRongjun Ying <Rongjun.Ying@csr.com>2013-05-14 11:03:20 -0400
committerVinod Koul <vinod.koul@intel.com>2013-07-05 02:10:39 -0400
commitadd93b578edda2a952b9b481ce8da2a9dc412cee (patch)
treec5409a24671e2f76beee0893a8f965d6a3cbe50f /drivers/dma
parent7bdc1e272a471062e8f310137c896e2355b46d13 (diff)
dmaengine: sirf: set dma residue based on the current dma transfer position
read SIRFSOC_DMA_CH_ADDR register to get current dma transfer position, then update dma residue so that things like ALSA drivers work as ALSA drivers need the right residue value. Signed-off-by: Rongjun Ying <Rongjun.Ying@csr.com> Signed-off-by: Barry Song <Baohua.Song@csr.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/sirf-dma.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 1765a0a2736d..716b23e4f327 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -466,12 +466,29 @@ static enum dma_status
466sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, 466sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
467 struct dma_tx_state *txstate) 467 struct dma_tx_state *txstate)
468{ 468{
469 struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
469 struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); 470 struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
470 unsigned long flags; 471 unsigned long flags;
471 enum dma_status ret; 472 enum dma_status ret;
473 struct sirfsoc_dma_desc *sdesc;
474 int cid = schan->chan.chan_id;
475 unsigned long dma_pos;
476 unsigned long dma_request_bytes;
477 unsigned long residue;
472 478
473 spin_lock_irqsave(&schan->lock, flags); 479 spin_lock_irqsave(&schan->lock, flags);
480
481 sdesc = list_first_entry(&schan->active, struct sirfsoc_dma_desc,
482 node);
483 dma_request_bytes = (sdesc->xlen + 1) * (sdesc->ylen + 1) *
484 (sdesc->width * SIRFSOC_DMA_WORD_LEN);
485
474 ret = dma_cookie_status(chan, cookie, txstate); 486 ret = dma_cookie_status(chan, cookie, txstate);
487 dma_pos = readl_relaxed(sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_ADDR)
488 << 2;
489 residue = dma_request_bytes - (dma_pos - sdesc->addr);
490 dma_set_residue(txstate, residue);
491
475 spin_unlock_irqrestore(&schan->lock, flags); 492 spin_unlock_irqrestore(&schan->lock, flags);
476 493
477 return ret; 494 return ret;