]> git.karo-electronics.de Git - linux-beck.git/commitdiff
dma: tegra: fix residual calculation for cyclic case
authorLaxman Dewangan <ldewangan@nvidia.com>
Mon, 2 Jul 2012 08:22:07 +0000 (13:52 +0530)
committerVinod Koul <vinod.koul@linux.intel.com>
Fri, 13 Jul 2012 03:19:54 +0000 (08:49 +0530)
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>
drivers/dma/tegra20-apb-dma.c

index c0836a7a8631c505581708868160dcab18337055..8e0ea2438ce1a39dc1e37fe9f7a4b972f1302d9c 100644 (file)
@@ -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;