.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Virtual DMA channel support for DMAengine |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2012 Russell King |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | 6 | */ |
---|
10 | 7 | #include <linux/device.h> |
---|
11 | 8 | #include <linux/dmaengine.h> |
---|
.. | .. |
---|
83 | 80 | * This tasklet handles the completion of a DMA descriptor by |
---|
84 | 81 | * calling its callback and freeing it. |
---|
85 | 82 | */ |
---|
86 | | -static void vchan_complete(unsigned long arg) |
---|
| 83 | +static void vchan_complete(struct tasklet_struct *t) |
---|
87 | 84 | { |
---|
88 | | - struct virt_dma_chan *vc = (struct virt_dma_chan *)arg; |
---|
| 85 | + struct virt_dma_chan *vc = from_tasklet(vc, t, task); |
---|
89 | 86 | struct virt_dma_desc *vd, *_vd; |
---|
90 | 87 | struct dmaengine_desc_callback cb; |
---|
91 | 88 | LIST_HEAD(head); |
---|
.. | .. |
---|
101 | 98 | } |
---|
102 | 99 | spin_unlock_irq(&vc->lock); |
---|
103 | 100 | |
---|
104 | | - dmaengine_desc_callback_invoke(&cb, NULL); |
---|
| 101 | + dmaengine_desc_callback_invoke(&cb, &vd->tx_result); |
---|
105 | 102 | |
---|
106 | 103 | list_for_each_entry_safe(vd, _vd, &head, node) { |
---|
107 | 104 | dmaengine_desc_get_callback(&vd->tx, &cb); |
---|
108 | 105 | |
---|
109 | 106 | list_del(&vd->node); |
---|
| 107 | + dmaengine_desc_callback_invoke(&cb, &vd->tx_result); |
---|
110 | 108 | vchan_vdesc_fini(vd); |
---|
111 | | - |
---|
112 | | - dmaengine_desc_callback_invoke(&cb, NULL); |
---|
113 | 109 | } |
---|
114 | 110 | } |
---|
115 | 111 | |
---|
.. | .. |
---|
118 | 114 | struct virt_dma_desc *vd, *_vd; |
---|
119 | 115 | |
---|
120 | 116 | list_for_each_entry_safe(vd, _vd, head, node) { |
---|
121 | | - if (dmaengine_desc_test_reuse(&vd->tx)) { |
---|
122 | | - list_move_tail(&vd->node, &vc->desc_allocated); |
---|
123 | | - } else { |
---|
124 | | - dev_dbg(vc->chan.device->dev, "txd %p: freeing\n", vd); |
---|
125 | | - list_del(&vd->node); |
---|
126 | | - vc->desc_free(vd); |
---|
127 | | - } |
---|
| 117 | + list_del(&vd->node); |
---|
| 118 | + vchan_vdesc_fini(vd); |
---|
128 | 119 | } |
---|
129 | 120 | } |
---|
130 | 121 | EXPORT_SYMBOL_GPL(vchan_dma_desc_free_list); |
---|
.. | .. |
---|
138 | 129 | INIT_LIST_HEAD(&vc->desc_submitted); |
---|
139 | 130 | INIT_LIST_HEAD(&vc->desc_issued); |
---|
140 | 131 | INIT_LIST_HEAD(&vc->desc_completed); |
---|
| 132 | + INIT_LIST_HEAD(&vc->desc_terminated); |
---|
141 | 133 | |
---|
142 | | - tasklet_init(&vc->task, vchan_complete, (unsigned long)vc); |
---|
| 134 | + tasklet_setup(&vc->task, vchan_complete); |
---|
143 | 135 | |
---|
144 | 136 | vc->chan.device = dmadev; |
---|
145 | 137 | list_add_tail(&vc->chan.device_node, &dmadev->channels); |
---|