summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaya Erez <merez@codeaurora.org>2015-09-24 14:17:08 +0300
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-31 15:27:29 -0700
commit96deb87c8ca7975fb0ed73e9dbfbe013fd36e2fc (patch)
treecdf10b3d8b00371afe50f94d245497b0e9fcdf2f
parent8a67fa5b178a680ae401dcc62164a89d06d12b02 (diff)
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>
-rw-r--r--drivers/mmc/core/core.c5
-rw-r--r--drivers/mmc/core/mmc.c8
2 files changed, 8 insertions, 5 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index a1b92cdbe83d..8e24ddfb51db 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1259,7 +1259,8 @@ EXPORT_SYMBOL(mmc_check_bkops);
* mmc_start_manual_bkops - start BKOPS for supported cards
* @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)
{
@@ -1273,7 +1274,6 @@ void mmc_start_manual_bkops(struct mmc_card *card)
if (mmc_card_doing_bkops(card))
return;
- mmc_claim_host(card->host);
mmc_retune_hold(card->host);
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_release_host(card->host);
}
EXPORT_SYMBOL(mmc_start_manual_bkops);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 4eac93303776..3a23cf434159 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -2587,6 +2587,9 @@ static int mmc_runtime_idle(struct mmc_host *host)
bool halt_cmdq;
BUG_ON(!host->card);
+
+ mmc_claim_host(host);
+
halt_cmdq = mmc_card_cmdq(host->card) &&
(host->card->bkops.needs_check ||
host->card->bkops.needs_manual);
@@ -2611,10 +2614,9 @@ static int mmc_runtime_idle(struct mmc_host *host)
host->card->bkops.needs_check = false;
if (host->card->bkops.needs_check) {
- mmc_claim_host(host);
mmc_check_bkops(host->card);
host->card->bkops.needs_check = false;
- mmc_release_host(host);
+
}
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",
mmc_hostname(host), __func__, err);
}
+
out:
/*
* TODO: consider prolonging suspend when bkops
@@ -2634,6 +2637,7 @@ out:
* */
pm_schedule_suspend(&host->card->dev, MMC_AUTOSUSPEND_DELAY_MS);
no_suspend:
+ mmc_release_host(host);
pm_runtime_mark_last_busy(&host->card->dev);
/* return negative value in order to avoid autosuspend */
return (err) ? err : NO_AUTOSUSPEND;