Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Raul E Rangel and committed by
Ulf Hansson
dcaac3f7 31f4f5b4

+11
+11
drivers/mmc/host/sdhci.c
··· 337 337 338 338 static void sdhci_reinit(struct sdhci_host *host) 339 339 { 340 + u32 cd = host->ier & (SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT); 341 + 340 342 sdhci_init(host, 0); 341 343 sdhci_enable_card_detection(host); 344 + 345 + /* 346 + * A change to the card detect bits indicates a change in present state, 347 + * refer sdhci_set_card_detection(). A card detect interrupt might have 348 + * been missed while the host controller was being reset, so trigger a 349 + * rescan to check. 350 + */ 351 + if (cd != (host->ier & (SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT))) 352 + mmc_detect_change(host->mmc, msecs_to_jiffies(200)); 342 353 } 343 354 344 355 static void __sdhci_led_activate(struct sdhci_host *host)