aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSahitya Tummala <stummala@codeaurora.org>2015-02-05 12:34:52 +0530
committerMoyster <oysterized@gmail.com>2016-09-28 15:14:50 +0200
commit03356ea7b3d1e8be99e894f271a15d17076a2053 (patch)
tree083723322bb285bff66404abe796e91a0b65ad95
parent1d0dc70511de207883ce0252801a77b796ec196f (diff)
mmc: core: fix race between mmc_power_off and mmc_power_up
In case card detect IRQ is triggered before mmc_add_host(), then there could be a potential race between mmc_power_off() which gets called from mmc_rescan() of card detect IRQ handler and mmc_start_host() which gets called from mmc_add_host(). This may turn off the clocks while mmc_start_host() is still running and thus may result in an un-clocked register access. Change-Id: I522df75ba0ad23f065127e015ad825075be94596 Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Signed-off-by: franciscofranco <franciscofranco.1990@gmail.com> Signed-off-by: W4TCH0UT <ateekujjawal@gmail.com>
-rw-r--r--drivers/mmc/core/core.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index b02f17ddc..fad74b3b2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2853,12 +2853,14 @@ void mmc_rescan(struct work_struct *work)
void mmc_start_host(struct mmc_host *host)
{
+ mmc_claim_host(host);
host->f_init = max(freqs[0], host->f_min);
host->rescan_disable = 0;
if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
mmc_power_off(host);
else
mmc_power_up(host);
+ mmc_release_host(host);
mmc_detect_change(host, 0);
}
@@ -3113,8 +3115,11 @@ int mmc_suspend_host(struct mmc_host *host)
}
mmc_bus_put(host);
- if (!err && !mmc_card_keep_power(host))
+ if (!err && !mmc_card_keep_power(host)) {
+ mmc_claim_host(host);
mmc_power_off(host);
+ mmc_release_host(host);
+ }
out:
return err;
@@ -3139,7 +3144,9 @@ int mmc_resume_host(struct mmc_host *host)
if (host->bus_ops && !host->bus_dead) {
if (!mmc_card_keep_power(host)) {
+ mmc_claim_host(host);
mmc_power_up(host);
+ mmc_release_host(host);
mmc_select_voltage(host, host->ocr);
/*
* Tell runtime PM core we just powered up the card,