diff options
author | Frank Li <Frank.Li@nxp.com> | 2023-08-23 20:26:35 +0200 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2023-09-28 13:28:57 +0200 |
commit | 3f4b82167a3b1f4ddb33d890f758a042ef4ceef1 (patch) | |
tree | 6cda9d13183e79dd4d12539d895365c079d8b7ef /drivers/dma/fsl-edma-common.c | |
parent | dt-bindings: dmaengine: zynqmp_dma: add xlnx,bus-width required property (diff) | |
download | linux-3f4b82167a3b1f4ddb33d890f758a042ef4ceef1.tar.xz linux-3f4b82167a3b1f4ddb33d890f758a042ef4ceef1.zip |
dmaengine: fsl-edma: fix edma4 channel enable failure on second attempt
When attempting to start DMA for the second time using
fsl_edma3_enable_request(), channel never start.
CHn_MUX must have a unique value when selecting a peripheral slot in the
channel mux configuration. The only value that may overlap is source 0.
If there is an attempt to write a mux configuration value that is already
consumed by another channel, a mux configuration of 0 (SRC = 0) will be
written.
Check CHn_MUX before writing in fsl_edma3_enable_request().
Fixes: 72f5801a4e2b ("dmaengine: fsl-edma: integrate v3 support")
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20230823182635.2618118-1-Frank.Li@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/fsl-edma-common.c')
-rw-r--r-- | drivers/dma/fsl-edma-common.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index 50203b82f9f5..6a3abe5b1790 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -92,8 +92,14 @@ static void fsl_edma3_enable_request(struct fsl_edma_chan *fsl_chan) edma_writel_chreg(fsl_chan, val, ch_sbr); - if (flags & FSL_EDMA_DRV_HAS_CHMUX) - edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux); + if (flags & FSL_EDMA_DRV_HAS_CHMUX) { + /* + * ch_mux: With the exception of 0, attempts to write a value + * already in use will be forced to 0. + */ + if (!edma_readl_chreg(fsl_chan, ch_mux)) + edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux); + } val = edma_readl_chreg(fsl_chan, ch_csr); val |= EDMA_V3_CH_CSR_ERQ; |