diff options
| author | Sahitya Tummala <stummala@codeaurora.org> | 2014-04-18 13:00:20 +0530 |
|---|---|---|
| committer | Subhash Jadavani <subhashj@codeaurora.org> | 2016-05-31 15:27:44 -0700 |
| commit | 71728d8db1686f38faaef0f07326d2aaff753a01 (patch) | |
| tree | bb7501b341bb070a018d33e3c77436250e1793e2 | |
| parent | e3a22cb14423fa5189393214e55ad50db03b7710 (diff) | |
mmc: core: fix issue with sleep cmd that follows an RPMB access
If the last access to eMMC before runtime/system suspend is an
RPMB access, the partition type within EXT_CSD[179] will be set
to RPMB. As per specification, the deselect CMD7 and sleep CMD5
are ignored by the card and are treated as illegal commands in
this state. This causes eMMC sleep command to timeout and thus
fails runtime/system suspend. Hence, switch to default partition
config before sending deselect CMD7 and sleep CMD5.
CRs-fixed: 630894
Change-Id: I40f3fb590aeba787de8ca3356a8eed5f2780bcc1
Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
[subhashj@codeaurora.org: fixed merge conflicts]
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
| -rw-r--r-- | drivers/mmc/core/mmc.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 65b2581e3195..e9827c52e283 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -2195,9 +2195,39 @@ static int mmc_sleepawake(struct mmc_host *host, bool sleep) { struct mmc_command cmd = {0}; struct mmc_card *card = host->card; - unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); + unsigned int timeout_ms; int err; + if (!card) { + pr_err("%s: %s: invalid card\n", mmc_hostname(host), __func__); + return -EINVAL; + } + + timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); + if (card->ext_csd.rev >= 3 && + card->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB) { + u8 part_config = card->ext_csd.part_config; + + /* + * If the last access before suspend is RPMB access, then + * switch to default part config so that sleep command CMD5 + * and deselect CMD7 can be sent to the card. + */ + part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_PART_CONFIG, + part_config, + card->ext_csd.part_time); + if (err) { + pr_err("%s: %s: failed to switch to default part config %x\n", + mmc_hostname(host), __func__, part_config); + return err; + } + card->ext_csd.part_config = part_config; + card->part_curr = card->ext_csd.part_config & + EXT_CSD_PART_CONFIG_ACC_MASK; + } + /* Re-tuning can't be done once the card is deselected */ mmc_retune_hold(host); |
