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