diff options
Diffstat (limited to 'drivers/dma/edma.c')
-rw-r--r-- | drivers/dma/edma.c | 18 |
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; |