[PATCH v2 4/4] mmc: dw_mmc: reset FIFO after an error

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

 



If an error occurs mid way through a transaction (such as a missing CRC
status response after the 2nd block written out of 3), then the FIFO may
still contain data which will interfere with the next transaction.
Therefore after an error has been detected, reset the fifo using the
CTRL register.

Signed-off-by: James Hogan <james.hogan@xxxxxxxxxx>
Acked-by: Will Newton <will.newton@xxxxxxxxxx>
Tested-by: Jaehoon Chung <jh80.chung@xxxxxxxxxxx>
---
 drivers/mmc/host/dw_mmc.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0dac397..0c839d3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -849,7 +849,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
 	struct mmc_command *cmd;
 	enum dw_mci_state state;
 	enum dw_mci_state prev_state;
-	u32 status;
+	u32 status, ctrl;
 
 	spin_lock(&host->lock);
 
@@ -929,6 +929,16 @@ static void dw_mci_tasklet_func(unsigned long priv)
 						status);
 					data->error = -EIO;
 				}
+				/*
+				 * After an error, there may be data lingering
+				 * in the FIFO, so reset it - doing so
+				 * generates a block interrupt, hence setting
+				 * the scatter-gather pointer to NULL.
+				 */
+				host->sg = NULL;
+				ctrl = mci_readl(host, CTRL);
+				ctrl |= SDMMC_CTRL_FIFO_RESET;
+				mci_writel(host, CTRL, ctrl);
 			} else {
 				data->bytes_xfered = data->blocks * data->blksz;
 				data->error = 0;
-- 
1.7.2.3


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux