mtd: spi-nor: Clear WEL bit when erase or program errors occur
authorTudor Ambarus <tudor.ambarus@microchip.com>
Mon, 23 Mar 2020 17:50:40 +0000 (19:50 +0200)
committerTudor Ambarus <tudor.ambarus@microchip.com>
Mon, 23 Mar 2020 17:50:40 +0000 (19:50 +0200)
When an Erase or Program error occurs on a spansion/cypress or a
micron flash, the WEL bit remains set to one and should be cleared
with a WRDI command in order to protect against inadvertent writes
that can possible corrupt the contents of the memory.

Winbond, macronix, gd, etc., do not support the E_ERR and P_ERR bits in the
Status Register and always clear the WEL bit regardless of the outcome
of the erase or page program operation (ex w25q40bw, MX25L25635E).

Issue a WRDI command when erase or page program errors occur.

Reported-by: John Garry <john.garry@huawei.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-by: John Garry <john.garry@huawei.com>
drivers/mtd/spi-nor/core.c

index 877557dbda7f8c91851272772b6fcb1d76b625dd..e0021dd34bfeff11cddeed714bc29b31b7c25608 100644 (file)
@@ -559,6 +559,17 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
                        dev_err(nor->dev, "Programming Error occurred\n");
 
                spi_nor_clear_sr(nor);
+
+               /*
+                * WEL bit remains set to one when an erase or page program
+                * error occurs. Issue a Write Disable command to protect
+                * against inadvertent writes that can possibly corrupt the
+                * contents of the memory.
+                */
+               ret = spi_nor_write_disable(nor);
+               if (ret)
+                       return ret;
+
                return -EIO;
        }
 
@@ -615,6 +626,17 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
                        "Attempted to modify a protected sector.\n");
 
                spi_nor_clear_fsr(nor);
+
+               /*
+                * WEL bit remains set to one when an erase or page program
+                * error occurs. Issue a Write Disable command to protect
+                * against inadvertent writes that can possibly corrupt the
+                * contents of the memory.
+                */
+               ret = spi_nor_write_disable(nor);
+               if (ret)
+                       return ret;
+
                return -EIO;
        }