diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2017-03-04 10:12:54 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-03-04 10:12:54 -0800 |
| commit | d2499ee89d291515865fe8738b6be0c39693e53a (patch) | |
| tree | b6be609025cd3ffc45e588448b228aabbb1187cf | |
| parent | 77610431cb72f691f94fdb4dd3cfcd83505ee77f (diff) | |
| parent | e9cc73402e87bfa62f503c7f319094f6cbdfe469 (diff) | |
Merge "mmc: core: Retry claim host in mmc_sd_detect"
| -rw-r--r-- | drivers/mmc/core/core.c | 32 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.c | 12 | ||||
| -rw-r--r-- | include/linux/mmc/core.h | 1 |
3 files changed, 44 insertions, 1 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f79e8377a2ee..5396e1d00178 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2114,6 +2114,38 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) EXPORT_SYMBOL(__mmc_claim_host); /** + * mmc_try_claim_host - try exclusively to claim a host + * and keep trying for given time, with a gap of 10ms + * @host: mmc host to claim + * @dealy_ms: delay in ms + * + * Returns %1 if the host is claimed, %0 otherwise. + */ +int mmc_try_claim_host(struct mmc_host *host, unsigned int delay_ms) +{ + int claimed_host = 0; + unsigned long flags; + int retry_cnt = delay_ms/10; + + do { + spin_lock_irqsave(&host->lock, flags); + if (!host->claimed || host->claimer == current) { + host->claimed = 1; + host->claimer = current; + host->claim_cnt += 1; + claimed_host = 1; + } + spin_unlock_irqrestore(&host->lock, flags); + if (!claimed_host) + mmc_delay(10); + } while (!claimed_host && retry_cnt--); + if (host->ops->enable && claimed_host && host->claim_cnt == 1) + host->ops->enable(host); + return claimed_host; +} +EXPORT_SYMBOL(mmc_try_claim_host); + +/** * mmc_release_host - release a host * @host: mmc host to release * diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 7e7d7eb4da2a..ec5ce79e84e7 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1147,7 +1147,17 @@ static void mmc_sd_detect(struct mmc_host *host) BUG_ON(!host); BUG_ON(!host->card); - mmc_get_card(host->card); + /* + * Try to acquire claim host. If failed to get the lock in 2 sec, + * just return; This is to ensure that when this call is invoked + * due to pm_suspend, not to block suspend for longer duration. + */ + pm_runtime_get_sync(&host->card->dev); + if (!mmc_try_claim_host(host, 2000)) { + pm_runtime_mark_last_busy(&host->card->dev); + pm_runtime_put_autosuspend(&host->card->dev); + return; + } /* * Just check if our card has been removed. diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 55a30d685226..1068953943d8 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -203,6 +203,7 @@ extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); extern void mmc_release_host(struct mmc_host *host); +extern int mmc_try_claim_host(struct mmc_host *host, unsigned int delay); extern void mmc_get_card(struct mmc_card *card); extern void mmc_put_card(struct mmc_card *card); |
