aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2019-09-04 10:46:24 -0600
committerUlf Hansson <ulf.hansson@linaro.org>2019-11-13 16:10:16 +0100
commitdcaac3f7840177ec9894abbd4a0fabf31801ecb6 (patch)
tree7d60af4796a575b6e5be0f7827049c7843abe60b /drivers/mmc/host
parentLinux 5.4-rc7 (diff)
downloadlinux-dev-dcaac3f7840177ec9894abbd4a0fabf31801ecb6.tar.xz
linux-dev-dcaac3f7840177ec9894abbd4a0fabf31801ecb6.zip
mmc: sdhci: Check card status after reset
In sdhci_do_reset we call the reset callback which is typically sdhci_reset. sdhci_reset can wait for up to 100ms waiting for the controller to reset. If SDHCI_RESET_ALL was passed as the flag, the controller will clear the IRQ mask. If during that 100ms the card is removed there is no notification to the MMC system that the card was removed. So from the drivers point of view the card is always present. By making sdhci_reinit compare the present state it can schedule a rescan if the card was removed while a reset was in progress. Signed-off-by: Raul E Rangel <rrangel@chromium.org> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/sdhci.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b056400e34b1..09cdbe86d9f9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -337,8 +337,19 @@ static void sdhci_init(struct sdhci_host *host, int soft)
static void sdhci_reinit(struct sdhci_host *host)
{
+ u32 cd = host->ier & (SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
+
sdhci_init(host, 0);
sdhci_enable_card_detection(host);
+
+ /*
+ * A change to the card detect bits indicates a change in present state,
+ * refer sdhci_set_card_detection(). A card detect interrupt might have
+ * been missed while the host controller was being reset, so trigger a
+ * rescan to check.
+ */
+ if (cd != (host->ier & (SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT)))
+ mmc_detect_change(host->mmc, msecs_to_jiffies(200));
}
static void __sdhci_led_activate(struct sdhci_host *host)