| From 083084df578a8bdb18334f69e7b32d690aaa3247 Mon Sep 17 00:00:00 2001 |
| From: Tokunori Ikegami <ikegami.t@gmail.com> |
| Date: Thu, 24 Mar 2022 02:04:55 +0900 |
| Subject: mtd: cfi_cmdset_0002: Move and rename chip_check/chip_ready/chip_good_for_write |
| |
| From: Tokunori Ikegami <ikegami.t@gmail.com> |
| |
| commit 083084df578a8bdb18334f69e7b32d690aaa3247 upstream. |
| |
| This is a preparation patch for the S29GL064N buffer writes fix. There |
| is no functional change. |
| |
| 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") |
| Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com> |
| Cc: stable@vger.kernel.org |
| 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-2-ikegami.t@gmail.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/mtd/chips/cfi_cmdset_0002.c | 77 ++++++++++++++---------------------- |
| 1 file changed, 32 insertions(+), 45 deletions(-) |
| |
| --- a/drivers/mtd/chips/cfi_cmdset_0002.c |
| +++ b/drivers/mtd/chips/cfi_cmdset_0002.c |
| @@ -726,50 +726,34 @@ static struct mtd_info *cfi_amdstd_setup |
| } |
| |
| /* |
| - * Return true if the chip is ready. |
| + * Return true if the chip is ready and has the correct value. |
| * |
| * Ready is one of: read mode, query mode, erase-suspend-read mode (in any |
| * non-suspended sector) and is indicated by no toggle bits toggling. |
| * |
| + * Error are indicated by toggling bits or bits held with the wrong value, |
| + * or with bits toggling. |
| + * |
| * Note that anything more complicated than checking if no bits are toggling |
| * (including checking DQ5 for an error status) is tricky to get working |
| * correctly and is therefore not done (particularly with interleaved chips |
| * as each chip must be checked independently of the others). |
| */ |
| -static int __xipram chip_ready(struct map_info *map, unsigned long addr) |
| +static int __xipram chip_ready(struct map_info *map, unsigned long addr, |
| + map_word *expected) |
| { |
| map_word d, t; |
| + int ret; |
| |
| d = map_read(map, addr); |
| t = map_read(map, addr); |
| |
| - return map_word_equal(map, d, t); |
| -} |
| + ret = map_word_equal(map, d, t); |
| |
| -/* |
| - * Return true if the chip is ready and has the correct value. |
| - * |
| - * Ready is one of: read mode, query mode, erase-suspend-read mode (in any |
| - * non-suspended sector) and it is indicated by no bits toggling. |
| - * |
| - * Error are indicated by toggling bits or bits held with the wrong value, |
| - * or with bits toggling. |
| - * |
| - * Note that anything more complicated than checking if no bits are toggling |
| - * (including checking DQ5 for an error status) is tricky to get working |
| - * correctly and is therefore not done (particularly with interleaved chips |
| - * as each chip must be checked independently of the others). |
| - * |
| - */ |
| -static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected) |
| -{ |
| - map_word oldd, curd; |
| - |
| - oldd = map_read(map, addr); |
| - curd = map_read(map, addr); |
| + if (!ret || !expected) |
| + return ret; |
| |
| - return map_word_equal(map, oldd, curd) && |
| - map_word_equal(map, curd, expected); |
| + return map_word_equal(map, t, *expected); |
| } |
| |
| static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) |
| @@ -786,7 +770,7 @@ static int get_chip(struct map_info *map |
| |
| case FL_STATUS: |
| for (;;) { |
| - if (chip_ready(map, adr)) |
| + if (chip_ready(map, adr, NULL)) |
| break; |
| |
| if (time_after(jiffies, timeo)) { |
| @@ -824,7 +808,7 @@ static int get_chip(struct map_info *map |
| chip->state = FL_ERASE_SUSPENDING; |
| chip->erase_suspended = 1; |
| for (;;) { |
| - if (chip_ready(map, adr)) |
| + if (chip_ready(map, adr, NULL)) |
| break; |
| |
| if (time_after(jiffies, timeo)) { |
| @@ -1357,7 +1341,7 @@ static int do_otp_lock(struct map_info * |
| /* wait for chip to become ready */ |
| timeo = jiffies + msecs_to_jiffies(2); |
| for (;;) { |
| - if (chip_ready(map, adr)) |
| + if (chip_ready(map, adr, NULL)) |
| break; |
| |
| if (time_after(jiffies, timeo)) { |
| @@ -1624,10 +1608,11 @@ static int __xipram do_write_oneword(str |
| } |
| |
| /* |
| - * We check "time_after" and "!chip_good" before checking |
| - * "chip_good" to avoid the failure due to scheduling. |
| + * We check "time_after" and "!chip_ready" before checking |
| + * "chip_ready" to avoid the failure due to scheduling. |
| */ |
| - if (time_after(jiffies, timeo) && !chip_good(map, adr, datum)) { |
| + if (time_after(jiffies, timeo) && |
| + !chip_ready(map, adr, &datum)) { |
| xip_enable(map, chip, adr); |
| printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); |
| xip_disable(map, chip, adr); |
| @@ -1635,7 +1620,7 @@ static int __xipram do_write_oneword(str |
| break; |
| } |
| |
| - if (chip_good(map, adr, datum)) |
| + if (chip_ready(map, adr, &datum)) |
| break; |
| |
| /* Latency issues. Drop the lock, wait a while and retry */ |
| @@ -1879,13 +1864,13 @@ static int __xipram do_write_buffer(stru |
| } |
| |
| /* |
| - * We check "time_after" and "!chip_good" before checking "chip_good" to avoid |
| - * the failure due to scheduling. |
| + * We check "time_after" and "!chip_ready" before checking |
| + * "chip_ready" to avoid the failure due to scheduling. |
| */ |
| - if (time_after(jiffies, timeo) && !chip_good(map, adr, datum)) |
| + if (time_after(jiffies, timeo) && !chip_ready(map, adr, &datum)) |
| break; |
| |
| - if (chip_good(map, adr, datum)) { |
| + if (chip_ready(map, adr, &datum)) { |
| xip_enable(map, chip, adr); |
| goto op_done; |
| } |
| @@ -2019,7 +2004,7 @@ static int cfi_amdstd_panic_wait(struct |
| * If the driver thinks the chip is idle, and no toggle bits |
| * are changing, then the chip is actually idle for sure. |
| */ |
| - if (chip->state == FL_READY && chip_ready(map, adr)) |
| + if (chip->state == FL_READY && chip_ready(map, adr, NULL)) |
| return 0; |
| |
| /* |
| @@ -2036,7 +2021,7 @@ static int cfi_amdstd_panic_wait(struct |
| |
| /* wait for the chip to become ready */ |
| for (i = 0; i < jiffies_to_usecs(timeo); i++) { |
| - if (chip_ready(map, adr)) |
| + if (chip_ready(map, adr, NULL)) |
| return 0; |
| |
| udelay(1); |
| @@ -2100,13 +2085,13 @@ retry: |
| map_write(map, datum, adr); |
| |
| for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) { |
| - if (chip_ready(map, adr)) |
| + if (chip_ready(map, adr, NULL)) |
| break; |
| |
| udelay(1); |
| } |
| |
| - if (!chip_good(map, adr, datum)) { |
| + if (!chip_ready(map, adr, &datum)) { |
| /* reset on all failures. */ |
| map_write(map, CMD(0xF0), chip->start); |
| /* FIXME - should have reset delay before continuing */ |
| @@ -2247,6 +2232,7 @@ static int __xipram do_erase_chip(struct |
| DECLARE_WAITQUEUE(wait, current); |
| int ret = 0; |
| int retry_cnt = 0; |
| + map_word datum = map_word_ff(map); |
| |
| adr = cfi->addr_unlock1; |
| |
| @@ -2301,7 +2287,7 @@ static int __xipram do_erase_chip(struct |
| chip->erase_suspended = 0; |
| } |
| |
| - if (chip_good(map, adr, map_word_ff(map))) |
| + if (chip_ready(map, adr, &datum)) |
| break; |
| |
| if (time_after(jiffies, timeo)) { |
| @@ -2343,6 +2329,7 @@ static int __xipram do_erase_oneblock(st |
| DECLARE_WAITQUEUE(wait, current); |
| int ret = 0; |
| int retry_cnt = 0; |
| + map_word datum = map_word_ff(map); |
| |
| adr += chip->start; |
| |
| @@ -2397,7 +2384,7 @@ static int __xipram do_erase_oneblock(st |
| chip->erase_suspended = 0; |
| } |
| |
| - if (chip_good(map, adr, map_word_ff(map))) { |
| + if (chip_ready(map, adr, &datum)) { |
| xip_enable(map, chip, adr); |
| break; |
| } |
| @@ -2612,7 +2599,7 @@ static int __maybe_unused do_ppb_xxlock( |
| */ |
| timeo = jiffies + msecs_to_jiffies(2000); /* 2s max (un)locking */ |
| for (;;) { |
| - if (chip_ready(map, adr)) |
| + if (chip_ready(map, adr, NULL)) |
| break; |
| |
| if (time_after(jiffies, timeo)) { |