]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mmc: core: Add SD card quirk for broken poweroff notification
authorKeita Aihara <keita.aihara@sony.com>
Fri, 13 Sep 2024 09:44:17 +0000 (18:44 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2024 19:03:40 +0000 (20:03 +0100)
[ Upstream commit cd068d51594d9635bf6688fc78717572b78bce6a ]

GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 report that
they support poweroff notification and cache, but they are not working
correctly.

Flush Cache bit never gets cleared in sd_flush_cache() and Poweroff
Notification Ready bit also never gets set to 1 within 1 second from the
end of busy of CMD49 in sd_poweroff_notify().

This leads to I/O error and runtime PM error state.

I observed that the same card manufactured on 01/2024 works as expected.

This problem seems similar to the Kingston cards fixed with
commit c467c8f08185 ("mmc: Add MMC_QUIRK_BROKEN_SD_CACHE for Kingston
Canvas Go Plus from 11/2019") and should be handled using quirks.

CID for the problematic card is here.
12345641535443002000000145016200

Manufacturer ID is 0x12 and defined as CID_MANFID_GIGASTONE as of now,
but would like comments on what naming is appropriate because MID list
is not public and not sure it's right.

Signed-off-by: Keita Aihara <keita.aihara@sony.com>
Link: https://lore.kernel.org/r/20240913094417.GA4191647@sony.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/mmc/core/card.h
drivers/mmc/core/quirks.h
drivers/mmc/core/sd.c
include/linux/mmc/card.h

index 64dcb463a4f491163478da16115c1630417a7eae..3205feb1e8ff6ac7296e81075c105798a5bbac68 100644 (file)
@@ -85,6 +85,7 @@ struct mmc_fixup {
 #define CID_MANFID_SANDISK_SD   0x3
 #define CID_MANFID_ATP          0x9
 #define CID_MANFID_TOSHIBA      0x11
+#define CID_MANFID_GIGASTONE    0x12
 #define CID_MANFID_MICRON       0x13
 #define CID_MANFID_SAMSUNG      0x15
 #define CID_MANFID_APACER       0x27
@@ -287,4 +288,10 @@ static inline int mmc_card_broken_cache_flush(const struct mmc_card *c)
 {
        return c->quirks & MMC_QUIRK_BROKEN_CACHE_FLUSH;
 }
+
+static inline int mmc_card_broken_sd_poweroff_notify(const struct mmc_card *c)
+{
+       return c->quirks & MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY;
+}
+
 #endif
index 92905fc46436dd107563d7ec2985780539e385a0..89b512905be1400334322484805c3cca01dc69c6 100644 (file)
@@ -25,6 +25,15 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
                   0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
                   MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
 
+       /*
+        * GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 never
+        * clear Flush Cache bit and set Poweroff Notification Ready bit.
+        */
+       _FIXUP_EXT("ASTC", CID_MANFID_GIGASTONE, 0x3456, 2022, 2,
+                  0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
+                  MMC_QUIRK_BROKEN_SD_CACHE | MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY,
+                  EXT_CSD_REV_ANY),
+
        END_FIXUP
 };
 
index 1d09f0f2e76970a35a53aba6782c8afeaf89afaa..63915541c0e494388e4749b6efca57df5a653aaf 100644 (file)
@@ -1113,7 +1113,7 @@ static int sd_parse_ext_reg_power(struct mmc_card *card, u8 fno, u8 page,
        card->ext_power.rev = reg_buf[0] & 0xf;
 
        /* Power Off Notification support at bit 4. */
-       if (reg_buf[1] & BIT(4))
+       if ((reg_buf[1] & BIT(4)) && !mmc_card_broken_sd_poweroff_notify(card))
                card->ext_power.feature_support |= SD_EXT_POWER_OFF_NOTIFY;
 
        /* Power Sustenance support at bit 5. */
index f39bce3223654f89e20c134fa9cef48ddbe8e46b..eb67d3d5ff5b22784bfa7032da13773cc68ec60b 100644 (file)
@@ -294,6 +294,7 @@ struct mmc_card {
 #define MMC_QUIRK_BROKEN_SD_DISCARD    (1<<14) /* Disable broken SD discard support */
 #define MMC_QUIRK_BROKEN_SD_CACHE      (1<<15) /* Disable broken SD cache support */
 #define MMC_QUIRK_BROKEN_CACHE_FLUSH   (1<<16) /* Don't flush cache until the write has occurred */
+#define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY    (1<<17) /* Disable broken SD poweroff notify support */
 
        bool                    written_flag;   /* Indicates eMMC has been written since power on */
        bool                    reenable_cmdq;  /* Re-enable Command Queue */