diff options
| author | Sahitya Tummala <stummala@codeaurora.org> | 2015-02-05 12:34:52 +0530 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2016-09-28 15:14:50 +0200 |
| commit | 03356ea7b3d1e8be99e894f271a15d17076a2053 (patch) | |
| tree | 083723322bb285bff66404abe796e91a0b65ad95 | |
| parent | 1d0dc70511de207883ce0252801a77b796ec196f (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.c | 9 |
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, |
