aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2014-07-16 17:15:48 -0400
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2014-12-23 04:13:02 -0500
commitccadee9b1e90dc6d3d97a20ac96cb1a82e0d5a1d (patch)
treef0ea642c3e287ddbd274789216e8234bf788885f
parent87244fe5abdf1dbaf4e438d80cf641bf3c01d5cf (diff)
dmaengine: rcar-dmac: Implement support for hardware descriptor lists
The DMAC supports hardware-based auto-configuration from descriptor lists. This reduces the number of interrupts required for processing a DMA transfer. Support that mode in the driver. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
-rw-r--r--drivers/dma/sh/rcar-dmac.c304
1 files changed, 253 insertions, 51 deletions
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index 89d40f9730ba..6e7cdab61827 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -10,6 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/dma-mapping.h>
13#include <linux/dmaengine.h> 14#include <linux/dmaengine.h>
14#include <linux/interrupt.h> 15#include <linux/interrupt.h>
15#include <linux/list.h> 16#include <linux/list.h>
@@ -41,6 +42,19 @@ struct rcar_dmac_xfer_chunk {
41}; 42};
42 43
43/* 44/*
45 * struct rcar_dmac_hw_desc - Hardware descriptor for a transfer chunk
46 * @sar: value of the SAR register (source address)
47 * @dar: value of the DAR register (destination address)
48 * @tcr: value of the TCR register (transfer count)
49 */
50struct rcar_dmac_hw_desc {
51 u32 sar;
52 u32 dar;
53 u32 tcr;
54 u32 reserved;
55} __attribute__((__packed__));
56
57/*
44 * struct rcar_dmac_desc - R-Car Gen2 DMA Transfer Descriptor 58 * struct rcar_dmac_desc - R-Car Gen2 DMA Transfer Descriptor
45 * @async_tx: base DMA asynchronous transaction descriptor 59 * @async_tx: base DMA asynchronous transaction descriptor
46 * @direction: direction of the DMA transfer 60 * @direction: direction of the DMA transfer
@@ -49,6 +63,10 @@ struct rcar_dmac_xfer_chunk {
49 * @node: entry in the channel's descriptors lists 63 * @node: entry in the channel's descriptors lists
50 * @chunks: list of transfer chunks for this transfer 64 * @chunks: list of transfer chunks for this transfer
51 * @running: the transfer chunk being currently processed 65 * @running: the transfer chunk being currently processed
66 * @nchunks: number of transfer chunks for this transfer
67 * @hwdescs.mem: hardware descriptors memory for the transfer
68 * @hwdescs.dma: device address of the hardware descriptors memory
69 * @hwdescs.size: size of the hardware descriptors in bytes
52 * @size: transfer size in bytes 70 * @size: transfer size in bytes
53 * @cyclic: when set indicates that the DMA transfer is cyclic 71 * @cyclic: when set indicates that the DMA transfer is cyclic
54 */ 72 */
@@ -61,6 +79,13 @@ struct rcar_dmac_desc {
61 struct list_head node; 79 struct list_head node;
62 struct list_head chunks; 80 struct list_head chunks;
63 struct rcar_dmac_xfer_chunk *running; 81 struct rcar_dmac_xfer_chunk *running;
82 unsigned int nchunks;
83
84 struct {
85 struct rcar_dmac_hw_desc *mem;
86 dma_addr_t dma;
87 size_t size;
88 } hwdescs;
64 89
65 unsigned int size; 90 unsigned int size;
66 bool cyclic; 91 bool cyclic;
@@ -217,7 +242,8 @@ struct rcar_dmac {
217#define RCAR_DMATSRB 0x0038 242#define RCAR_DMATSRB 0x0038
218#define RCAR_DMACHCRB 0x001c 243#define RCAR_DMACHCRB 0x001c
219#define RCAR_DMACHCRB_DCNT(n) ((n) << 24) 244#define RCAR_DMACHCRB_DCNT(n) ((n) << 24)
220#define RCAR_DMACHCRB_DPTR(n) ((n) << 16) 245#define RCAR_DMACHCRB_DPTR_MASK (0xff << 16)
246#define RCAR_DMACHCRB_DPTR_SHIFT 16
221#define RCAR_DMACHCRB_DRST (1 << 15) 247#define RCAR_DMACHCRB_DRST (1 << 15)
222#define RCAR_DMACHCRB_DTS (1 << 8) 248#define RCAR_DMACHCRB_DTS (1 << 8)
223#define RCAR_DMACHCRB_SLM_NORMAL (0 << 4) 249#define RCAR_DMACHCRB_SLM_NORMAL (0 << 4)
@@ -289,30 +315,81 @@ static bool rcar_dmac_chan_is_busy(struct rcar_dmac_chan *chan)
289static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan) 315static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan)
290{ 316{
291 struct rcar_dmac_desc *desc = chan->desc.running; 317 struct rcar_dmac_desc *desc = chan->desc.running;
292 struct rcar_dmac_xfer_chunk *chunk = desc->running; 318 u32 chcr = desc->chcr;
293
294 dev_dbg(chan->chan.device->dev,
295 "chan%u: queue chunk %p: %u@%pad -> %pad\n",
296 chan->index, chunk, chunk->size, &chunk->src_addr,
297 &chunk->dst_addr);
298 319
299 WARN_ON_ONCE(rcar_dmac_chan_is_busy(chan)); 320 WARN_ON_ONCE(rcar_dmac_chan_is_busy(chan));
300 321
322 if (chan->mid_rid >= 0)
323 rcar_dmac_chan_write(chan, RCAR_DMARS, chan->mid_rid);
324
325 if (desc->hwdescs.mem) {
326 dev_dbg(chan->chan.device->dev,
327 "chan%u: queue desc %p: %u@%pad\n",
328 chan->index, desc, desc->nchunks, &desc->hwdescs.dma);
329
301#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 330#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
302 rcar_dmac_chan_write(chan, RCAR_DMAFIXSAR, chunk->src_addr >> 32); 331 rcar_dmac_chan_write(chan, RCAR_DMAFIXDPBASE,
303 rcar_dmac_chan_write(chan, RCAR_DMAFIXDAR, chunk->dst_addr >> 32); 332 desc->hwdescs.dma >> 32);
304#endif 333#endif
305 rcar_dmac_chan_write(chan, RCAR_DMASAR, chunk->src_addr & 0xffffffff); 334 rcar_dmac_chan_write(chan, RCAR_DMADPBASE,
306 rcar_dmac_chan_write(chan, RCAR_DMADAR, chunk->dst_addr & 0xffffffff); 335 (desc->hwdescs.dma & 0xfffffff0) |
336 RCAR_DMADPBASE_SEL);
337 rcar_dmac_chan_write(chan, RCAR_DMACHCRB,
338 RCAR_DMACHCRB_DCNT(desc->nchunks - 1) |
339 RCAR_DMACHCRB_DRST);
307 340
308 if (chan->mid_rid >= 0) 341 /*
309 rcar_dmac_chan_write(chan, RCAR_DMARS, chan->mid_rid); 342 * Program the descriptor stage interrupt to occur after the end
343 * of the first stage.
344 */
345 rcar_dmac_chan_write(chan, RCAR_DMADPCR, RCAR_DMADPCR_DIPT(1));
346
347 chcr |= RCAR_DMACHCR_RPT_SAR | RCAR_DMACHCR_RPT_DAR
348 | RCAR_DMACHCR_RPT_TCR | RCAR_DMACHCR_DPB;
349
350 /*
351 * If the descriptor isn't cyclic enable normal descriptor mode
352 * and the transfer completion interrupt.
353 */
354 if (!desc->cyclic)
355 chcr |= RCAR_DMACHCR_DPM_ENABLED | RCAR_DMACHCR_IE;
356 /*
357 * If the descriptor is cyclic and has a callback enable the
358 * descriptor stage interrupt in infinite repeat mode.
359 */
360 else if (desc->async_tx.callback)
361 chcr |= RCAR_DMACHCR_DPM_INFINITE | RCAR_DMACHCR_DSIE;
362 /*
363 * Otherwise just select infinite repeat mode without any
364 * interrupt.
365 */
366 else
367 chcr |= RCAR_DMACHCR_DPM_INFINITE;
368 } else {
369 struct rcar_dmac_xfer_chunk *chunk = desc->running;
310 370
311 rcar_dmac_chan_write(chan, RCAR_DMATCR, 371 dev_dbg(chan->chan.device->dev,
312 chunk->size >> desc->xfer_shift); 372 "chan%u: queue chunk %p: %u@%pad -> %pad\n",
373 chan->index, chunk, chunk->size, &chunk->src_addr,
374 &chunk->dst_addr);
313 375
314 rcar_dmac_chan_write(chan, RCAR_DMACHCR, desc->chcr | RCAR_DMACHCR_DE | 376#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
315 RCAR_DMACHCR_IE); 377 rcar_dmac_chan_write(chan, RCAR_DMAFIXSAR,
378 chunk->src_addr >> 32);
379 rcar_dmac_chan_write(chan, RCAR_DMAFIXDAR,
380 chunk->dst_addr >> 32);
381#endif
382 rcar_dmac_chan_write(chan, RCAR_DMASAR,
383 chunk->src_addr & 0xffffffff);
384 rcar_dmac_chan_write(chan, RCAR_DMADAR,
385 chunk->dst_addr & 0xffffffff);
386 rcar_dmac_chan_write(chan, RCAR_DMATCR,
387 chunk->size >> desc->xfer_shift);
388
389 chcr |= RCAR_DMACHCR_DPM_DISABLED | RCAR_DMACHCR_IE;
390 }
391
392 rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr | RCAR_DMACHCR_DE);
316} 393}
317 394
318static int rcar_dmac_init(struct rcar_dmac *dmac) 395static int rcar_dmac_init(struct rcar_dmac *dmac)
@@ -403,31 +480,58 @@ static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
403 * @desc: the descriptor 480 * @desc: the descriptor
404 * 481 *
405 * Put the descriptor and its transfer chunk descriptors back in the channel's 482 * Put the descriptor and its transfer chunk descriptors back in the channel's
406 * free descriptors lists. The descriptor's chunk will be reinitialized to an 483 * free descriptors lists, and free the hardware descriptors list memory. The
407 * empty list as a result. 484 * descriptor's chunks list will be reinitialized to an empty list as a result.
408 * 485 *
409 * The descriptor must have been removed from the channel's done list before 486 * The descriptor must have been removed from the channel's lists before calling
410 * calling this function. 487 * this function.
411 * 488 *
412 * Locking: Must be called with the channel lock held. 489 * Locking: Must be called in non-atomic context.
413 */ 490 */
414static void rcar_dmac_desc_put(struct rcar_dmac_chan *chan, 491static void rcar_dmac_desc_put(struct rcar_dmac_chan *chan,
415 struct rcar_dmac_desc *desc) 492 struct rcar_dmac_desc *desc)
416{ 493{
494 if (desc->hwdescs.mem) {
495 dma_free_coherent(NULL, desc->hwdescs.size, desc->hwdescs.mem,
496 desc->hwdescs.dma);
497 desc->hwdescs.mem = NULL;
498 }
499
500 spin_lock_irq(&chan->lock);
417 list_splice_tail_init(&desc->chunks, &chan->desc.chunks_free); 501 list_splice_tail_init(&desc->chunks, &chan->desc.chunks_free);
418 list_add_tail(&desc->node, &chan->desc.free); 502 list_add_tail(&desc->node, &chan->desc.free);
503 spin_unlock_irq(&chan->lock);
419} 504}
420 505
421static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan) 506static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
422{ 507{
423 struct rcar_dmac_desc *desc, *_desc; 508 struct rcar_dmac_desc *desc, *_desc;
509 LIST_HEAD(list);
424 510
425 list_for_each_entry_safe(desc, _desc, &chan->desc.wait, node) { 511 /*
512 * We have to temporarily move all descriptors from the wait list to a
513 * local list as iterating over the wait list, even with
514 * list_for_each_entry_safe, isn't safe if we release the channel lock
515 * around the rcar_dmac_desc_put() call.
516 */
517 spin_lock_irq(&chan->lock);
518 list_splice_init(&chan->desc.wait, &list);
519 spin_unlock_irq(&chan->lock);
520
521 list_for_each_entry_safe(desc, _desc, &list, node) {
426 if (async_tx_test_ack(&desc->async_tx)) { 522 if (async_tx_test_ack(&desc->async_tx)) {
427 list_del(&desc->node); 523 list_del(&desc->node);
428 rcar_dmac_desc_put(chan, desc); 524 rcar_dmac_desc_put(chan, desc);
429 } 525 }
430 } 526 }
527
528 if (list_empty(&list))
529 return;
530
531 /* Put the remaining descriptors back in the wait list. */
532 spin_lock_irq(&chan->lock);
533 list_splice(&list, &chan->desc.wait);
534 spin_unlock_irq(&chan->lock);
431} 535}
432 536
433/* 537/*
@@ -444,11 +548,11 @@ static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
444 struct rcar_dmac_desc *desc; 548 struct rcar_dmac_desc *desc;
445 int ret; 549 int ret;
446 550
447 spin_lock_irq(&chan->lock);
448
449 /* Recycle acked descriptors before attempting allocation. */ 551 /* Recycle acked descriptors before attempting allocation. */
450 rcar_dmac_desc_recycle_acked(chan); 552 rcar_dmac_desc_recycle_acked(chan);
451 553
554 spin_lock_irq(&chan->lock);
555
452 do { 556 do {
453 if (list_empty(&chan->desc.free)) { 557 if (list_empty(&chan->desc.free)) {
454 /* 558 /*
@@ -547,6 +651,28 @@ rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan)
547 return chunk; 651 return chunk;
548} 652}
549 653
654static void rcar_dmac_alloc_hwdesc(struct rcar_dmac_chan *chan,
655 struct rcar_dmac_desc *desc)
656{
657 struct rcar_dmac_xfer_chunk *chunk;
658 struct rcar_dmac_hw_desc *hwdesc;
659 size_t size = desc->nchunks * sizeof(*hwdesc);
660
661 hwdesc = dma_alloc_coherent(NULL, size, &desc->hwdescs.dma, GFP_NOWAIT);
662 if (!hwdesc)
663 return;
664
665 desc->hwdescs.mem = hwdesc;
666 desc->hwdescs.size = size;
667
668 list_for_each_entry(chunk, &desc->chunks, node) {
669 hwdesc->sar = chunk->src_addr;
670 hwdesc->dar = chunk->dst_addr;
671 hwdesc->tcr = chunk->size >> desc->xfer_shift;
672 hwdesc++;
673 }
674}
675
550/* ----------------------------------------------------------------------------- 676/* -----------------------------------------------------------------------------
551 * Stop and reset 677 * Stop and reset
552 */ 678 */
@@ -555,7 +681,8 @@ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
555{ 681{
556 u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); 682 u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
557 683
558 chcr &= ~(RCAR_DMACHCR_IE | RCAR_DMACHCR_TE | RCAR_DMACHCR_DE); 684 chcr &= ~(RCAR_DMACHCR_DSE | RCAR_DMACHCR_DSIE | RCAR_DMACHCR_IE |
685 RCAR_DMACHCR_TE | RCAR_DMACHCR_DE);
559 rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr); 686 rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
560} 687}
561 688
@@ -666,8 +793,10 @@ rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl,
666 struct rcar_dmac_xfer_chunk *chunk; 793 struct rcar_dmac_xfer_chunk *chunk;
667 struct rcar_dmac_desc *desc; 794 struct rcar_dmac_desc *desc;
668 struct scatterlist *sg; 795 struct scatterlist *sg;
796 unsigned int nchunks = 0;
669 unsigned int max_chunk_size; 797 unsigned int max_chunk_size;
670 unsigned int full_size = 0; 798 unsigned int full_size = 0;
799 bool highmem = false;
671 unsigned int i; 800 unsigned int i;
672 801
673 desc = rcar_dmac_desc_get(chan); 802 desc = rcar_dmac_desc_get(chan);
@@ -706,6 +835,14 @@ rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl,
706 size = ALIGN(dev_addr, 1ULL << 32) - dev_addr; 835 size = ALIGN(dev_addr, 1ULL << 32) - dev_addr;
707 if (mem_addr >> 32 != (mem_addr + size - 1) >> 32) 836 if (mem_addr >> 32 != (mem_addr + size - 1) >> 32)
708 size = ALIGN(mem_addr, 1ULL << 32) - mem_addr; 837 size = ALIGN(mem_addr, 1ULL << 32) - mem_addr;
838
839 /*
840 * Check if either of the source or destination address
841 * can't be expressed in 32 bits. If so we can't use
842 * hardware descriptor lists.
843 */
844 if (dev_addr >> 32 || mem_addr >> 32)
845 highmem = true;
709#endif 846#endif
710 847
711 chunk = rcar_dmac_xfer_chunk_get(chan); 848 chunk = rcar_dmac_xfer_chunk_get(chan);
@@ -736,11 +873,26 @@ rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl,
736 len -= size; 873 len -= size;
737 874
738 list_add_tail(&chunk->node, &desc->chunks); 875 list_add_tail(&chunk->node, &desc->chunks);
876 nchunks++;
739 } 877 }
740 } 878 }
741 879
880 desc->nchunks = nchunks;
742 desc->size = full_size; 881 desc->size = full_size;
743 882
883 /*
884 * Use hardware descriptor lists if possible when more than one chunk
885 * needs to be transferred (otherwise they don't make much sense).
886 *
887 * The highmem check currently covers the whole transfer. As an
888 * optimization we could use descriptor lists for consecutive lowmem
889 * chunks and direct manual mode for highmem chunks. Whether the
890 * performance improvement would be significant enough compared to the
891 * additional complexity remains to be investigated.
892 */
893 if (!highmem && nchunks > 1)
894 rcar_dmac_alloc_hwdesc(chan, desc);
895
744 return &desc->async_tx; 896 return &desc->async_tx;
745} 897}
746 898
@@ -940,8 +1092,10 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
940 dma_cookie_t cookie) 1092 dma_cookie_t cookie)
941{ 1093{
942 struct rcar_dmac_desc *desc = chan->desc.running; 1094 struct rcar_dmac_desc *desc = chan->desc.running;
1095 struct rcar_dmac_xfer_chunk *running = NULL;
943 struct rcar_dmac_xfer_chunk *chunk; 1096 struct rcar_dmac_xfer_chunk *chunk;
944 unsigned int residue = 0; 1097 unsigned int residue = 0;
1098 unsigned int dptr = 0;
945 1099
946 if (!desc) 1100 if (!desc)
947 return 0; 1101 return 0;
@@ -954,9 +1108,23 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
954 if (cookie != desc->async_tx.cookie) 1108 if (cookie != desc->async_tx.cookie)
955 return desc->size; 1109 return desc->size;
956 1110
1111 /*
1112 * In descriptor mode the descriptor running pointer is not maintained
1113 * by the interrupt handler, find the running descriptor from the
1114 * descriptor pointer field in the CHCRB register. In non-descriptor
1115 * mode just use the running descriptor pointer.
1116 */
1117 if (desc->hwdescs.mem) {
1118 dptr = (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) &
1119 RCAR_DMACHCRB_DPTR_MASK) >> RCAR_DMACHCRB_DPTR_SHIFT;
1120 WARN_ON(dptr >= desc->nchunks);
1121 } else {
1122 running = desc->running;
1123 }
1124
957 /* Compute the size of all chunks still to be transferred. */ 1125 /* Compute the size of all chunks still to be transferred. */
958 list_for_each_entry_reverse(chunk, &desc->chunks, node) { 1126 list_for_each_entry_reverse(chunk, &desc->chunks, node) {
959 if (chunk == desc->running) 1127 if (chunk == running || ++dptr == desc->nchunks)
960 break; 1128 break;
961 1129
962 residue += chunk->size; 1130 residue += chunk->size;
@@ -1025,42 +1193,71 @@ done:
1025 * IRQ handling 1193 * IRQ handling
1026 */ 1194 */
1027 1195
1196static irqreturn_t rcar_dmac_isr_desc_stage_end(struct rcar_dmac_chan *chan)
1197{
1198 struct rcar_dmac_desc *desc = chan->desc.running;
1199 unsigned int stage;
1200
1201 if (WARN_ON(!desc || !desc->cyclic)) {
1202 /*
1203 * This should never happen, there should always be a running
1204 * cyclic descriptor when a descriptor stage end interrupt is
1205 * triggered. Warn and return.
1206 */
1207 return IRQ_NONE;
1208 }
1209
1210 /* Program the interrupt pointer to the next stage. */
1211 stage = (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) &
1212 RCAR_DMACHCRB_DPTR_MASK) >> RCAR_DMACHCRB_DPTR_SHIFT;
1213 rcar_dmac_chan_write(chan, RCAR_DMADPCR, RCAR_DMADPCR_DIPT(stage));
1214
1215 return IRQ_WAKE_THREAD;
1216}
1217
1028static irqreturn_t rcar_dmac_isr_transfer_end(struct rcar_dmac_chan *chan) 1218static irqreturn_t rcar_dmac_isr_transfer_end(struct rcar_dmac_chan *chan)
1029{ 1219{
1030 struct rcar_dmac_desc *desc = chan->desc.running; 1220 struct rcar_dmac_desc *desc = chan->desc.running;
1031 struct rcar_dmac_xfer_chunk *chunk;
1032 irqreturn_t ret = IRQ_WAKE_THREAD; 1221 irqreturn_t ret = IRQ_WAKE_THREAD;
1033 1222
1034 if (WARN_ON_ONCE(!desc)) { 1223 if (WARN_ON_ONCE(!desc)) {
1035 /* 1224 /*
1036 * This should never happen, there should always be 1225 * This should never happen, there should always be a running
1037 * a running descriptor when a transfer ends. Warn and 1226 * descriptor when a transfer end interrupt is triggered. Warn
1038 * return. 1227 * and return.
1039 */ 1228 */
1040 return IRQ_NONE; 1229 return IRQ_NONE;
1041 } 1230 }
1042 1231
1043 /* 1232 /*
1044 * If we haven't completed the last transfer chunk simply move to the 1233 * The transfer end interrupt isn't generated for each chunk when using
1045 * next one. Only wake the IRQ thread if the transfer is cyclic. 1234 * descriptor mode. Only update the running chunk pointer in
1235 * non-descriptor mode.
1046 */ 1236 */
1047 chunk = desc->running; 1237 if (!desc->hwdescs.mem) {
1048 if (!list_is_last(&chunk->node, &desc->chunks)) { 1238 /*
1049 desc->running = list_next_entry(chunk, node); 1239 * If we haven't completed the last transfer chunk simply move
1050 if (!desc->cyclic) 1240 * to the next one. Only wake the IRQ thread if the transfer is
1051 ret = IRQ_HANDLED; 1241 * cyclic.
1052 goto done; 1242 */
1053 } 1243 if (!list_is_last(&desc->running->node, &desc->chunks)) {
1244 desc->running = list_next_entry(desc->running, node);
1245 if (!desc->cyclic)
1246 ret = IRQ_HANDLED;
1247 goto done;
1248 }
1054 1249
1055 /* 1250 /*
1056 * We've completed the last transfer chunk. If the transfer is cyclic, 1251 * We've completed the last transfer chunk. If the transfer is
1057 * move back to the first one. 1252 * cyclic, move back to the first one.
1058 */ 1253 */
1059 if (desc->cyclic) { 1254 if (desc->cyclic) {
1060 desc->running = list_first_entry(&desc->chunks, 1255 desc->running =
1256 list_first_entry(&desc->chunks,
1061 struct rcar_dmac_xfer_chunk, 1257 struct rcar_dmac_xfer_chunk,
1062 node); 1258 node);
1063 goto done; 1259 goto done;
1260 }
1064 } 1261 }
1065 1262
1066 /* The descriptor is complete, move it to the done list. */ 1263 /* The descriptor is complete, move it to the done list. */
@@ -1083,6 +1280,7 @@ done:
1083 1280
1084static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev) 1281static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
1085{ 1282{
1283 u32 mask = RCAR_DMACHCR_DSE | RCAR_DMACHCR_TE;
1086 struct rcar_dmac_chan *chan = dev; 1284 struct rcar_dmac_chan *chan = dev;
1087 irqreturn_t ret = IRQ_NONE; 1285 irqreturn_t ret = IRQ_NONE;
1088 u32 chcr; 1286 u32 chcr;
@@ -1090,8 +1288,12 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
1090 spin_lock(&chan->lock); 1288 spin_lock(&chan->lock);
1091 1289
1092 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); 1290 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
1093 rcar_dmac_chan_write(chan, RCAR_DMACHCR, 1291 if (chcr & RCAR_DMACHCR_TE)
1094 chcr & ~(RCAR_DMACHCR_TE | RCAR_DMACHCR_DE)); 1292 mask |= RCAR_DMACHCR_DE;
1293 rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr & ~mask);
1294
1295 if (chcr & RCAR_DMACHCR_DSE)
1296 ret |= rcar_dmac_isr_desc_stage_end(chan);
1095 1297
1096 if (chcr & RCAR_DMACHCR_TE) 1298 if (chcr & RCAR_DMACHCR_TE)
1097 ret |= rcar_dmac_isr_transfer_end(chan); 1299 ret |= rcar_dmac_isr_transfer_end(chan);
@@ -1148,11 +1350,11 @@ static irqreturn_t rcar_dmac_isr_channel_thread(int irq, void *dev)
1148 list_add_tail(&desc->node, &chan->desc.wait); 1350 list_add_tail(&desc->node, &chan->desc.wait);
1149 } 1351 }
1150 1352
1353 spin_unlock_irq(&chan->lock);
1354
1151 /* Recycle all acked descriptors. */ 1355 /* Recycle all acked descriptors. */
1152 rcar_dmac_desc_recycle_acked(chan); 1356 rcar_dmac_desc_recycle_acked(chan);
1153 1357
1154 spin_unlock_irq(&chan->lock);
1155
1156 return IRQ_HANDLED; 1358 return IRQ_HANDLED;
1157} 1359}
1158 1360