aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmc
diff options
context:
space:
mode:
authorPratibhasagar V <pratibha@codeaurora.org>2016-06-09 18:09:31 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2016-07-25 10:34:12 +0200
commit5320226a051248b50cc2d80f2cb9599dfb56d422 (patch)
tree49b15538c654f6babac1b576d4a671826f179bf3 /include/linux/mmc
parentmmc: core: Only change mode if mmc_select_bus_width() is successful (diff)
downloadlinux-dev-5320226a051248b50cc2d80f2cb9599dfb56d422.tar.xz
linux-dev-5320226a051248b50cc2d80f2cb9599dfb56d422.zip
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. Signed-off-by: Pratibhasagar V <pratibha@codeaurora.org> Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> [gdavis: Forward port and cleanup] Signed-off-by: George G. Davis <george_davis@mentor.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'include/linux/mmc')
-rw-r--r--include/linux/mmc/card.h35
1 files changed, 30 insertions, 5 deletions
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 22defc2a83b7..d8673ca968ba 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -280,6 +280,7 @@ struct mmc_card {
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
#define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */
#define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */
+#define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */
unsigned int erase_size; /* erase size in sectors */
@@ -354,6 +355,9 @@ struct mmc_fixup {
/* SDIO-specfic fields. You can use SDIO_ANY_ID here of course */
u16 cis_vendor, cis_device;
+ /* for MMC cards */
+ unsigned int ext_csd_rev;
+
void (*vendor_fixup)(struct mmc_card *card, int data);
int data;
};
@@ -362,11 +366,20 @@ struct mmc_fixup {
#define CID_OEMID_ANY ((unsigned short) -1)
#define CID_NAME_ANY (NULL)
+#define EXT_CSD_REV_ANY (-1u)
+
+#define CID_MANFID_SANDISK 0x2
+#define CID_MANFID_TOSHIBA 0x11
+#define CID_MANFID_MICRON 0x13
+#define CID_MANFID_SAMSUNG 0x15
+#define CID_MANFID_KINGSTON 0x70
+#define CID_MANFID_HYNIX 0x90
+
#define END_FIXUP { NULL }
#define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \
_cis_vendor, _cis_device, \
- _fixup, _data) \
+ _fixup, _data, _ext_csd_rev) \
{ \
.name = (_name), \
.manfid = (_manfid), \
@@ -377,23 +390,30 @@ struct mmc_fixup {
.cis_device = (_cis_device), \
.vendor_fixup = (_fixup), \
.data = (_data), \
+ .ext_csd_rev = (_ext_csd_rev), \
}
#define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \
- _fixup, _data) \
+ _fixup, _data, _ext_csd_rev) \
_FIXUP_EXT(_name, _manfid, \
_oemid, _rev_start, _rev_end, \
SDIO_ANY_ID, SDIO_ANY_ID, \
- _fixup, _data) \
+ _fixup, _data, _ext_csd_rev) \
#define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \
- MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data)
+ MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \
+ EXT_CSD_REV_ANY)
+
+#define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \
+ _ext_csd_rev) \
+ MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \
+ _ext_csd_rev)
#define SDIO_FIXUP(_vendor, _device, _fixup, _data) \
_FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \
CID_OEMID_ANY, 0, -1ull, \
_vendor, _device, \
- _fixup, _data) \
+ _fixup, _data, EXT_CSD_REV_ANY) \
#define cid_rev(hwrev, fwrev, year, month) \
(((u64) hwrev) << 40 | \
@@ -512,6 +532,11 @@ static inline int mmc_card_broken_irq_polling(const struct mmc_card *c)
return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING;
}
+static inline int mmc_card_broken_hpi(const struct mmc_card *c)
+{
+ return c->quirks & MMC_QUIRK_BROKEN_HPI;
+}
+
#define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) (dev_name(&(c)->dev))