Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: cfi_cmdset_0002: Use chip_ready() for write on S29GL064N

Since commit dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to
check correct value") buffered writes fail on S29GL064N. This is
because, on S29GL064N, reads return 0xFF at the end of DQ polling for
write completion, where as, chip_good() check expects actual data
written to the last location to be returned post DQ polling completion.
Fix is to revert to using chip_good() for S29GL064N which only checks
for DQ lines to settle down to determine write completion.

Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.de/
Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
Cc: stable@vger.kernel.org
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
Acked-by: Vignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20220323170458.5608-3-ikegami.t@gmail.com

authored by

Tokunori Ikegami and committed by
Miquel Raynal
0a8e9830 083084df

+35 -8
+34 -8
drivers/mtd/chips/cfi_cmdset_0002.c
··· 59 59 #define CFI_SR_WBASB BIT(3) 60 60 #define CFI_SR_SLSB BIT(1) 61 61 62 + enum cfi_quirks { 63 + CFI_QUIRK_DQ_TRUE_DATA = BIT(0), 64 + }; 65 + 62 66 static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 63 67 static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 64 68 #if !FORCE_WORD_WRITE ··· 440 436 mtd->name); 441 437 } 442 438 439 + static void fixup_quirks(struct mtd_info *mtd) 440 + { 441 + struct map_info *map = mtd->priv; 442 + struct cfi_private *cfi = map->fldrv_priv; 443 + 444 + if (cfi->mfr == CFI_MFR_AMD && cfi->id == 0x0c01) 445 + cfi->quirks |= CFI_QUIRK_DQ_TRUE_DATA; 446 + } 447 + 443 448 /* Used to fix CFI-Tables of chips without Extended Query Tables */ 444 449 static struct cfi_fixup cfi_nopri_fixup_table[] = { 445 450 { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */ ··· 487 474 #if !FORCE_WORD_WRITE 488 475 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers }, 489 476 #endif 477 + { CFI_MFR_ANY, CFI_ID_ANY, fixup_quirks }, 490 478 { 0, 0, NULL } 491 479 }; 492 480 static struct cfi_fixup jedec_fixup_table[] = { ··· 858 844 return ret; 859 845 860 846 return map_word_equal(map, t, *expected); 847 + } 848 + 849 + static int __xipram chip_good(struct map_info *map, struct flchip *chip, 850 + unsigned long addr, map_word *expected) 851 + { 852 + struct cfi_private *cfi = map->fldrv_priv; 853 + map_word *datum = expected; 854 + 855 + if (cfi->quirks & CFI_QUIRK_DQ_TRUE_DATA) 856 + datum = NULL; 857 + 858 + return chip_ready(map, chip, addr, datum); 861 859 } 862 860 863 861 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) ··· 1688 1662 } 1689 1663 1690 1664 /* 1691 - * We check "time_after" and "!chip_ready" before checking 1692 - * "chip_ready" to avoid the failure due to scheduling. 1665 + * We check "time_after" and "!chip_good" before checking 1666 + * "chip_good" to avoid the failure due to scheduling. 1693 1667 */ 1694 1668 if (time_after(jiffies, timeo) && 1695 - !chip_ready(map, chip, adr, &datum)) { 1669 + !chip_good(map, chip, adr, &datum)) { 1696 1670 xip_enable(map, chip, adr); 1697 1671 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); 1698 1672 xip_disable(map, chip, adr); ··· 1700 1674 break; 1701 1675 } 1702 1676 1703 - if (chip_ready(map, chip, adr, &datum)) { 1677 + if (chip_good(map, chip, adr, &datum)) { 1704 1678 if (cfi_check_err_status(map, chip, adr)) 1705 1679 ret = -EIO; 1706 1680 break; ··· 1968 1942 } 1969 1943 1970 1944 /* 1971 - * We check "time_after" and "!chip_ready" before checking 1972 - * "chip_ready" to avoid the failure due to scheduling. 1945 + * We check "time_after" and "!chip_good" before checking 1946 + * "chip_good" to avoid the failure due to scheduling. 1973 1947 */ 1974 1948 if (time_after(jiffies, timeo) && 1975 - !chip_ready(map, chip, adr, &datum)) { 1949 + !chip_good(map, chip, adr, &datum)) { 1976 1950 pr_err("MTD %s(): software timeout, address:0x%.8lx.\n", 1977 1951 __func__, adr); 1978 1952 ret = -EIO; 1979 1953 break; 1980 1954 } 1981 1955 1982 - if (chip_ready(map, chip, adr, &datum)) { 1956 + if (chip_good(map, chip, adr, &datum)) { 1983 1957 if (cfi_check_err_status(map, chip, adr)) 1984 1958 ret = -EIO; 1985 1959 break;
+1
include/linux/mtd/cfi.h
··· 286 286 map_word sector_erase_cmd; 287 287 unsigned long chipshift; /* Because they're of the same type */ 288 288 const char *im_name; /* inter_module name for cmdset_setup */ 289 + unsigned long quirks; 289 290 struct flchip chips[]; /* per-chip data structure for each chip */ 290 291 }; 291 292