Skip to content

Commit f5d79af

Browse files
ambarusvinodkoul
authored andcommitted
dmaengine: at_hdmac: Pass residue by address to avoid unnecessary implicit casts
struct dma_tx_state defines residue as u32. atc_get_bytes_left() returned an int which could be either an error or the value of the residue. This could cause problems if the controller supported a u32 buffer transfer size and the u32 value was past the max int can hold. Our controller does not support u32 buffer transfer size, but even so, improve the code and pass the residue by address to avoid unnecessary implicit casts and make atc_get_bytes_left() return 0 on success or -errno on errors. Signed-off-by: Tudor Ambarus <[email protected]> Acked-by: Nicolas Ferre <[email protected]> Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 0e75c28 commit f5d79af

File tree

1 file changed

+30
-24
lines changed

1 file changed

+30
-24
lines changed

drivers/dma/at_hdmac.c

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ static struct at_desc *atc_get_desc_by_cookie(struct at_dma_chan *atchan,
293293
* @current_len: the number of bytes left before reading CTRLA
294294
* @ctrla: the value of CTRLA
295295
*/
296-
static inline int atc_calc_bytes_left(int current_len, u32 ctrla)
296+
static inline u32 atc_calc_bytes_left(u32 current_len, u32 ctrla)
297297
{
298298
u32 btsize = (ctrla & ATC_BTSIZE_MAX);
299299
u32 src_width = ATC_REG_TO_SRC_WIDTH(ctrla);
@@ -308,17 +308,20 @@ static inline int atc_calc_bytes_left(int current_len, u32 ctrla)
308308
}
309309

310310
/**
311-
* atc_get_bytes_left - get the number of bytes residue for a cookie
311+
* atc_get_bytes_left - get the number of bytes residue for a cookie.
312+
* The residue is passed by address and updated on success.
312313
* @chan: DMA channel
313314
* @cookie: transaction identifier to check status of
315+
* @residue: residue to be updated.
316+
* Return 0 on success, -errono otherwise.
314317
*/
315-
static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
318+
static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie,
319+
u32 *residue)
316320
{
317321
struct at_dma_chan *atchan = to_at_dma_chan(chan);
318322
struct at_desc *desc_first = atc_first_active(atchan);
319323
struct at_desc *desc;
320-
int ret;
321-
u32 ctrla, dscr;
324+
u32 len, ctrla, dscr;
322325
unsigned int i;
323326

324327
/*
@@ -333,7 +336,7 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
333336
return desc->total_len;
334337

335338
/* cookie matches to the currently running transfer */
336-
ret = desc_first->total_len;
339+
len = desc_first->total_len;
337340

338341
if (desc_first->lli.dscr) {
339342
/* hardware linked list transfer */
@@ -419,29 +422,31 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
419422
return -ETIMEDOUT;
420423

421424
/* for the first descriptor we can be more accurate */
422-
if (desc_first->lli.dscr == dscr)
423-
return atc_calc_bytes_left(ret, ctrla);
425+
if (desc_first->lli.dscr == dscr) {
426+
*residue = atc_calc_bytes_left(len, ctrla);
427+
return 0;
428+
}
424429

425-
ret -= desc_first->len;
430+
len -= desc_first->len;
426431
list_for_each_entry(desc, &desc_first->tx_list, desc_node) {
427432
if (desc->lli.dscr == dscr)
428433
break;
429434

430-
ret -= desc->len;
435+
len -= desc->len;
431436
}
432437

433438
/*
434439
* For the current descriptor in the chain we can calculate
435440
* the remaining bytes using the channel's register.
436441
*/
437-
ret = atc_calc_bytes_left(ret, ctrla);
442+
*residue = atc_calc_bytes_left(len, ctrla);
438443
} else {
439444
/* single transfer */
440445
ctrla = channel_readl(atchan, CTRLA);
441-
ret = atc_calc_bytes_left(ret, ctrla);
446+
*residue = atc_calc_bytes_left(len, ctrla);
442447
}
443448

444-
return ret;
449+
return 0;
445450
}
446451

447452
/**
@@ -1457,31 +1462,32 @@ atc_tx_status(struct dma_chan *chan,
14571462
{
14581463
struct at_dma_chan *atchan = to_at_dma_chan(chan);
14591464
unsigned long flags;
1460-
enum dma_status ret;
1461-
int bytes = 0;
1465+
enum dma_status dma_status;
1466+
u32 residue;
1467+
int ret;
14621468

1463-
ret = dma_cookie_status(chan, cookie, txstate);
1464-
if (ret == DMA_COMPLETE || !txstate)
1465-
return ret;
1469+
dma_status = dma_cookie_status(chan, cookie, txstate);
1470+
if (dma_status == DMA_COMPLETE || !txstate)
1471+
return dma_status;
14661472

14671473
spin_lock_irqsave(&atchan->lock, flags);
14681474

14691475
/* Get number of bytes left in the active transactions */
1470-
bytes = atc_get_bytes_left(chan, cookie);
1476+
ret = atc_get_bytes_left(chan, cookie, &residue);
14711477

14721478
spin_unlock_irqrestore(&atchan->lock, flags);
14731479

1474-
if (unlikely(bytes < 0)) {
1480+
if (unlikely(ret < 0)) {
14751481
dev_vdbg(chan2dev(chan), "get residual bytes error\n");
14761482
return DMA_ERROR;
14771483
} else {
1478-
dma_set_residue(txstate, bytes);
1484+
dma_set_residue(txstate, residue);
14791485
}
14801486

1481-
dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d residue = %d\n",
1482-
ret, cookie, bytes);
1487+
dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d residue = %u\n",
1488+
dma_status, cookie, residue);
14831489

1484-
return ret;
1490+
return dma_status;
14851491
}
14861492

14871493
/**

0 commit comments

Comments
 (0)