mmc: Hynix 4.41 iNAND no trim quirk patch from mediatek
authorlintao <lintao@rock-chips.com>
Wed, 22 Oct 2014 06:59:23 +0000 (14:59 +0800)
committerlintao <lintao@rock-chips.com>
Wed, 22 Oct 2014 06:59:32 +0000 (14:59 +0800)
drivers/mmc/card/block.c
drivers/mmc/core/core.c
include/linux/mmc/card.h

index 8d4d8837fb00a52bce02a9a2419803aaf555c8b7..a5eb95bc4717bc478829bfd075f95a29b18e6061 100755 (executable)
@@ -2318,6 +2318,7 @@ force_ro_fail:
 #define CID_MANFID_TOSHIBA     0x11
 #define CID_MANFID_MICRON      0x13
 #define CID_MANFID_SAMSUNG     0x15
+#define CID_MANFID_HYNIX        0x90
 
 static const struct mmc_fixup blk_fixups[] =
 {
@@ -2376,6 +2377,10 @@ static const struct mmc_fixup blk_fixups[] =
        MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
                  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
 
+       /* Hynix 4.41 iNAND execute trim will lead boot up failed. */
+       MMC_FIXUP(CID_NAME_ANY, CID_MANFID_HYNIX, CID_OEMID_ANY, add_quirk_mmc,
+                 MMC_QUIRK_TRIM_UNSTABLE),
+
        END_FIXUP
 };
 
index efc26a00665cf4ede5404306dc0e7ca420bda105..307fae48fd37a4e8eb23c9c1ecc47e0f4e462ff5 100755 (executable)
@@ -2109,7 +2109,8 @@ EXPORT_SYMBOL(mmc_can_erase);
 
 int mmc_can_trim(struct mmc_card *card)
 {
-       if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
+       if ((card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) &&
+           !(card->quirks & MMC_QUIRK_TRIM_UNSTABLE))
                return 1;
        return 0;
 }
index cfa28593de910edc2800e0a2d60aec7b88fe5c95..cf89531adb59510893688b67d649abfab6e10c3b 100644 (file)
@@ -276,6 +276,7 @@ struct mmc_card {
 #define MMC_QUIRK_LONG_READ_TIME (1<<9)                /* Data read time > CSD says */
 #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_UNSTABLE (1<<28)                /* Skip trim */
 
        unsigned int            erase_size;     /* erase size in sectors */
        unsigned int            erase_shift;    /* if erase unit is power 2 */