msm: core: eMMC v4.5 BKOPS fixes
This change fixes the following issues in eMMC v4.5 BKOPS (back
ground operations)
1. For HPI (high priority interrupt) sent using CMD12,
configure R1B response flag, as defined by spec
2. Mark BKOPS shadow flag (doing_bkops) only for non-urgent BKOPS levels,
otherwise is not needed this because BKOPS already completed
synchronously (with R1B)
3. Send HPI before sleep (CMD5), when BKOPS is in progress
Change-Id: I575fe0946d04c91f1de71804409c60c7acb6d46a
Signed-off-by: Konstantin Dorfman <kdorfman@codeaurora.org>
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 91c37e5..6c82c74 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -269,9 +269,16 @@
spin_lock_irqsave(&card->host->lock, flags);
mmc_card_clr_need_bkops(card);
- mmc_card_set_doing_bkops(card);
+
+ /*
+ * For urgent bkops status (LEVEL_2 and more)
+ * bkops executed synchronously, otherwise
+ * the operation is in progress
+ */
if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2)
mmc_card_set_check_bkops(card);
+ else
+ mmc_card_set_doing_bkops(card);
spin_unlock_irqrestore(&card->host->lock, flags);
out:
@@ -2537,8 +2544,12 @@
err = -EBUSY;
if (!err) {
- if (host->bus_ops->suspend)
+ if (host->bus_ops->suspend) {
+ if (mmc_card_doing_bkops(host->card))
+ mmc_interrupt_bkops(host->card);
+
err = host->bus_ops->suspend(host);
+ }
if (!(host->card && mmc_card_sdio(host->card)))
mmc_do_release_host(host);
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0d3c77b..cf9aea5 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -565,14 +565,14 @@
{
struct mmc_command cmd = {0};
unsigned int opcode;
- unsigned int flags;
+ unsigned int flags = MMC_CMD_AC;
int err;
opcode = card->ext_csd.hpi_cmd;
if (opcode == MMC_STOP_TRANSMISSION)
- flags = MMC_RSP_R1 | MMC_CMD_AC;
+ flags |= MMC_RSP_R1B;
else if (opcode == MMC_SEND_STATUS)
- flags = MMC_RSP_R1 | MMC_CMD_AC;
+ flags |= MMC_RSP_R1;
cmd.opcode = opcode;
cmd.arg = card->rca << 16 | 1;