aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/virt-dma.c19
-rw-r--r--drivers/dma/virt-dma.h14
2 files changed, 29 insertions, 4 deletions
diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
index a8054fc40cef..6f80432a3f0a 100644
--- a/drivers/dma/virt-dma.c
+++ b/drivers/dma/virt-dma.c
@@ -59,17 +59,28 @@ EXPORT_SYMBOL_GPL(vchan_find_desc);
static void vchan_complete(unsigned long arg)
{
struct virt_dma_chan *vc = (struct virt_dma_chan *)arg;
+ struct virt_dma_desc *vd;
+ dma_async_tx_callback cb = NULL;
+ void *cb_data = NULL;
LIST_HEAD(head);
spin_lock_irq(&vc->lock);
list_splice_tail_init(&vc->desc_completed, &head);
+ vd = vc->cyclic;
+ if (vd) {
+ vc->cyclic = NULL;
+ cb = vd->tx.callback;
+ cb_data = vd->tx.callback_param;
+ }
spin_unlock_irq(&vc->lock);
+ if (cb)
+ cb(cb_data);
+
while (!list_empty(&head)) {
- struct virt_dma_desc *vd = list_first_entry(&head,
- struct virt_dma_desc, node);
- dma_async_tx_callback cb = vd->tx.callback;
- void *cb_data = vd->tx.callback_param;
+ vd = list_first_entry(&head, struct virt_dma_desc, node);
+ cb = vd->tx.callback;
+ cb_data = vd->tx.callback_param;
list_del(&vd->node);
diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h
index 44ec57e7e419..85c19d63f9fb 100644
--- a/drivers/dma/virt-dma.h
+++ b/drivers/dma/virt-dma.h
@@ -32,6 +32,8 @@ struct virt_dma_chan {
struct list_head desc_submitted;
struct list_head desc_issued;
struct list_head desc_completed;
+
+ struct virt_dma_desc *cyclic;
};
static inline struct virt_dma_chan *to_virt_chan(struct dma_chan *chan)
@@ -92,6 +94,18 @@ static inline void vchan_cookie_complete(struct virt_dma_desc *vd)
}
/**
+ * vchan_cyclic_callback - report the completion of a period
+ * vd: virtual descriptor
+ */
+static inline void vchan_cyclic_callback(struct virt_dma_desc *vd)
+{
+ struct virt_dma_chan *vc = to_virt_chan(vd->tx.chan);
+
+ vc->cyclic = vd;
+ tasklet_schedule(&vc->task);
+}
+
+/**
* vchan_next_desc - peek at the next descriptor to be processed
* vc: virtual channel to obtain descriptor from
*