summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b0a3200..320c294 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -935,6 +935,9 @@ static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq)
static void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq)
{
+ if (sdhci_needs_reset(host, mrq))
+ host->pending_reset = true;
+
tasklet_schedule(&host->finish_tasklet);
}
@@ -2232,6 +2235,8 @@ static void sdhci_tasklet_finish(unsigned long param)
controllers do not like that. */
sdhci_do_reset(host, SDHCI_RESET_CMD);
sdhci_do_reset(host, SDHCI_RESET_DATA);
+
+ host->pending_reset = false;
}
host->mrq = NULL;
@@ -2287,6 +2292,13 @@ static void sdhci_timeout_timer(unsigned long data)
static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *mask)
{
if (!host->cmd) {
+ /*
+ * SDHCI recovers from errors by resetting the cmd and data
+ * circuits. Until that is done, there very well might be more
+ * interrupts, so ignore them in that case.
+ */
+ if (host->pending_reset)
+ return;
pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n",
mmc_hostname(host->mmc), (unsigned)intmask);
sdhci_dumpregs(host);
@@ -2409,6 +2421,14 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
}
}
+ /*
+ * SDHCI recovers from errors by resetting the cmd and data
+ * circuits. Until that is done, there very well might be more
+ * interrupts, so ignore them in that case.
+ */
+ if (host->pending_reset)
+ return;
+
pr_err("%s: Got data interrupt 0x%08x even though no data operation was in progress.\n",
mmc_hostname(host->mmc), (unsigned)intmask);
sdhci_dumpregs(host);
OpenPOWER on IntegriCloud