summaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-07-02 13:52:07 +0530
committerVinod Koul <vinod.koul@linux.intel.com>2012-07-13 08:49:54 +0530
commit4a46ba36e25dcff1d30eb1681135c3c10af71c16 (patch)
tree8003546e61cd4337b5f27001bab7854cefcfe8bc /drivers/dma
parent46fb3f8ef5bde1325b1e58867a3a98dd746511d7 (diff)
dma: tegra: fix residual calculation for cyclic case
In cyclic mode of DMA, the byte transferred can be more than the requested size and in this case, calculating residuals based on the current position of DMA transfer to bytes requested i.e. bytes required to transfer to reach bytes requested from current DMA position. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Acked-by: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/tegra20-apb-dma.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index c0836a7a863..8e0ea2438ce 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -731,6 +731,7 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
struct tegra_dma_sg_req *sg_req;
enum dma_status ret;
unsigned long flags;
+ unsigned int residual;
spin_lock_irqsave(&tdc->lock, flags);
@@ -744,9 +745,10 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
/* Check on wait_ack desc status */
list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) {
if (dma_desc->txd.cookie == cookie) {
- dma_set_residue(txstate,
- dma_desc->bytes_requested -
- dma_desc->bytes_transferred);
+ residual = dma_desc->bytes_requested -
+ (dma_desc->bytes_transferred %
+ dma_desc->bytes_requested);
+ dma_set_residue(txstate, residual);
ret = dma_desc->dma_status;
spin_unlock_irqrestore(&tdc->lock, flags);
return ret;
@@ -757,9 +759,10 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
list_for_each_entry(sg_req, &tdc->pending_sg_req, node) {
dma_desc = sg_req->dma_desc;
if (dma_desc->txd.cookie == cookie) {
- dma_set_residue(txstate,
- dma_desc->bytes_requested -
- dma_desc->bytes_transferred);
+ residual = dma_desc->bytes_requested -
+ (dma_desc->bytes_transferred %
+ dma_desc->bytes_requested);
+ dma_set_residue(txstate, residual);
ret = dma_desc->dma_status;
spin_unlock_irqrestore(&tdc->lock, flags);
return ret;