aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2014-01-10 08:51:42 -0500
committerChris Ball <chris@printf.net>2014-02-23 10:41:17 -0500
commite7f3d22289e4307b3071cc18b1d8ecc6598c0be4 (patch)
tree686b60dc3e1695d3e2a53308bd8dd5b9e8d35c41 /drivers/mmc
parentbb5cba40dc7f079ea7ee3ae760b7c388b6eb5fc3 (diff)
mmc: mmci: Handle CMD irq before DATA irq
In case of a read operation both MCI_CMDRESPEND and MCI_DATAEND can be set in the status register when entering the interrupt handler. This is due to that the card start sending data before the host has acknowledged the command response. To resolve the issue for this scenario, we must start by handling the CMD irq instead of the DATA irq. The reason is beacuse the completion of the DATA irq will not respect the current command and then causing it to be garbled. Cc: Russell King <linux@arm.linux.org.uk> Cc: Johan Rudholm <jrudholm@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mmci.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index b93122636531..8324e3ec21c2 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1144,16 +1144,17 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
1144 1144
1145 dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 1145 dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
1146 1146
1147 cmd = host->cmd;
1148 if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|
1149 MCI_CMDRESPEND) && cmd)
1150 mmci_cmd_irq(host, cmd, status);
1151
1147 data = host->data; 1152 data = host->data;
1148 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| 1153 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR|
1149 MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| 1154 MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND|
1150 MCI_DATABLOCKEND) && data) 1155 MCI_DATABLOCKEND) && data)
1151 mmci_data_irq(host, data, status); 1156 mmci_data_irq(host, data, status);
1152 1157
1153 cmd = host->cmd;
1154 if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd)
1155 mmci_cmd_irq(host, cmd, status);
1156
1157 ret = 1; 1158 ret = 1;
1158 } while (status); 1159 } while (status);
1159 1160