summaryrefslogtreecommitdiff
path: root/drivers/dma/virt-dma.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-29 09:44:45 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-29 09:44:45 -0700
commit1bc5e157ed2b4f5b206155fc772d860158acd201 (patch)
tree0edf76217120a05502437e775bf99cf66ae0d13f /drivers/dma/virt-dma.c
parentf199b663fc5a276af10a49c24a83d8de27a41b53 (diff)
parent657d61275dad112ff36e70ee63c71d64821db36c (diff)
Merge tag 'dmaengine-4.2-rc1' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine updates from Vinod Koul: "This time we have support for few new devices, few new features and odd fixes spread thru the subsystem. New devices added: - support for CSRatlas7 dma controller - Allwinner H3(sun8i) controller - TI DMA crossbar driver on DRA7x - new pxa driver New features added: - memset support is bought back now that we have a user in xdmac controller - interleaved transfers support different source and destination strides - supporting DMA routers and configuration thru DT - support for reusing descriptors - xdmac memset and interleaved transfer support - hdmac support for interleaved transfers - omap-dma support for memcpy Others: - Constify platform_device_id - mv_xor fixes and improvements" * tag 'dmaengine-4.2-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (46 commits) dmaengine: xgene: fix file permission dmaengine: fsl-edma: clear pending interrupts on initialization dmaengine: xdmac: Add memset support Documentation: dmaengine: document DMA_CTRL_ACK dmaengine: virt-dma: don't always free descriptor upon completion dmaengine: Revert "drivers/dma: remove unused support for MEMSET operations" dmaengine: hdmac: Implement interleaved transfers dmaengine: Move icg helpers to global header dmaengine: mv_xor: improve descriptors list handling and reduce locking dmaengine: mv_xor: Enlarge descriptor pool size dmaengine: mv_xor: add support for a38x command in descriptor mode dmaengine: mv_xor: Rename function for consistent naming dmaengine: mv_xor: bug fix for racing condition in descriptors cleanup dmaengine: pl330: fix wording in mcbufsz message dmaengine: sirf: add CSRatlas7 SoC support dmaengine: xgene-dma: Fix "incorrect type in assignement" warnings dmaengine: fix kernel-doc documentation dmaengine: pxa_dma: add support for legacy transition dmaengine: pxa_dma: add debug information dmaengine: pxa: add pxa dmaengine driver ...
Diffstat (limited to 'drivers/dma/virt-dma.c')
-rw-r--r--drivers/dma/virt-dma.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
index 6f80432a3f0a..7d2c17d8d30f 100644
--- a/drivers/dma/virt-dma.c
+++ b/drivers/dma/virt-dma.c
@@ -29,7 +29,7 @@ dma_cookie_t vchan_tx_submit(struct dma_async_tx_descriptor *tx)
spin_lock_irqsave(&vc->lock, flags);
cookie = dma_cookie_assign(tx);
- list_add_tail(&vd->node, &vc->desc_submitted);
+ list_move_tail(&vd->node, &vc->desc_submitted);
spin_unlock_irqrestore(&vc->lock, flags);
dev_dbg(vc->chan.device->dev, "vchan %p: txd %p[%x]: submitted\n",
@@ -83,8 +83,10 @@ static void vchan_complete(unsigned long arg)
cb_data = vd->tx.callback_param;
list_del(&vd->node);
-
- vc->desc_free(vd);
+ if (async_tx_test_ack(&vd->tx))
+ list_add(&vd->node, &vc->desc_allocated);
+ else
+ vc->desc_free(vd);
if (cb)
cb(cb_data);
@@ -96,9 +98,13 @@ void vchan_dma_desc_free_list(struct virt_dma_chan *vc, struct list_head *head)
while (!list_empty(head)) {
struct virt_dma_desc *vd = list_first_entry(head,
struct virt_dma_desc, node);
- list_del(&vd->node);
- dev_dbg(vc->chan.device->dev, "txd %p: freeing\n", vd);
- vc->desc_free(vd);
+ if (async_tx_test_ack(&vd->tx)) {
+ list_move_tail(&vd->node, &vc->desc_allocated);
+ } else {
+ dev_dbg(vc->chan.device->dev, "txd %p: freeing\n", vd);
+ list_del(&vd->node);
+ vc->desc_free(vd);
+ }
}
}
EXPORT_SYMBOL_GPL(vchan_dma_desc_free_list);
@@ -108,6 +114,7 @@ void vchan_init(struct virt_dma_chan *vc, struct dma_device *dmadev)
dma_cookie_init(&vc->chan);
spin_lock_init(&vc->lock);
+ INIT_LIST_HEAD(&vc->desc_allocated);
INIT_LIST_HEAD(&vc->desc_submitted);
INIT_LIST_HEAD(&vc->desc_issued);
INIT_LIST_HEAD(&vc->desc_completed);