static enum dma_status fsl_edma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, struct dma_tx_state *txstate) { struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); struct virt_dma_desc *vdesc; enum dma_status status; unsigned long flags; status = dma_cookie_status(chan, cookie, txstate); if (status == DMA_COMPLETE) return status; if (!txstate) return fsl_chan->status; spin_lock_irqsave(&fsl_chan->vchan.lock, flags); vdesc = vchan_find_desc(&fsl_chan->vchan, cookie); if (fsl_chan->edesc && cookie == fsl_chan->edesc->vdesc.tx.cookie) txstate->residue = fsl_edma_desc_residue(fsl_chan, vdesc, true); else if (vdesc) txstate->residue = fsl_edma_desc_residue(fsl_chan, vdesc, false); else txstate->residue = 0; spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); return fsl_chan->status; }
static enum dma_status tegra_adma_tx_status(struct dma_chan *dc, dma_cookie_t cookie, struct dma_tx_state *txstate) { struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); struct tegra_adma_desc *desc; struct virt_dma_desc *vd; enum dma_status ret; unsigned long flags; unsigned int residual; ret = dma_cookie_status(dc, cookie, txstate); if (ret == DMA_COMPLETE || !txstate) return ret; spin_lock_irqsave(&tdc->vc.lock, flags); vd = vchan_find_desc(&tdc->vc, cookie); if (vd) { desc = to_tegra_adma_desc(&vd->tx); residual = desc->ch_regs.tc; } else if (tdc->desc && tdc->desc->vd.tx.cookie == cookie) { residual = tegra_adma_get_residue(tdc); } else { residual = 0; } spin_unlock_irqrestore(&tdc->vc.lock, flags); dma_set_residue(txstate, residual); return ret; }
static enum dma_status at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, struct dma_tx_state *txstate) { struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); struct at_xdmac_desc *desc, *_desc; struct list_head *descs_list; enum dma_status ret; int residue; u32 cur_nda, mask, value; u8 dwidth = 0; unsigned long flags; ret = dma_cookie_status(chan, cookie, txstate); if (ret == DMA_COMPLETE) return ret; if (!txstate) return ret; spin_lock_irqsave(&atchan->lock, flags); desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, xfer_node); /* * If the transfer has not been started yet, don't need to compute the * residue, it's the transfer length. */ if (!desc->active_xfer) { dma_set_residue(txstate, desc->xfer_size); goto spin_unlock; } residue = desc->xfer_size; /*