summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorVeerabhadrarao Badiganti <vbadigan@codeaurora.org>2017-08-07 14:58:15 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-08-29 23:27:37 -0700
commit28f9652f80e6000f5dbc341287aa9db935825271 (patch)
treef003bdd84c24da5e91767a80772b90846a16cad6 /drivers
parent0d617edc010f86e7df529fe2b30b1b12ffdcee58 (diff)
mmc: core: Ignore bus resume flags when card removal event is detected
Ignore bus resume flags in the resume path if there is an outstanding card removal event. With deferred resume feature enabled, we don't check for card presence (i.e., mmc_detect_change) in the resume path. This is to improve the resume latency. If at all card is removed during suspend state, in some cases we may not detect the card removal immediately but only when a request was issued to it. In some scenarios, card removal in suspend state leading to card suspend to fail (since the card is removed) and which is causing system suspend to fail. And we don't try to resume card because of deferred resume it leading to system suspend to fail continuously. To fix this scenario, ignore the bus resume flag in the resume path only if there an outstanding card removal event. By doing so, we are ensuring that the driver would check for card presence (mmc_detect_change) in the resume path (mmc_pm_notify) and it will mark the card as removed if it finds the card is no more present. Change-Id: I7d075c2a5c2aaba1ff92f4072fdd2541bb98aa95 Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/core/core.c12
-rw-r--r--drivers/mmc/core/sd.c5
2 files changed, 15 insertions, 2 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0da9c5caea13..34a5f81fc5fc 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -3301,6 +3301,13 @@ static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
pm_wakeup_event(mmc_dev(host), 5000);
host->detect_change = 1;
+ /*
+ * Change in cd_gpio state, so make sure detection part is
+ * not overided because of manual resume.
+ */
+ if (cd_irq && mmc_bus_manual_resume(host))
+ host->ignore_bus_resume_flags = true;
+
mmc_schedule_delayed_work(&host->detect, delay);
}
@@ -4199,6 +4206,8 @@ void mmc_rescan(struct work_struct *work)
host->bus_ops->detect(host);
host->detect_change = 0;
+ if (host->ignore_bus_resume_flags)
+ host->ignore_bus_resume_flags = false;
/*
* Let mmc_bus_put() free the bus/bus_ops if we've found that
@@ -4456,7 +4465,8 @@ int mmc_pm_notify(struct notifier_block *notify_block,
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 0;
- if (mmc_bus_manual_resume(host)) {
+ if (mmc_bus_manual_resume(host) &&
+ !host->ignore_bus_resume_flags) {
spin_unlock_irqrestore(&host->lock, flags);
break;
}
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 5033107f6e26..48709ecc9ff1 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1237,7 +1237,10 @@ static int mmc_sd_suspend(struct mmc_host *host)
if (!err) {
pm_runtime_disable(&host->card->dev);
pm_runtime_set_suspended(&host->card->dev);
- }
+ /* if suspend fails, force mmc_detect_change during resume */
+ } else if (mmc_bus_manual_resume(host))
+ host->ignore_bus_resume_flags = true;
+
MMC_TRACE(host, "%s: Exit err: %d\n", __func__, err);
return err;