[PATCH 1/2] dmaengine: ep93xx: Always start from BASE0

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

 



The current buffer is being reset to zero on device_free_chan_resources()
but not on device_terminate_all(). It could happen that HW is restarted and
expects BASE0 to be used, but the driver is not synchronized and will start
from BASE1. Therefore, it's better to reset the buffer explicitly in
m2p_hw_setup(). While here, check that HW really starts from BASE0 and
warn otherwise.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
 drivers/dma/ep93xx_dma.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index d37e8dda8079..a3d946d2a8e1 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -45,6 +45,7 @@
 
 #define M2P_PPALLOC			0x0008
 #define M2P_STATUS			0x000c
+#define M2P_STATUS_NEXTBUFFER		BIT(6)
 
 #define M2P_MAXCNT0			0x0020
 #define M2P_BASE0			0x0024
@@ -312,6 +313,13 @@ static void m2p_set_control(struct ep93xx_dma_chan *edmac, u32 control)
 	readl(edmac->regs + M2P_CONTROL);
 }
 
+static inline u32 m2p_channel_nextbuf(struct ep93xx_dma_chan *edmac)
+{
+	if (readl(edmac->regs + M2P_STATUS) & M2P_STATUS_NEXTBUFFER)
+		return 1;
+	return 0;
+}
+
 static int m2p_hw_setup(struct ep93xx_dma_chan *edmac)
 {
 	struct ep93xx_dma_data *data = edmac->chan.private;
@@ -323,6 +331,10 @@ static int m2p_hw_setup(struct ep93xx_dma_chan *edmac)
 		| M2P_CONTROL_ENABLE;
 	m2p_set_control(edmac, control);
 
+	if (m2p_channel_nextbuf(edmac) != 0)
+		dev_warn(chan2dev(edmac), "M2P: Starting from BASE1\n");
+	edmac->buffer = 0;
+
 	return 0;
 }
 
-- 
2.12.2




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]