aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/edma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/edma.c')
-rw-r--r--drivers/dma/edma.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 4f6d87bcaa0d..f9075129d27c 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -222,9 +222,9 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
222 enum dma_slave_buswidth dev_width; 222 enum dma_slave_buswidth dev_width;
223 u32 burst; 223 u32 burst;
224 struct scatterlist *sg; 224 struct scatterlist *sg;
225 int i;
226 int acnt, bcnt, ccnt, src, dst, cidx; 225 int acnt, bcnt, ccnt, src, dst, cidx;
227 int src_bidx, dst_bidx, src_cidx, dst_cidx; 226 int src_bidx, dst_bidx, src_cidx, dst_cidx;
227 int i, nslots;
228 228
229 if (unlikely(!echan || !sgl || !sg_len)) 229 if (unlikely(!echan || !sgl || !sg_len))
230 return NULL; 230 return NULL;
@@ -262,8 +262,10 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
262 262
263 edesc->pset_nr = sg_len; 263 edesc->pset_nr = sg_len;
264 264
265 for_each_sg(sgl, sg, sg_len, i) { 265 /* Allocate a PaRAM slot, if needed */
266 /* Allocate a PaRAM slot, if needed */ 266 nslots = min_t(unsigned, MAX_NR_SG, sg_len);
267
268 for (i = 0; i < nslots; i++) {
267 if (echan->slot[i] < 0) { 269 if (echan->slot[i] < 0) {
268 echan->slot[i] = 270 echan->slot[i] =
269 edma_alloc_slot(EDMA_CTLR(echan->ch_num), 271 edma_alloc_slot(EDMA_CTLR(echan->ch_num),
@@ -273,6 +275,10 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
273 return NULL; 275 return NULL;
274 } 276 }
275 } 277 }
278 }
279
280 /* Configure PaRAM sets for each SG */
281 for_each_sg(sgl, sg, sg_len, i) {
276 282
277 acnt = dev_width; 283 acnt = dev_width;
278 284
@@ -330,6 +336,12 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
330 /* Configure A or AB synchronized transfers */ 336 /* Configure A or AB synchronized transfers */
331 if (edesc->absync) 337 if (edesc->absync)
332 edesc->pset[i].opt |= SYNCDIM; 338 edesc->pset[i].opt |= SYNCDIM;
339
340 /* If this is the last in a current SG set of transactions,
341 enable interrupts so that next set is processed */
342 if (!((i+1) % MAX_NR_SG))
343 edesc->pset[i].opt |= TCINTEN;
344
333 /* If this is the last set, enable completion interrupt flag */ 345 /* If this is the last set, enable completion interrupt flag */
334 if (i == sg_len - 1) 346 if (i == sg_len - 1)
335 edesc->pset[i].opt |= TCINTEN; 347 edesc->pset[i].opt |= TCINTEN;