mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
dmaengine: stm32-dma: fix residue in case of MDMA chaining
commit67e13e8974upstream. In case of MDMA chaining, DMA is configured in Double-Buffer Mode (DBM) with two periods, but if transfer has been prepared with _prep_slave_sg(), the transfer is not marked cyclic (=!chan->desc->cyclic). However, as DBM is activated for MDMA chaining, residue computation must take into account cyclic constraints. With only two periods in MDMA chaining, and no update due to Transfer Complete interrupt masked, n_sg is always 0. If DMA current memory address (depending on SxCR.CT and SxM0AR/SxM1AR) does not correspond, it means n_sg should be increased. Then, the residue of the current period is the one read from SxNDTR and should not be overwritten with the full period length. Fixes:723795173c("dmaengine: stm32-dma: add support to trigger STM32 MDMA") Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20231004155024.2609531-2-amelie.delaunay@foss.st.com Signed-off-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
1e3b981a25
commit
fe15819408
@@ -1389,11 +1389,12 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan,
|
|||||||
|
|
||||||
residue = stm32_dma_get_remaining_bytes(chan);
|
residue = stm32_dma_get_remaining_bytes(chan);
|
||||||
|
|
||||||
if (chan->desc->cyclic && !stm32_dma_is_current_sg(chan)) {
|
if ((chan->desc->cyclic || chan->trig_mdma) && !stm32_dma_is_current_sg(chan)) {
|
||||||
n_sg++;
|
n_sg++;
|
||||||
if (n_sg == chan->desc->num_sgs)
|
if (n_sg == chan->desc->num_sgs)
|
||||||
n_sg = 0;
|
n_sg = 0;
|
||||||
residue = sg_req->len;
|
if (!chan->trig_mdma)
|
||||||
|
residue = sg_req->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1403,7 +1404,7 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan,
|
|||||||
* residue = remaining bytes from NDTR + remaining
|
* residue = remaining bytes from NDTR + remaining
|
||||||
* periods/sg to be transferred
|
* periods/sg to be transferred
|
||||||
*/
|
*/
|
||||||
if (!chan->desc->cyclic || n_sg != 0)
|
if ((!chan->desc->cyclic && !chan->trig_mdma) || n_sg != 0)
|
||||||
for (i = n_sg; i < desc->num_sgs; i++)
|
for (i = n_sg; i < desc->num_sgs; i++)
|
||||||
residue += desc->sg_req[i].len;
|
residue += desc->sg_req[i].len;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user