Skip to content

Commit

Permalink
dmaengine: dw-axi-dmac: Fix a non-atomic update
Browse files Browse the repository at this point in the history
dw_axi_dma_interrupt disables interrupts for the duration of the channel
handling. It does so by clearing a bit in the DMA_CFG register - an
action that involves a read-modify-write. That in itself would be safe
because there will be no further interrupts, hence no reentrancy, were
it the only bit of code accessing that register.

The only neighbour of INT_EN is DMAC_EN - the main enable for the block.
That's not the sort of thing you would expect to be modified during the
normal course of operation, but bizarrely it is set at the start of the
transfer of every block, in axi_chan_block_xfer_star, by a call to
axi_dma_enable. This can lead to INT_EN being accidentally cleared,
which causes all DMA transfers to time out.

One might think that the enabling was being delayed until the first
transfer, but the probe function calls axi_dma_resume which in turn
calls axi_dma_enable, so that isn't the case.

Fix the atomicity problem by removing the spurious call to
axi_dma_enable.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
  • Loading branch information
pelwell committed Mar 15, 2024
1 parent 4f9425b commit bade6f8
Showing 1 changed file with 0 additions and 2 deletions.
2 changes: 0 additions & 2 deletions drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,6 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
return;
}

axi_dma_enable(chan->chip);

config.dst_multblk_type = DWAXIDMAC_MBLK_TYPE_LL;
config.src_multblk_type = DWAXIDMAC_MBLK_TYPE_LL;
config.tt_fc = DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC;
Expand Down

0 comments on commit bade6f8

Please sign in to comment.