Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit add93b57 authored by Rongjun Ying's avatar Rongjun Ying Committed by Vinod Koul
Browse files

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: default avatarRongjun Ying <Rongjun.Ying@csr.com>
Signed-off-by: default avatarBarry Song <Baohua.Song@csr.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent 7bdc1e27
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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;