Skip to content

Commit

Permalink
dmaengine: PL08x: fix tx_status function to return correct residue
Browse files Browse the repository at this point in the history
Now that we're converted to use the generic vchan support, we can fix
the residue return from tx_status to be compliant with dmaengine.  This
returns the number of bytes remaining for the _specified_ cookie, not
the number of bytes in all pending transfers on the channel.

Acked-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Russell King committed Jul 1, 2012
1 parent 1853613 commit 06e885b
Showing 1 changed file with 34 additions and 27 deletions.
61 changes: 34 additions & 27 deletions drivers/dma/amba-pl08x.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,8 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
{
struct pl08x_phy_chan *ch;
struct pl08x_txd *txd;
unsigned long flags;
size_t bytes = 0;

spin_lock_irqsave(&plchan->vc.lock, flags);
ch = plchan->phychan;
txd = plchan->at;

Expand Down Expand Up @@ -516,27 +514,6 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
}
}

/* Sum up all queued transactions */
if (!list_empty(&plchan->vc.desc_issued)) {
struct pl08x_txd *txdi;
list_for_each_entry(txdi, &plchan->vc.desc_issued, vd.node) {
struct pl08x_sg *dsg;
list_for_each_entry(dsg, &txd->dsg_list, node)
bytes += dsg->len;
}
}

if (!list_empty(&plchan->vc.desc_submitted)) {
struct pl08x_txd *txdi;
list_for_each_entry(txdi, &plchan->vc.desc_submitted, vd.node) {
struct pl08x_sg *dsg;
list_for_each_entry(dsg, &txd->dsg_list, node)
bytes += dsg->len;
}
}

spin_unlock_irqrestore(&plchan->vc.lock, flags);

return bytes;
}

Expand Down Expand Up @@ -1171,23 +1148,53 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
dma_cookie_t cookie, struct dma_tx_state *txstate)
{
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
struct virt_dma_desc *vd;
unsigned long flags;
enum dma_status ret;
size_t bytes = 0;

ret = dma_cookie_status(chan, cookie, txstate);
if (ret == DMA_SUCCESS)
return ret;

/*
* There's no point calculating the residue if there's
* no txstate to store the value.
*/
if (!txstate) {
if (plchan->state == PL08X_CHAN_PAUSED)
ret = DMA_PAUSED;
return ret;
}

spin_lock_irqsave(&plchan->vc.lock, flags);
ret = dma_cookie_status(chan, cookie, txstate);
if (ret != DMA_SUCCESS) {
vd = vchan_find_desc(&plchan->vc, cookie);
if (vd) {
/* On the issued list, so hasn't been processed yet */
struct pl08x_txd *txd = to_pl08x_txd(&vd->tx);
struct pl08x_sg *dsg;

list_for_each_entry(dsg, &txd->dsg_list, node)
bytes += dsg->len;
} else {
bytes = pl08x_getbytes_chan(plchan);
}
}
spin_unlock_irqrestore(&plchan->vc.lock, flags);

/*
* This cookie not complete yet
* Get number of bytes left in the active transactions and queue
*/
dma_set_residue(txstate, pl08x_getbytes_chan(plchan));
dma_set_residue(txstate, bytes);

if (plchan->state == PL08X_CHAN_PAUSED)
return DMA_PAUSED;
if (plchan->state == PL08X_CHAN_PAUSED && ret == DMA_IN_PROGRESS)
ret = DMA_PAUSED;

/* Whether waiting or running, we're in progress */
return DMA_IN_PROGRESS;
return ret;
}

/* PrimeCell DMA extension */
Expand Down

0 comments on commit 06e885b

Please sign in to comment.