aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2011-06-29 04:30:47 -0400
committerChris Ball <cjb@laptop.org>2011-07-20 17:21:06 -0400
commit94dd5b3371c989b32685a00a54cba7bb530f864d (patch)
treef25015abe7cc532eab00d48e8292d437903e7927 /drivers/mmc
parent55c5efbc0dbcb20b7f0d264d172ab376494d79a1 (diff)
mmc: dw_mmc: reset FIFO after an error
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@imgtec.com> Acked-by: Will Newton <will.newton@imgtec.com> Tested-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/dw_mmc.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0dac397f37fd..0c839d3338db 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)
849 struct mmc_command *cmd; 849 struct mmc_command *cmd;
850 enum dw_mci_state state; 850 enum dw_mci_state state;
851 enum dw_mci_state prev_state; 851 enum dw_mci_state prev_state;
852 u32 status; 852 u32 status, ctrl;
853 853
854 spin_lock(&host->lock); 854 spin_lock(&host->lock);
855 855
@@ -929,6 +929,16 @@ static void dw_mci_tasklet_func(unsigned long priv)
929 status); 929 status);
930 data->error = -EIO; 930 data->error = -EIO;
931 } 931 }
932 /*
933 * After an error, there may be data lingering
934 * in the FIFO, so reset it - doing so
935 * generates a block interrupt, hence setting
936 * the scatter-gather pointer to NULL.
937 */
938 host->sg = NULL;
939 ctrl = mci_readl(host, CTRL);
940 ctrl |= SDMMC_CTRL_FIFO_RESET;
941 mci_writel(host, CTRL, ctrl);
932 } else { 942 } else {
933 data->bytes_xfered = data->blocks * data->blksz; 943 data->bytes_xfered = data->blocks * data->blksz;
934 data->error = 0; 944 data->error = 0;