diff options
author | Rongjun Ying <Rongjun.Ying@csr.com> | 2013-05-14 11:03:20 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-07-05 02:10:39 -0400 |
commit | add93b578edda2a952b9b481ce8da2a9dc412cee (patch) | |
tree | c5409a24671e2f76beee0893a8f965d6a3cbe50f /drivers/dma | |
parent | 7bdc1e272a471062e8f310137c896e2355b46d13 (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.c | 17 |
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 | |||
466 | sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, | 466 | sirfsoc_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; |