diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 93b0b596dd20..087e9ea1fda0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -490,13 +490,30 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) ext_csd[EXT_CSD_PWR_CL_DDR_200_360]; } + /* check whether the eMMC card supports HPI */ + if ((ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) && + !(card->quirks & MMC_QUIRK_BROKEN_HPI)) { + card->ext_csd.hpi = 1; + if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2) + card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION; + else + card->ext_csd.hpi_cmd = MMC_SEND_STATUS; + /* + * Indicate the maximum timeout to close + * a command interrupted by HPI + */ + card->ext_csd.out_of_int_time = + ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10; + } + if (card->ext_csd.rev >= 5) { /* Adjust production date as per JEDEC JESD84-B451 */ if (card->cid.year < 2010) card->cid.year += 16; /* check whether the eMMC card supports BKOPS */ - if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { + if ((ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) && + card->ext_csd.hpi) { card->ext_csd.bkops = 1; card->ext_csd.man_bkops_en = (ext_csd[EXT_CSD_BKOPS_EN] & @@ -1788,8 +1805,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* * If cache size is higher than 0, this indicates * the existence of cache and it can be turned on. + * If HPI is not supported then cache shouldn't be enabled. */ - if (card->ext_csd.cache_size > 0) { + if (card->ext_csd.cache_size > 0 && card->ext_csd.hpi_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CACHE_CTRL, 1, card->ext_csd.generic_cmd6_time); diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 91248c14af01..6384bf34660f 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -767,7 +767,7 @@ int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) unsigned int opcode; int err; - if (!card->ext_csd.hpi) { + if (!card->ext_csd.hpi_en) { pr_warn("%s: Card didn't support HPI command\n", mmc_hostname(card->host)); return -EINVAL; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index a9c756549c2f..a16fd1739371 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -306,6 +306,8 @@ struct mmc_card { #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ /* byte mode */ #define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<13) /* For incorrect data timeout */ +#define MMC_QUIRK_BROKEN_HPI (1 << 14) /* For devices which gets */ + /* broken due to HPI feature */ unsigned int erase_size; /* erase size in sectors */