diff options
Diffstat (limited to 'drivers')
-rwxr-xr-x | drivers/mmc/core/mmc.c | 19 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 6 |
2 files changed, 23 insertions, 2 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 9af23fe2ae8f..e450fbc66559 100755 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -58,6 +58,16 @@ static const unsigned int tacc_mant[] = { __res & __mask; \ }) +static const struct mmc_fixup mmc_fixups[] = { + /* + * Certain Hynix eMMC 4.41 cards might get broken when HPI feature + * is used so disable the HPI feature for such buggy cards. + */ + MMC_FIXUP(CID_NAME_ANY, CID_MANFID_HYNIX, 0x014a, add_quirk, + MMC_QUIRK_BROKEN_HPI), + END_FIXUP +}; + /* * Given the decoded CSD structure, decode the raw CID to our CID structure. */ @@ -271,6 +281,9 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) */ card->ext_csd.rev = ext_csd[EXT_CSD_REV]; + /* fixup device after ext_csd revision field is updated */ + mmc_fixup_device(card, mmc_fixups); + card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; @@ -414,7 +427,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) if (card->ext_csd.rev >= 5) { card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; /* check whether the eMMC card supports HPI */ - if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) { + 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; @@ -429,7 +443,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) } /* Check whether the eMMC card supports background ops */ - if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) + if ((ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) && + card->ext_csd.hpi) card->ext_csd.bk_ops = 1; /* Check whether the eMMC card needs proactive refresh */ diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index c85c58aca3e2..b9b472796a64 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -555,6 +555,12 @@ int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) unsigned int flags; int err; + if (!card->ext_csd.hpi_en) { + pr_warning("%s: Card didn't support HPI command\n", + mmc_hostname(card->host)); + return -EINVAL; + } + opcode = card->ext_csd.hpi_cmd; flags = MMC_RSP_R1 | MMC_CMD_AC; |