Merge tag 'iwlwifi-for-kalle-2016-01-26_2' of https://git.kernel.org/pub/scm/linux...
[linux-2.6-block.git] / drivers / dma / virt-dma.c
index 7d2c17d8d30fc1a4f1efd9c7471bc1e5cbdc794c..a35c211857dd61f7679aabe652a32bb6220fb27c 100644 (file)
@@ -39,6 +39,33 @@ dma_cookie_t vchan_tx_submit(struct dma_async_tx_descriptor *tx)
 }
 EXPORT_SYMBOL_GPL(vchan_tx_submit);
 
+/**
+ * vchan_tx_desc_free - free a reusable descriptor
+ * @tx: the transfer
+ *
+ * This function frees a previously allocated reusable descriptor. The only
+ * other way is to clear the DMA_CTRL_REUSE flag and submit one last time the
+ * transfer.
+ *
+ * Returns 0 upon success
+ */
+int vchan_tx_desc_free(struct dma_async_tx_descriptor *tx)
+{
+       struct virt_dma_chan *vc = to_virt_chan(tx->chan);
+       struct virt_dma_desc *vd = to_virt_desc(tx);
+       unsigned long flags;
+
+       spin_lock_irqsave(&vc->lock, flags);
+       list_del(&vd->node);
+       spin_unlock_irqrestore(&vc->lock, flags);
+
+       dev_dbg(vc->chan.device->dev, "vchan %p: txd %p[%x]: freeing\n",
+               vc, vd, vd->tx.cookie);
+       vc->desc_free(vd);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(vchan_tx_desc_free);
+
 struct virt_dma_desc *vchan_find_desc(struct virt_dma_chan *vc,
        dma_cookie_t cookie)
 {
@@ -83,7 +110,7 @@ static void vchan_complete(unsigned long arg)
                cb_data = vd->tx.callback_param;
 
                list_del(&vd->node);
-               if (async_tx_test_ack(&vd->tx))
+               if (dmaengine_desc_test_reuse(&vd->tx))
                        list_add(&vd->node, &vc->desc_allocated);
                else
                        vc->desc_free(vd);
@@ -98,7 +125,7 @@ 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);
-               if (async_tx_test_ack(&vd->tx)) {
+               if (dmaengine_desc_test_reuse(&vd->tx)) {
                        list_move_tail(&vd->node, &vc->desc_allocated);
                } else {
                        dev_dbg(vc->chan.device->dev, "txd %p: freeing\n", vd);