summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2015-10-14 16:11:59 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2015-10-14 16:11:59 +0200
commit332211ed906a6d3c7ffb0f3cae1865348aadcd14 (patch)
tree319ff3e1d2964a1572ca466beee1b93aa1b71552 /drivers
parent891f3ac4478238d6ff890a3bd5c8536e7ef91d5e (diff)
mmc: core: Disable HPI for certain Hynix eMMC cards
Certain Hynix eMMC 4.41 cards might get broken when HPI feature is used and hence this patch disables the HPI feature for such buggy cards. As some of the other features like BKOPs/Cache/Sanitize are dependent on HPI feature, those features would also get disabled if HPI is disabled. Change-Id: I6a638ce089cbd977122e47aecb721bc3f0adf7b0 Signed-off-by: Pratibhasagar V <pratibha@codeaurora.org> Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> Fix ported from the following Android MSM kernel commit: https://www.codeaurora.org/cgit/quic/la/kernel/msm/commit/?id=84af3731019921a28d595dbf6cbf00539706a42c
Diffstat (limited to 'drivers')
-rwxr-xr-xdrivers/mmc/core/mmc.c19
-rw-r--r--drivers/mmc/core/mmc_ops.c6
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;