Skip to content

Commit 0a8e983

Browse files
ikegami-tmiquelraynal
authored andcommitted
mtd: cfi_cmdset_0002: Use chip_ready() for write on S29GL064N
Since commit dfeae10("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: dfeae10("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
1 parent 083084d commit 0a8e983

2 files changed

Lines changed: 35 additions & 8 deletions

File tree

drivers/mtd/chips/cfi_cmdset_0002.c

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
#define CFI_SR_WBASB BIT(3)
6060
#define CFI_SR_SLSB BIT(1)
6161

62+
enum cfi_quirks {
63+
CFI_QUIRK_DQ_TRUE_DATA = BIT(0),
64+
};
65+
6266
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
6367
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
6468
#if !FORCE_WORD_WRITE
@@ -436,6 +440,15 @@ static void fixup_s29ns512p_sectors(struct mtd_info *mtd)
436440
mtd->name);
437441
}
438442

443+
static void fixup_quirks(struct mtd_info *mtd)
444+
{
445+
struct map_info *map = mtd->priv;
446+
struct cfi_private *cfi = map->fldrv_priv;
447+
448+
if (cfi->mfr == CFI_MFR_AMD && cfi->id == 0x0c01)
449+
cfi->quirks |= CFI_QUIRK_DQ_TRUE_DATA;
450+
}
451+
439452
/* Used to fix CFI-Tables of chips without Extended Query Tables */
440453
static struct cfi_fixup cfi_nopri_fixup_table[] = {
441454
{ CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */
@@ -474,6 +487,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
474487
#if !FORCE_WORD_WRITE
475488
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers },
476489
#endif
490+
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_quirks },
477491
{ 0, 0, NULL }
478492
};
479493
static struct cfi_fixup jedec_fixup_table[] = {
@@ -846,6 +860,18 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
846860
return map_word_equal(map, t, *expected);
847861
}
848862

863+
static int __xipram chip_good(struct map_info *map, struct flchip *chip,
864+
unsigned long addr, map_word *expected)
865+
{
866+
struct cfi_private *cfi = map->fldrv_priv;
867+
map_word *datum = expected;
868+
869+
if (cfi->quirks & CFI_QUIRK_DQ_TRUE_DATA)
870+
datum = NULL;
871+
872+
return chip_ready(map, chip, addr, datum);
873+
}
874+
849875
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
850876
{
851877
DECLARE_WAITQUEUE(wait, current);
@@ -1662,19 +1688,19 @@ static int __xipram do_write_oneword_once(struct map_info *map,
16621688
}
16631689

16641690
/*
1665-
* We check "time_after" and "!chip_ready" before checking
1666-
* "chip_ready" to avoid the failure due to scheduling.
1691+
* We check "time_after" and "!chip_good" before checking
1692+
* "chip_good" to avoid the failure due to scheduling.
16671693
*/
16681694
if (time_after(jiffies, timeo) &&
1669-
!chip_ready(map, chip, adr, &datum)) {
1695+
!chip_good(map, chip, adr, &datum)) {
16701696
xip_enable(map, chip, adr);
16711697
printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
16721698
xip_disable(map, chip, adr);
16731699
ret = -EIO;
16741700
break;
16751701
}
16761702

1677-
if (chip_ready(map, chip, adr, &datum)) {
1703+
if (chip_good(map, chip, adr, &datum)) {
16781704
if (cfi_check_err_status(map, chip, adr))
16791705
ret = -EIO;
16801706
break;
@@ -1942,18 +1968,18 @@ static int __xipram do_write_buffer_wait(struct map_info *map,
19421968
}
19431969

19441970
/*
1945-
* We check "time_after" and "!chip_ready" before checking
1946-
* "chip_ready" to avoid the failure due to scheduling.
1971+
* We check "time_after" and "!chip_good" before checking
1972+
* "chip_good" to avoid the failure due to scheduling.
19471973
*/
19481974
if (time_after(jiffies, timeo) &&
1949-
!chip_ready(map, chip, adr, &datum)) {
1975+
!chip_good(map, chip, adr, &datum)) {
19501976
pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
19511977
__func__, adr);
19521978
ret = -EIO;
19531979
break;
19541980
}
19551981

1956-
if (chip_ready(map, chip, adr, &datum)) {
1982+
if (chip_good(map, chip, adr, &datum)) {
19571983
if (cfi_check_err_status(map, chip, adr))
19581984
ret = -EIO;
19591985
break;

include/linux/mtd/cfi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ struct cfi_private {
286286
map_word sector_erase_cmd;
287287
unsigned long chipshift; /* Because they're of the same type */
288288
const char *im_name; /* inter_module name for cmdset_setup */
289+
unsigned long quirks;
289290
struct flchip chips[]; /* per-chip data structure for each chip */
290291
};
291292

0 commit comments

Comments
 (0)