Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Rongjun Ying and committed by
Vinod Koul
add93b57 7bdc1e27

+17
+17
drivers/dma/sirf-dma.c
··· 466 466 sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, 467 467 struct dma_tx_state *txstate) 468 468 { 469 + struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan); 469 470 struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan); 470 471 unsigned long flags; 471 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 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 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 492 spin_unlock_irqrestore(&schan->lock, flags); 476 493 477 494 return ret;