mmc: core: claim host before halt in pm runtime idle

There can be a race condition between runtime idle and incoming
requests. In such a race condition, we can send requests
while the queue is halted.
Claiming the host at the beginning of runtime idle will prevent
such a case.

Change-Id: I8e55f0798543b2de44b37da13f7770889e6fbe5f
Signed-off-by: Maya Erez <merez@codeaurora.org>
[subhashj@codeaurora.org: fixed merge conflicts]
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
Maya Erez 2015-09-24 14:17:08 +03:00 committed by Subhash Jadavani
parent 8a67fa5b17
commit 96deb87c8c
2 changed files with 8 additions and 5 deletions

View file

@ -1260,6 +1260,7 @@ EXPORT_SYMBOL(mmc_check_bkops);
* @card: MMC card to start BKOPS * @card: MMC card to start BKOPS
* *
* Send START_BKOPS to the card. * Send START_BKOPS to the card.
* The function should be called with claimed host.
*/ */
void mmc_start_manual_bkops(struct mmc_card *card) void mmc_start_manual_bkops(struct mmc_card *card)
{ {
@ -1273,7 +1274,6 @@ void mmc_start_manual_bkops(struct mmc_card *card)
if (mmc_card_doing_bkops(card)) if (mmc_card_doing_bkops(card))
return; return;
mmc_claim_host(card->host);
mmc_retune_hold(card->host); mmc_retune_hold(card->host);
err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_START, err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_START,
@ -1288,7 +1288,6 @@ void mmc_start_manual_bkops(struct mmc_card *card)
} }
mmc_retune_release(card->host); mmc_retune_release(card->host);
mmc_release_host(card->host);
} }
EXPORT_SYMBOL(mmc_start_manual_bkops); EXPORT_SYMBOL(mmc_start_manual_bkops);

View file

@ -2587,6 +2587,9 @@ static int mmc_runtime_idle(struct mmc_host *host)
bool halt_cmdq; bool halt_cmdq;
BUG_ON(!host->card); BUG_ON(!host->card);
mmc_claim_host(host);
halt_cmdq = mmc_card_cmdq(host->card) && halt_cmdq = mmc_card_cmdq(host->card) &&
(host->card->bkops.needs_check || (host->card->bkops.needs_check ||
host->card->bkops.needs_manual); host->card->bkops.needs_manual);
@ -2611,10 +2614,9 @@ static int mmc_runtime_idle(struct mmc_host *host)
host->card->bkops.needs_check = false; host->card->bkops.needs_check = false;
if (host->card->bkops.needs_check) { if (host->card->bkops.needs_check) {
mmc_claim_host(host);
mmc_check_bkops(host->card); mmc_check_bkops(host->card);
host->card->bkops.needs_check = false; host->card->bkops.needs_check = false;
mmc_release_host(host);
} }
if (host->card->bkops.needs_manual) if (host->card->bkops.needs_manual)
@ -2626,6 +2628,7 @@ static int mmc_runtime_idle(struct mmc_host *host)
pr_err("%s: %s failed to unhalt cmdq (%d)\n", pr_err("%s: %s failed to unhalt cmdq (%d)\n",
mmc_hostname(host), __func__, err); mmc_hostname(host), __func__, err);
} }
out: out:
/* /*
* TODO: consider prolonging suspend when bkops * TODO: consider prolonging suspend when bkops
@ -2634,6 +2637,7 @@ out:
* */ * */
pm_schedule_suspend(&host->card->dev, MMC_AUTOSUSPEND_DELAY_MS); pm_schedule_suspend(&host->card->dev, MMC_AUTOSUSPEND_DELAY_MS);
no_suspend: no_suspend:
mmc_release_host(host);
pm_runtime_mark_last_busy(&host->card->dev); pm_runtime_mark_last_busy(&host->card->dev);
/* return negative value in order to avoid autosuspend */ /* return negative value in order to avoid autosuspend */
return (err) ? err : NO_AUTOSUSPEND; return (err) ? err : NO_AUTOSUSPEND;