summaryrefslogtreecommitdiffstats
path: root/drivers/dma/fsl-edma-common.c
diff options
context:
space:
mode:
authorFrank Li <Frank.Li@nxp.com>2023-08-23 20:26:35 +0200
committerVinod Koul <vkoul@kernel.org>2023-09-28 13:28:57 +0200
commit3f4b82167a3b1f4ddb33d890f758a042ef4ceef1 (patch)
tree6cda9d13183e79dd4d12539d895365c079d8b7ef /drivers/dma/fsl-edma-common.c
parentdt-bindings: dmaengine: zynqmp_dma: add xlnx,bus-width required property (diff)
downloadlinux-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.c10
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;