mmc: block: Fix issue with deferred resume when CQ is enabled

In CQ mode, the legacy commands will be sent after CQ is put in
halt state. But when deferred resume is enabled, the resume
happens in mmc_wait_for_req(), which will enable CQ again
overiding the caller's state. This causes legacy commands to fail.

Fix this by moving the deferred resume from all the places to
mmc_rpm_hold() which is always the first step done in both
CQ/legacy commands and thus avoids the above issue scneario.

Fix: fbb7cbf8ea (mmc: core: Add deferred resume for command queue mode)
Change-Id: I97fb9d654968b294dc1fb6986b8b9431e22233c0
Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
This commit is contained in:
Veerabhadrarao Badiganti 2016-12-05 11:50:33 +05:30 committed by Gerrit - the friendly Code Review server
parent 20ff85dc2b
commit dbceeaf8ea
2 changed files with 13 additions and 13 deletions

View File

@ -3643,10 +3643,7 @@ static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
mmc_rpm_hold(card->host, &card->dev);
mmc_claim_host(card->host);
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
if (mmc_bus_needs_resume(card->host))
mmc_resume_bus(card->host);
#endif
ret = mmc_blk_cmdq_part_switch(card, md);
if (ret) {
pr_err("%s: %s: partition switch failed %d\n",
@ -3710,10 +3707,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
mmc_rpm_hold(host, &card->dev);
/* claim host only for the first request */
mmc_claim_host(card->host);
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
if (mmc_bus_needs_resume(card->host))
mmc_resume_bus(card->host);
#endif
if (mmc_card_get_bkops_en_manual(card))
mmc_stop_bkops(card);
}

View File

@ -1205,10 +1205,6 @@ EXPORT_SYMBOL(mmc_start_req);
*/
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
if (mmc_bus_needs_resume(host))
mmc_resume_bus(host);
#endif
__mmc_start_req(host, mrq);
mmc_wait_for_req_done(host, mrq);
}
@ -2369,8 +2365,12 @@ int mmc_resume_bus(struct mmc_host *host)
unsigned long flags;
int err = 0;
if (!mmc_bus_needs_resume(host))
mmc_claim_host(host);
if (!mmc_bus_needs_resume(host)) {
mmc_release_host(host);
return -EINVAL;
}
spin_lock_irqsave(&host->lock, flags);
host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
@ -2394,6 +2394,8 @@ int mmc_resume_bus(struct mmc_host *host)
}
mmc_bus_put(host);
mmc_release_host(host);
return 0;
}
@ -4346,6 +4348,11 @@ void mmc_rpm_hold(struct mmc_host *host, struct device *dev)
if (pm_runtime_suspended(dev))
BUG_ON(1);
}
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
if (mmc_bus_needs_resume(host))
mmc_resume_bus(host);
#endif
}
EXPORT_SYMBOL(mmc_rpm_hold);