From 2bef02bee8fa74273cfc764e288b6f92b8646bb7 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sat, 19 Feb 2022 19:39:32 +0900 Subject: [PATCH v2] mtd: cfi_cmdset_0002: Change chip_good() to check DQ true data 0xFF The regression issue has been caused on S29GL064N and reported it. The change mentioned for regression is to use chip_good() for buffered write. Also it seems that the 0xFF value is read on the error case. It is possible to be caused by DQ true data described by S29GL064N datasheet. So change chip_good() to check DQ true data 0xFF additionally for the error. Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value") Signed-off-by: Tokunori Ikegami Cc: linux-mtd@lists.infradead.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/linux-mtd/cedb1604-e024-2738-5b33-15703a653803@gmail.com/ --- drivers/mtd/chips/cfi_cmdset_0002.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index a761134fd3be..079f69e5400d 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -853,7 +853,7 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip, * */ static int __xipram chip_good(struct map_info *map, struct flchip *chip, - unsigned long addr, map_word expected) + unsigned long addr, map_word *expected) { struct cfi_private *cfi = map->fldrv_priv; map_word oldd, curd; @@ -875,8 +875,13 @@ static int __xipram chip_good(struct map_info *map, struct flchip *chip, oldd = map_read(map, addr); curd = map_read(map, addr); - return map_word_equal(map, oldd, curd) && - map_word_equal(map, curd, expected); + if (!map_word_equal(map, oldd, curd)) + return 0; + + if (expected && map_word_equal(map, curd, *expected)) + return 1; + + return map_word_equal(map, oldd, map_word_ff(map)); } static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) @@ -1699,7 +1704,7 @@ static int __xipram do_write_oneword_once(struct map_info *map, * "chip_good" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_good(map, chip, adr, datum)) { + !chip_good(map, chip, adr, &datum)) { xip_enable(map, chip, adr); printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); xip_disable(map, chip, adr); @@ -1707,7 +1712,7 @@ static int __xipram do_write_oneword_once(struct map_info *map, break; } - if (chip_good(map, chip, adr, datum)) { + if (chip_good(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -1979,14 +1984,14 @@ static int __xipram do_write_buffer_wait(struct map_info *map, * "chip_good" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_good(map, chip, adr, datum)) { + !chip_good(map, chip, adr, &datum)) { pr_err("MTD %s(): software timeout, address:0x%.8lx.\n", __func__, adr); ret = -EIO; break; } - if (chip_good(map, chip, adr, datum)) { + if (chip_good(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -2282,7 +2287,7 @@ static int do_panic_write_oneword(struct map_info *map, struct flchip *chip, udelay(1); } - if (!chip_good(map, chip, adr, datum) || + if (!chip_good(map, chip, adr, &datum) || cfi_check_err_status(map, chip, adr)) { /* reset on all failures. */ map_write(map, CMD(0xF0), chip->start); @@ -2478,7 +2483,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) chip->erase_suspended = 0; } - if (chip_good(map, chip, adr, map_word_ff(map))) { + if (chip_good(map, chip, adr, NULL)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -2577,7 +2582,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, chip->erase_suspended = 0; } - if (chip_good(map, chip, adr, map_word_ff(map))) { + if (chip_good(map, chip, adr, NULL)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; -- 2.32.0