mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	mmc: Add MMC_QUIRK_BROKEN_SD_CACHE for Kingston Canvas Go Plus from 11/2019
This microSD card never clears Flush Cache bit after cache flush has
been started in sd_flush_cache(). This leads e.g. to failure to mount
file system. Add a quirk which disables the SD cache for this specific
card from specific manufacturing date of 11/2019, since on newer dated
cards from 05/2023 the cache flush works correctly.
Fixes: 08ebf903af ("mmc: core: Fixup support for writeback-cache for eMMC and SD")
Signed-off-by: Marek Vasut <marex@denx.de>
Link: https://lore.kernel.org/r/20230620102713.7701-1-marex@denx.de
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
			
			
This commit is contained in:
		
							parent
							
								
									f1738a1f81
								
							
						
					
					
						commit
						c467c8f081
					
				
					 4 changed files with 38 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -53,6 +53,10 @@ struct mmc_fixup {
 | 
			
		|||
	unsigned int manfid;
 | 
			
		||||
	unsigned short oemid;
 | 
			
		||||
 | 
			
		||||
	/* Manufacturing date */
 | 
			
		||||
	unsigned short year;
 | 
			
		||||
	unsigned char month;
 | 
			
		||||
 | 
			
		||||
	/* SDIO-specific fields. You can use SDIO_ANY_ID here of course */
 | 
			
		||||
	u16 cis_vendor, cis_device;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +72,8 @@ struct mmc_fixup {
 | 
			
		|||
 | 
			
		||||
#define CID_MANFID_ANY (-1u)
 | 
			
		||||
#define CID_OEMID_ANY ((unsigned short) -1)
 | 
			
		||||
#define CID_YEAR_ANY ((unsigned short) -1)
 | 
			
		||||
#define CID_MONTH_ANY ((unsigned char) -1)
 | 
			
		||||
#define CID_NAME_ANY (NULL)
 | 
			
		||||
 | 
			
		||||
#define EXT_CSD_REV_ANY (-1u)
 | 
			
		||||
| 
						 | 
				
			
			@ -81,17 +87,21 @@ struct mmc_fixup {
 | 
			
		|||
#define CID_MANFID_APACER       0x27
 | 
			
		||||
#define CID_MANFID_KINGSTON     0x70
 | 
			
		||||
#define CID_MANFID_HYNIX	0x90
 | 
			
		||||
#define CID_MANFID_KINGSTON_SD	0x9F
 | 
			
		||||
#define CID_MANFID_NUMONYX	0xFE
 | 
			
		||||
 | 
			
		||||
#define END_FIXUP { NULL }
 | 
			
		||||
 | 
			
		||||
#define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end,	\
 | 
			
		||||
		   _cis_vendor, _cis_device,				\
 | 
			
		||||
		   _fixup, _data, _ext_csd_rev)				\
 | 
			
		||||
#define _FIXUP_EXT(_name, _manfid, _oemid, _year, _month,	\
 | 
			
		||||
		   _rev_start, _rev_end,			\
 | 
			
		||||
		   _cis_vendor, _cis_device,			\
 | 
			
		||||
		   _fixup, _data, _ext_csd_rev)			\
 | 
			
		||||
	{						\
 | 
			
		||||
		.name = (_name),			\
 | 
			
		||||
		.manfid = (_manfid),			\
 | 
			
		||||
		.oemid = (_oemid),			\
 | 
			
		||||
		.year = (_year),			\
 | 
			
		||||
		.month = (_month),			\
 | 
			
		||||
		.rev_start = (_rev_start),		\
 | 
			
		||||
		.rev_end = (_rev_end),			\
 | 
			
		||||
		.cis_vendor = (_cis_vendor),		\
 | 
			
		||||
| 
						 | 
				
			
			@ -103,8 +113,8 @@ struct mmc_fixup {
 | 
			
		|||
 | 
			
		||||
#define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end,	\
 | 
			
		||||
		      _fixup, _data, _ext_csd_rev)			\
 | 
			
		||||
	_FIXUP_EXT(_name, _manfid,					\
 | 
			
		||||
		   _oemid, _rev_start, _rev_end,			\
 | 
			
		||||
	_FIXUP_EXT(_name, _manfid, _oemid, CID_YEAR_ANY, CID_MONTH_ANY,	\
 | 
			
		||||
		   _rev_start, _rev_end,				\
 | 
			
		||||
		   SDIO_ANY_ID, SDIO_ANY_ID,				\
 | 
			
		||||
		   _fixup, _data, _ext_csd_rev)				\
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,8 +128,9 @@ struct mmc_fixup {
 | 
			
		|||
		      _ext_csd_rev)
 | 
			
		||||
 | 
			
		||||
#define SDIO_FIXUP(_vendor, _device, _fixup, _data)			\
 | 
			
		||||
	_FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY,			\
 | 
			
		||||
		    CID_OEMID_ANY, 0, -1ull,				\
 | 
			
		||||
	_FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, CID_OEMID_ANY,		\
 | 
			
		||||
		   CID_YEAR_ANY, CID_MONTH_ANY,				\
 | 
			
		||||
		   0, -1ull,						\
 | 
			
		||||
		   _vendor, _device,					\
 | 
			
		||||
		   _fixup, _data, EXT_CSD_REV_ANY)			\
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -264,4 +275,9 @@ static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)
 | 
			
		|||
	return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int mmc_card_broken_sd_cache(const struct mmc_card *c)
 | 
			
		||||
{
 | 
			
		||||
	return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,6 +53,15 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
 | 
			
		|||
	MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
 | 
			
		||||
		  MMC_QUIRK_BLK_NO_CMD23),
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
 | 
			
		||||
	 * This has so far only been observed on cards from 11/2019, while new
 | 
			
		||||
	 * cards from 2023/05 do not exhibit this behavior.
 | 
			
		||||
	 */
 | 
			
		||||
	_FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
 | 
			
		||||
		   0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
 | 
			
		||||
		   MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Some SD cards lockup while using CMD23 multiblock transfers.
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +232,10 @@ static inline void mmc_fixup_device(struct mmc_card *card,
 | 
			
		|||
		if (f->of_compatible &&
 | 
			
		||||
		    !mmc_fixup_of_compatible_match(card, f->of_compatible))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (f->year != CID_YEAR_ANY && f->year != card->cid.year)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (f->month != CID_MONTH_ANY && f->month != card->cid.month)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup);
 | 
			
		||||
		f->vendor_fixup(card, f->data);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1170,7 +1170,7 @@ static int sd_parse_ext_reg_perf(struct mmc_card *card, u8 fno, u8 page,
 | 
			
		|||
		card->ext_perf.feature_support |= SD_EXT_PERF_HOST_MAINT;
 | 
			
		||||
 | 
			
		||||
	/* Cache support at bit 0. */
 | 
			
		||||
	if (reg_buf[4] & BIT(0))
 | 
			
		||||
	if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card))
 | 
			
		||||
		card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
 | 
			
		||||
 | 
			
		||||
	/* Command queue support indicated via queue depth bits (0 to 4). */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -294,6 +294,7 @@ struct mmc_card {
 | 
			
		|||
#define MMC_QUIRK_TRIM_BROKEN	(1<<12)		/* Skip trim */
 | 
			
		||||
#define MMC_QUIRK_BROKEN_HPI	(1<<13)		/* Disable broken HPI support */
 | 
			
		||||
#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 */
 | 
			
		||||
 | 
			
		||||
	bool			reenable_cmdq;	/* Re-enable Command Queue */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue