mmc: mmc: Handle error case in mmc_suspend
Currently in case if suspend is failed due to some reason then the error case is not handled properly :- 1. w.r.t. suspend_clk_scaling claim_host counters are going bad. 2. In case of any error after halting and disabling cmdq - the error is returned to the PM framework and it assumes that card is not suspended, whereas CQ remains disabled. This causes I/O requests hangs since no request can be processed any further. Fix this by handling error cases properly. Change-Id: I8691eebcb0e2d089720505475aa0297efce5cca5 Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org> Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org> Signed-off-by: Siba Prasad <sibap@codeaurora.org>
This commit is contained in:
parent
d11fa99334
commit
16b7aeeeaa
1 changed files with 30 additions and 6 deletions
|
@ -2494,7 +2494,7 @@ static int mmc_test_awake_ext_csd(struct mmc_host *host)
|
|||
|
||||
static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
|
||||
{
|
||||
int err = 0;
|
||||
int err = 0, ret;
|
||||
|
||||
BUG_ON(!host);
|
||||
BUG_ON(!host->card);
|
||||
|
@ -2503,6 +2503,8 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
|
|||
if (err) {
|
||||
pr_err("%s: %s: fail to suspend clock scaling (%d)\n",
|
||||
mmc_hostname(host), __func__, err);
|
||||
if (host->card->cmdq_init)
|
||||
wake_up(&host->cmdq_ctx.wait);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -2527,12 +2529,12 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
|
|||
if (mmc_card_doing_bkops(host->card)) {
|
||||
err = mmc_stop_bkops(host->card);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
err = mmc_flush_cache(host->card);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_err;
|
||||
|
||||
if (mmc_can_sleepawake(host)) {
|
||||
/*
|
||||
|
@ -2549,16 +2551,38 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
|
|||
err = mmc_deselect_cards(host);
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
mmc_power_off(host);
|
||||
mmc_card_set_suspended(host->card);
|
||||
if (err)
|
||||
goto out_err;
|
||||
mmc_power_off(host);
|
||||
mmc_card_set_suspended(host->card);
|
||||
|
||||
goto out;
|
||||
|
||||
out_err:
|
||||
/*
|
||||
* In case of err let's put controller back in cmdq mode and unhalt
|
||||
* the controller.
|
||||
* We expect cmdq_enable and unhalt won't return any error
|
||||
* since it is anyway enabling few registers.
|
||||
*/
|
||||
if (host->card->cmdq_init) {
|
||||
mmc_host_clk_hold(host);
|
||||
ret = host->cmdq_ops->enable(host);
|
||||
if (ret)
|
||||
pr_err("%s: %s: enabling CMDQ mode failed (%d)\n",
|
||||
mmc_hostname(host), __func__, ret);
|
||||
mmc_host_clk_release(host);
|
||||
mmc_cmdq_halt(host, false);
|
||||
}
|
||||
|
||||
out:
|
||||
/* Kick CMDQ thread to process any requests came in while suspending */
|
||||
if (host->card->cmdq_init)
|
||||
wake_up(&host->cmdq_ctx.wait);
|
||||
|
||||
mmc_release_host(host);
|
||||
if (err)
|
||||
mmc_resume_clk_scaling(host);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue