Skip to content

Commit

Permalink
dmaengine: sirf: set dma residue based on the current dma transfer po…
Browse files Browse the repository at this point in the history
…sition

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 <[email protected]>
Signed-off-by: Barry Song <[email protected]>
Signed-off-by: Vinod Koul <[email protected]>
  • Loading branch information
Rongjun Ying authored and Vinod Koul committed Jul 5, 2013
1 parent 7bdc1e2 commit add93b5
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions drivers/dma/sirf-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,12 +466,29 @@ static enum dma_status
sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
unsigned long flags;
enum dma_status ret;
struct sirfsoc_dma_desc *sdesc;
int cid = schan->chan.chan_id;
unsigned long dma_pos;
unsigned long dma_request_bytes;
unsigned long residue;

spin_lock_irqsave(&schan->lock, flags);

sdesc = list_first_entry(&schan->active, struct sirfsoc_dma_desc,
node);
dma_request_bytes = (sdesc->xlen + 1) * (sdesc->ylen + 1) *
(sdesc->width * SIRFSOC_DMA_WORD_LEN);

ret = dma_cookie_status(chan, cookie, txstate);
dma_pos = readl_relaxed(sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_ADDR)
<< 2;
residue = dma_request_bytes - (dma_pos - sdesc->addr);
dma_set_residue(txstate, residue);

spin_unlock_irqrestore(&schan->lock, flags);

return ret;
Expand Down

0 comments on commit add93b5

Please sign in to comment.