[PATCH 7/8] dmaengine: fsl-edma: wait until no hardware request is in progress

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Wait DMA hardware complete cleanup work by checking HRS bit before
disabling the channel to make sure trail data is already written to
memory.

Fixes: 72f5801a4e2b7 ("dmaengine: fsl-edma: integrate v3 support")
Signed-off-by: Larisa Grigore <larisa.grigore@xxxxxxxxxxx>
---
 drivers/dma/fsl-edma-common.c | 9 +++++++++
 drivers/dma/fsl-edma-common.h | 4 ++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 62d51b269e54..d364514f21be 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_domain.h>
 
@@ -127,11 +128,19 @@ static void fsl_edma_enable_request(struct fsl_edma_chan *fsl_chan)
 
 static void fsl_edma3_disable_request(struct fsl_edma_chan *fsl_chan)
 {
+	struct fsl_edma_engine *fsl_edma = fsl_chan->edma;
+	struct edma_regs *regs = &fsl_chan->edma->regs;
 	u32 val = edma_readl_chreg(fsl_chan, ch_csr);
+	u32 ch = fsl_chan->vchan.chan.chan_id;
 	u32 flags;
 
 	flags = fsl_edma_drvflags(fsl_chan);
 
+	/* Make sure there is no hardware request in progress. */
+	read_poll_timeout(edma_readl, val, !(val & EDMA_V3_MP_HRS_CH(ch)),
+			  EDMA_USEC_POLL, EDMA_USEC_TIMEOUT, false, fsl_edma,
+			  regs->v3.hrs);
+
 	if (flags & FSL_EDMA_DRV_HAS_CHMUX)
 		edma_writel(fsl_chan->edma, 0, fsl_chan->mux_addr);
 
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index 63e908fc3575..ed210bd71681 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -70,6 +70,10 @@
 #define EDMA_V3_CH_CSR_ACTIVE      BIT(31)
 #define EDMA_V3_CH_ES_ERR          BIT(31)
 #define EDMA_V3_MP_ES_VLD          BIT(31)
+#define EDMA_V3_MP_HRS_CH(ch)      BIT(ch)
+
+#define EDMA_USEC_POLL		10
+#define EDMA_USEC_TIMEOUT	10000
 
 enum fsl_edma_pm_state {
 	RUNNING = 0,
-- 
2.47.0





[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux