summaryrefslogtreecommitdiff
path: root/include/linux/mmc
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2021-03-10 16:29:00 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2021-03-30 11:42:03 +0200
commit17a17bf50612e6048a9975450cf1bd30f93815b5 (patch)
tree4d754105cc170a9168d492ffd3db128e5f40522b /include/linux/mmc
parent18bbda900ffa7770b93daa1bc1ce3be39e643101 (diff)
mmc: core: Fix hanging on I/O during system suspend for removable cards
The mmc core uses a PM notifier to temporarily during system suspend, turn off the card detection mechanism for removal/insertion of (e)MMC/SD/SDIO cards. Additionally, the notifier may be used to remove an SDIO card entirely, if a corresponding SDIO functional driver don't have the system suspend/resume callbacks assigned. This behaviour has been around for a very long time. However, a recent bug report tells us there are problems with this approach. More precisely, when receiving the PM_SUSPEND_PREPARE notification, we may end up hanging on I/O to be completed, thus also preventing the system from getting suspended. In the end what happens, is that the cancel_delayed_work_sync() in mmc_pm_notify() ends up waiting for mmc_rescan() to complete - and since mmc_rescan() wants to claim the host, it needs to wait for the I/O to be completed first. Typically, this problem is triggered in Android, if there is ongoing I/O while the user decides to suspend, resume and then suspend the system again. This due to that after the resume, an mmc_rescan() work gets punted to the workqueue, which job is to verify that the card remains inserted after the system has resumed. To fix this problem, userspace needs to become frozen to suspend the I/O, prior to turning off the card detection mechanism. Therefore, let's drop the PM notifiers for mmc subsystem altogether and rely on the card detection to be turned off/on as a part of the system_freezable_wq, that we are already using. Moreover, to allow and SDIO card to be removed during system suspend, let's manage this from a ->prepare() callback, assigned at the mmc_host_class level. In this way, we can use the parent device (the mmc_host_class device), to remove the card device that is the child, in the device_prepare() phase. Reported-by: Kiwoong Kim <kwmad.kim@samsung.com> Cc: stable@vger.kernel.org # v4.5+ Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20210310152900.149380-1-ulf.hansson@linaro.org Reviewed-by: Kiwoong Kim <kwmad.kim@samsung.com>
Diffstat (limited to 'include/linux/mmc')
-rw-r--r--include/linux/mmc/host.h3
1 files changed, 0 insertions, 3 deletions
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index a001ad2f5f23..17d7b326af29 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -302,9 +302,6 @@ struct mmc_host {
u32 ocr_avail_sdio; /* SDIO-specific OCR */
u32 ocr_avail_sd; /* SD-specific OCR */
u32 ocr_avail_mmc; /* MMC-specific OCR */
-#ifdef CONFIG_PM_SLEEP
- struct notifier_block pm_notify;
-#endif
struct wakeup_source *ws; /* Enable consume of uevents */
u32 max_current_330;
u32 max_current_300;