0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/of.h>
0014 #include <linux/mmc/sdio_ids.h>
0015
0016 #include "card.h"
0017
0018 static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
0019 #define INAND_CMD38_ARG_EXT_CSD 113
0020 #define INAND_CMD38_ARG_ERASE 0x00
0021 #define INAND_CMD38_ARG_TRIM 0x01
0022 #define INAND_CMD38_ARG_SECERASE 0x80
0023 #define INAND_CMD38_ARG_SECTRIM1 0x81
0024 #define INAND_CMD38_ARG_SECTRIM2 0x88
0025
0026 MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk,
0027 MMC_QUIRK_INAND_CMD38),
0028 MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk,
0029 MMC_QUIRK_INAND_CMD38),
0030 MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk,
0031 MMC_QUIRK_INAND_CMD38),
0032 MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk,
0033 MMC_QUIRK_INAND_CMD38),
0034 MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk,
0035 MMC_QUIRK_INAND_CMD38),
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 MMC_FIXUP("SDMB-32", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc,
0046 MMC_QUIRK_BLK_NO_CMD23),
0047 MMC_FIXUP("SDM032", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc,
0048 MMC_QUIRK_BLK_NO_CMD23),
0049 MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
0050 MMC_QUIRK_BLK_NO_CMD23),
0051 MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
0052 MMC_QUIRK_BLK_NO_CMD23),
0053 MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
0054 MMC_QUIRK_BLK_NO_CMD23),
0055
0056
0057
0058
0059 MMC_FIXUP("AF SD", CID_MANFID_ATP, CID_OEMID_ANY, add_quirk_sd,
0060 MMC_QUIRK_BLK_NO_CMD23),
0061 MMC_FIXUP("APUSD", CID_MANFID_APACER, 0x5048, add_quirk_sd,
0062 MMC_QUIRK_BLK_NO_CMD23),
0063
0064
0065
0066
0067 MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,
0068 MMC_QUIRK_LONG_READ_TIME),
0069 MMC_FIXUP("008GE0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
0070 MMC_QUIRK_LONG_READ_TIME),
0071
0072
0073
0074
0075
0076
0077 MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0078 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0079 MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0080 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0081 MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0082 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0083 MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0084 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0085 MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0086 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0087 MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0088 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0089 MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0090 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0091 MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
0092 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
0093
0094
0095
0096
0097
0098 MMC_FIXUP("V10008", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
0099 MMC_QUIRK_TRIM_BROKEN),
0100 MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
0101 MMC_QUIRK_TRIM_BROKEN),
0102
0103 END_FIXUP
0104 };
0105
0106 static const struct mmc_fixup __maybe_unused mmc_ext_csd_fixups[] = {
0107
0108
0109
0110
0111 MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX,
0112 0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5),
0113
0114
0115
0116
0117 MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_NUMONYX,
0118 0x014e, add_quirk, MMC_QUIRK_BROKEN_HPI, 6),
0119
0120 END_FIXUP
0121 };
0122
0123
0124 static const struct mmc_fixup __maybe_unused sdio_fixup_methods[] = {
0125 SDIO_FIXUP(SDIO_VENDOR_ID_TI_WL1251, SDIO_DEVICE_ID_TI_WL1251,
0126 add_quirk, MMC_QUIRK_NONSTD_FUNC_IF),
0127
0128 SDIO_FIXUP(SDIO_VENDOR_ID_TI_WL1251, SDIO_DEVICE_ID_TI_WL1251,
0129 add_quirk, MMC_QUIRK_DISABLE_CD),
0130
0131 SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
0132 add_quirk, MMC_QUIRK_NONSTD_FUNC_IF),
0133
0134 SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
0135 add_quirk, MMC_QUIRK_DISABLE_CD),
0136
0137 SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200,
0138 add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512),
0139
0140 SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0,
0141 add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING),
0142
0143 SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8887_F0,
0144 add_limit_rate_quirk, 150000000),
0145
0146 END_FIXUP
0147 };
0148
0149 static const struct mmc_fixup __maybe_unused sdio_card_init_methods[] = {
0150 SDIO_FIXUP_COMPATIBLE("ti,wl1251", wl1251_quirk, 0),
0151
0152 SDIO_FIXUP_COMPATIBLE("silabs,wf200", add_quirk,
0153 MMC_QUIRK_BROKEN_BYTE_MODE_512 |
0154 MMC_QUIRK_LENIENT_FN0 |
0155 MMC_QUIRK_BLKSZ_FOR_BYTE_MODE),
0156
0157 END_FIXUP
0158 };
0159
0160 static inline bool mmc_fixup_of_compatible_match(struct mmc_card *card,
0161 const char *compatible)
0162 {
0163 struct device_node *np;
0164
0165 for_each_child_of_node(mmc_dev(card->host)->of_node, np) {
0166 if (of_device_is_compatible(np, compatible)) {
0167 of_node_put(np);
0168 return true;
0169 }
0170 }
0171
0172 return false;
0173 }
0174
0175 static inline void mmc_fixup_device(struct mmc_card *card,
0176 const struct mmc_fixup *table)
0177 {
0178 const struct mmc_fixup *f;
0179 u64 rev = cid_rev_card(card);
0180
0181 for (f = table; f->vendor_fixup; f++) {
0182 if (f->manfid != CID_MANFID_ANY &&
0183 f->manfid != card->cid.manfid)
0184 continue;
0185 if (f->oemid != CID_OEMID_ANY &&
0186 f->oemid != card->cid.oemid)
0187 continue;
0188 if (f->name != CID_NAME_ANY &&
0189 strncmp(f->name, card->cid.prod_name,
0190 sizeof(card->cid.prod_name)))
0191 continue;
0192 if (f->cis_vendor != (u16)SDIO_ANY_ID &&
0193 f->cis_vendor != card->cis.vendor)
0194 continue;
0195 if (f->cis_device != (u16)SDIO_ANY_ID &&
0196 f->cis_device != card->cis.device)
0197 continue;
0198 if (f->ext_csd_rev != EXT_CSD_REV_ANY &&
0199 f->ext_csd_rev != card->ext_csd.rev)
0200 continue;
0201 if (rev < f->rev_start || rev > f->rev_end)
0202 continue;
0203 if (f->of_compatible &&
0204 !mmc_fixup_of_compatible_match(card, f->of_compatible))
0205 continue;
0206
0207 dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup);
0208 f->vendor_fixup(card, f->data);
0209 }
0210 }