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 | |
| 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>
| -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; |
