summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/sdhci.c20
-rw-r--r--drivers/mmc/host/sdhci.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b0a320004e0d..320c294b9d73 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);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 13e0bd6cff5d..7301c90f8500 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -463,6 +463,7 @@ struct sdhci_host {
bool runtime_suspended; /* Host is runtime suspended */
bool bus_on; /* Bus power prevents runtime suspend */
bool preset_enabled; /* Preset is enabled */
+ bool pending_reset; /* Cmd/data reset is pending */
struct mmc_request *mrq; /* Current request */
struct mmc_command *cmd; /* Current command */