summaryrefslogtreecommitdiff
path: root/drivers/dma
diff options
context:
space:
mode:
authorTommaso Merciai <tommaso.merciai.xr@bp.renesas.com>2026-09-22 12:20:37 +0300
committerVinod Koul <vkoul@kernel.org>2026-10-05 17:34:10 +0200
commit9db8e502b34bc1df8078abd0169a4fa0624de3bb (patch)
tree97858573cb83f899b7275f2b8ab516742f5a0e31 /drivers/dma
parent57946765c242005bdb16d17944c27662c8c5b013 (diff)
dmaengine: sh: rz-dmac: Fix off-by-one in residue lmdesc lookup
lmdesc->nxla is the address of the next descriptor, so comparing it against CRLA, which is the address of the current descriptor, finds the descriptor before the active one, not the active one. The residue loops below then summed one lmdesc too many on top of that. Compare each descriptor's own address to CRLA instead, and add tb after advancing to the next lmdesc. Fixes: 21323b118c16 ("dmaengine: sh: rz-dmac: Add device_tx_status() callback") Fixes: 172bfb57481c ("dmaengine: sh: rz-dmac: Add cyclic DMA support") Cc: stable@vger.kernel.org Suggested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260922092037.224884-1-claudiu.beznea@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/sh/rz-dmac.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
index ca76f1bb45c4..fdd7131e890a 100644
--- a/drivers/dma/sh/rz-dmac.c
+++ b/drivers/dma/sh/rz-dmac.c
@@ -937,7 +937,7 @@ static u32 rz_dmac_calculate_residue_bytes_in_vd(struct rz_dmac_chan *channel,
struct rz_dmac *dmac = to_rz_dmac(chan->device);
u32 residue = 0, i = 0;
- while (lmdesc->nxla != crla) {
+ while (rz_dmac_lmdesc_addr(channel, lmdesc) != crla) {
lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc);
if (++i >= DMAC_NR_LMDESC)
return 0;
@@ -948,13 +948,13 @@ static u32 rz_dmac_calculate_residue_bytes_in_vd(struct rz_dmac_chan *channel,
u32 start_lmdesc_addr = rz_dmac_lmdesc_addr(channel, desc->start_lmdesc);
while (lmdesc->nxla != start_lmdesc_addr) {
- residue += lmdesc->tb;
lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc);
+ residue += lmdesc->tb;
}
} else {
while (lmdesc->chcfg & CHCFG_DEM) {
- residue += lmdesc->tb;
lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc);
+ residue += lmdesc->tb;
}
}