aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/dw_dmac.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index b15c32ca0ef..265d43c8b35 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -195,18 +195,21 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
195/*----------------------------------------------------------------------*/ 195/*----------------------------------------------------------------------*/
196 196
197static void 197static void
198dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc) 198dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
199 bool callback_required)
199{ 200{
200 dma_async_tx_callback callback; 201 dma_async_tx_callback callback = NULL;
201 void *param; 202 void *param = NULL;
202 struct dma_async_tx_descriptor *txd = &desc->txd; 203 struct dma_async_tx_descriptor *txd = &desc->txd;
203 struct dw_desc *child; 204 struct dw_desc *child;
204 205
205 dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie); 206 dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
206 207
207 dwc->completed = txd->cookie; 208 dwc->completed = txd->cookie;
208 callback = txd->callback; 209 if (callback_required) {
209 param = txd->callback_param; 210 callback = txd->callback;
211 param = txd->callback_param;
212 }
210 213
211 dwc_sync_desc_for_cpu(dwc, desc); 214 dwc_sync_desc_for_cpu(dwc, desc);
212 215
@@ -238,11 +241,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc)
238 } 241 }
239 } 242 }
240 243
241 /* 244 if (callback_required && callback)
242 * The API requires that no submissions are done from a
243 * callback, so we don't need to drop the lock here
244 */
245 if (callback)
246 callback(param); 245 callback(param);
247} 246}
248 247
@@ -272,7 +271,7 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
272 } 271 }
273 272
274 list_for_each_entry_safe(desc, _desc, &list, desc_node) 273 list_for_each_entry_safe(desc, _desc, &list, desc_node)
275 dwc_descriptor_complete(dwc, desc); 274 dwc_descriptor_complete(dwc, desc, true);
276} 275}
277 276
278static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) 277static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
@@ -322,7 +321,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
322 * No descriptors so far seem to be in progress, i.e. 321 * No descriptors so far seem to be in progress, i.e.
323 * this one must be done. 322 * this one must be done.
324 */ 323 */
325 dwc_descriptor_complete(dwc, desc); 324 dwc_descriptor_complete(dwc, desc, true);
326 } 325 }
327 326
328 dev_err(chan2dev(&dwc->chan), 327 dev_err(chan2dev(&dwc->chan),
@@ -384,7 +383,7 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
384 dwc_dump_lli(dwc, &child->lli); 383 dwc_dump_lli(dwc, &child->lli);
385 384
386 /* Pretend the descriptor completed successfully */ 385 /* Pretend the descriptor completed successfully */
387 dwc_descriptor_complete(dwc, bad_desc); 386 dwc_descriptor_complete(dwc, bad_desc, true);
388} 387}
389 388
390/* --------------------- Cyclic DMA API extensions -------------------- */ 389/* --------------------- Cyclic DMA API extensions -------------------- */
@@ -831,7 +830,7 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
831 830
832 /* Flush all pending and queued descriptors */ 831 /* Flush all pending and queued descriptors */
833 list_for_each_entry_safe(desc, _desc, &list, desc_node) 832 list_for_each_entry_safe(desc, _desc, &list, desc_node)
834 dwc_descriptor_complete(dwc, desc); 833 dwc_descriptor_complete(dwc, desc, false);
835 834
836 return 0; 835 return 0;
837} 836}