summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorTalel Shenhar <tatias@codeaurora.org>2015-02-05 14:44:15 +0200
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-31 15:26:10 -0700
commita89dfb1bbd09b7625eca50ce02448a517c7156c6 (patch)
tree5246b031e95233b17471f8856e2a094981c52b89 /drivers/mmc
parentd3254ba7a0f2956dd9da87d575ad83a8b9914b15 (diff)
mmc: quirks: add new quirk that allows HPI disable
Certain cards might get broken when HPI feature is used. This patch allows host to avoid using HPI for such buggy cards by adding new quirk. As some of the other features like BKOPs/Cache are dependent on HPI feature, those features would also get disabled if HPI is disabled. Change-Id: I93a8810e4031eafcd44b5152296e065dc3330b63 Signed-off-by: Talel Shenhar <tatias@codeaurora.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/mmc.c22
-rw-r--r--drivers/mmc/core/mmc_ops.c2
2 files changed, 21 insertions, 3 deletions
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;