Skip to content

Commit bc7ff55

Browse files
TE-KeitaAiharagregkh
authored andcommitted
mmc: core: Add SD card quirk for broken poweroff notification
[ Upstream commit cd068d5 ] 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 c467c8f ("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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 87ace43 commit bc7ff55

File tree

4 files changed

+18
-1
lines changed

4 files changed

+18
-1
lines changed

drivers/mmc/core/card.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct mmc_fixup {
8585
#define CID_MANFID_SANDISK_SD 0x3
8686
#define CID_MANFID_ATP 0x9
8787
#define CID_MANFID_TOSHIBA 0x11
88+
#define CID_MANFID_GIGASTONE 0x12
8889
#define CID_MANFID_MICRON 0x13
8990
#define CID_MANFID_SAMSUNG 0x15
9091
#define CID_MANFID_APACER 0x27
@@ -287,4 +288,10 @@ static inline int mmc_card_broken_cache_flush(const struct mmc_card *c)
287288
{
288289
return c->quirks & MMC_QUIRK_BROKEN_CACHE_FLUSH;
289290
}
291+
292+
static inline int mmc_card_broken_sd_poweroff_notify(const struct mmc_card *c)
293+
{
294+
return c->quirks & MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY;
295+
}
296+
290297
#endif

drivers/mmc/core/quirks.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
2525
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
2626
MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
2727

28+
/*
29+
* GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 never
30+
* clear Flush Cache bit and set Poweroff Notification Ready bit.
31+
*/
32+
_FIXUP_EXT("ASTC", CID_MANFID_GIGASTONE, 0x3456, 2022, 2,
33+
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
34+
MMC_QUIRK_BROKEN_SD_CACHE | MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY,
35+
EXT_CSD_REV_ANY),
36+
2837
END_FIXUP
2938
};
3039

drivers/mmc/core/sd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ static int sd_parse_ext_reg_power(struct mmc_card *card, u8 fno, u8 page,
11131113
card->ext_power.rev = reg_buf[0] & 0xf;
11141114

11151115
/* Power Off Notification support at bit 4. */
1116-
if (reg_buf[1] & BIT(4))
1116+
if ((reg_buf[1] & BIT(4)) && !mmc_card_broken_sd_poweroff_notify(card))
11171117
card->ext_power.feature_support |= SD_EXT_POWER_OFF_NOTIFY;
11181118

11191119
/* Power Sustenance support at bit 5. */

include/linux/mmc/card.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ struct mmc_card {
294294
#define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14) /* Disable broken SD discard support */
295295
#define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */
296296
#define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16) /* Don't flush cache until the write has occurred */
297+
#define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY (1<<17) /* Disable broken SD poweroff notify support */
297298

298299
bool written_flag; /* Indicates eMMC has been written since power on */
299300
bool reenable_cmdq; /* Re-enable Command Queue */

0 commit comments

Comments
 (0)