> 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@xxxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx> Reviewed-by: Kiwoong Kim <kwmad.kim@xxxxxxxxxxx> Thanks. Kiwoong Kim