mtd: cfi_cmdset_0002: Move and rename chip_check/chip_ready/chip_good_for_write
authorTokunori Ikegami <ikegami.t@gmail.com>
Wed, 23 Mar 2022 17:04:55 +0000 (02:04 +0900)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Thu, 28 Apr 2022 08:17:01 +0000 (10:17 +0200)
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
drivers/mtd/chips/cfi_cmdset_0002.c

index a761134..9ccde90 100644 (file)
@@ -802,21 +802,25 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 }
 
 /*
- * 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, struct flchip *chip,
-                              unsigned long addr)
+                              unsigned long addr, map_word *expected)
 {
        struct cfi_private *cfi = map->fldrv_priv;
        map_word d, t;
+       int ret;
 
        if (cfi_use_status_reg(cfi)) {
                map_word ready = CMD(CFI_SR_DRB);
@@ -826,57 +830,20 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
                 */
                cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
                                 cfi->device_type, NULL);
-               d = map_read(map, addr);
+               t = map_read(map, addr);
 
-               return map_word_andequal(map, d, ready, ready);
+               return map_word_andequal(map, t, ready, ready);
        }
 
        d = map_read(map, addr);
        t = map_read(map, addr);
 
-       return 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, struct flchip *chip,
-                             unsigned long addr, map_word expected)
-{
-       struct cfi_private *cfi = map->fldrv_priv;
-       map_word oldd, curd;
-
-       if (cfi_use_status_reg(cfi)) {
-               map_word ready = CMD(CFI_SR_DRB);
-
-               /*
-                * For chips that support status register, check device
-                * ready bit
-                */
-               cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
-                                cfi->device_type, NULL);
-               curd = map_read(map, addr);
-
-               return map_word_andequal(map, curd, ready, ready);
-       }
+       ret = map_word_equal(map, d, t);
 
-       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)
@@ -893,7 +860,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
 
        case FL_STATUS:
                for (;;) {
-                       if (chip_ready(map, chip, adr))
+                       if (chip_ready(map, chip, adr, NULL))
                                break;
 
                        if (time_after(jiffies, timeo)) {
@@ -932,7 +899,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                chip->state = FL_ERASE_SUSPENDING;
                chip->erase_suspended = 1;
                for (;;) {
-                       if (chip_ready(map, chip, adr))
+                       if (chip_ready(map, chip, adr, NULL))
                                break;
 
                        if (time_after(jiffies, timeo)) {
@@ -1463,7 +1430,7 @@ static int do_otp_lock(struct map_info *map, struct flchip *chip, loff_t adr,
        /* wait for chip to become ready */
        timeo = jiffies + msecs_to_jiffies(2);
        for (;;) {
-               if (chip_ready(map, chip, adr))
+               if (chip_ready(map, chip, adr, NULL))
                        break;
 
                if (time_after(jiffies, timeo)) {
@@ -1695,11 +1662,11 @@ static int __xipram do_write_oneword_once(struct map_info *map,
                }
 
                /*
-                * 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, chip, adr, datum)) {
+                   !chip_ready(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 +1674,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
                        break;
                }
 
-               if (chip_good(map, chip, adr, datum)) {
+               if (chip_ready(map, chip, adr, &datum)) {
                        if (cfi_check_err_status(map, chip, adr))
                                ret = -EIO;
                        break;
@@ -1975,18 +1942,18 @@ static int __xipram do_write_buffer_wait(struct map_info *map,
                }
 
                /*
-                * 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, chip, adr, datum)) {
+                   !chip_ready(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_ready(map, chip, adr, &datum)) {
                        if (cfi_check_err_status(map, chip, adr))
                                ret = -EIO;
                        break;
@@ -2195,7 +2162,7 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip,
         * 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, chip, adr))
+       if (chip->state == FL_READY && chip_ready(map, chip, adr, NULL))
                return 0;
 
        /*
@@ -2212,7 +2179,7 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip,
 
                /* wait for the chip to become ready */
                for (i = 0; i < jiffies_to_usecs(timeo); i++) {
-                       if (chip_ready(map, chip, adr))
+                       if (chip_ready(map, chip, adr, NULL))
                                return 0;
 
                        udelay(1);
@@ -2276,13 +2243,13 @@ retry:
        map_write(map, datum, adr);
 
        for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) {
-               if (chip_ready(map, chip, adr))
+               if (chip_ready(map, chip, adr, NULL))
                        break;
 
                udelay(1);
        }
 
-       if (!chip_good(map, chip, adr, datum) ||
+       if (!chip_ready(map, chip, adr, &datum) ||
            cfi_check_err_status(map, chip, adr)) {
                /* reset on all failures. */
                map_write(map, CMD(0xF0), chip->start);
@@ -2424,6 +2391,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
        DECLARE_WAITQUEUE(wait, current);
        int ret;
        int retry_cnt = 0;
+       map_word datum = map_word_ff(map);
 
        adr = cfi->addr_unlock1;
 
@@ -2478,7 +2446,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_ready(map, chip, adr, &datum)) {
                        if (cfi_check_err_status(map, chip, adr))
                                ret = -EIO;
                        break;
@@ -2523,6 +2491,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        DECLARE_WAITQUEUE(wait, current);
        int ret;
        int retry_cnt = 0;
+       map_word datum = map_word_ff(map);
 
        adr += chip->start;
 
@@ -2577,7 +2546,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_ready(map, chip, adr, &datum)) {
                        if (cfi_check_err_status(map, chip, adr))
                                ret = -EIO;
                        break;
@@ -2771,7 +2740,7 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
         */
        timeo = jiffies + msecs_to_jiffies(2000);       /* 2s max (un)locking */
        for (;;) {
-               if (chip_ready(map, chip, adr))
+               if (chip_ready(map, chip, adr, NULL))
                        break;
 
                if (time_after(jiffies, timeo)) {