Skip to content

Commit 49db68d

Browse files
esmilvinodkoul
authored andcommitted
dmaengine: dw-axi-dmac: Fix RMW on channel suspend register
When the DMA is configured for more than 8 channels the bits controlling suspend moves to another register. However when adding support for this the new register would be completely overwritten in one case and overwritten with values from the old register in another case. Found by comparing the parallel implementation of more than 8 channel support for the StarFive JH7100 SoC by Samin. Fixes: 8243516 ("dmaengine: dw-axi-dmac: support DMAX_NUM_CHANNELS > 8") Co-developed-by: Samin Guo <samin.guo@starfivetech.com> Signed-off-by: Samin Guo <samin.guo@starfivetech.com> Signed-off-by: Emil Renner Berthing <kernel@esmil.dk> Link: https://lore.kernel.org/r/20220627090939.1775717-1-emil.renner.berthing@canonical.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 44c4237 commit 49db68d

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,8 +1164,9 @@ static int dma_chan_pause(struct dma_chan *dchan)
11641164
BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT;
11651165
axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
11661166
} else {
1167-
val = BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT |
1168-
BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT;
1167+
val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
1168+
val |= BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT |
1169+
BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT;
11691170
axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);
11701171
}
11711172

@@ -1190,12 +1191,13 @@ static inline void axi_chan_resume(struct axi_dma_chan *chan)
11901191
{
11911192
u32 val;
11921193

1193-
val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
11941194
if (chan->chip->dw->hdata->reg_map_8_channels) {
1195+
val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
11951196
val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT);
11961197
val |= (BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT);
11971198
axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
11981199
} else {
1200+
val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
11991201
val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT);
12001202
val |= (BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT);
12011203
axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);

0 commit comments

Comments
 (0)