mtd: spi-nor: move all spansion specifics into spansion.c
authorMichael Walle <michael@walle.cc>
Wed, 23 Feb 2022 13:43:54 +0000 (14:43 +0100)
committerTudor Ambarus <tudor.ambarus@microchip.com>
Fri, 25 Feb 2022 16:12:49 +0000 (18:12 +0200)
The clear status register flags is only available on spansion flashes.
Move all the functions around that into the spanion module.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-by: Pratyush Yadav <p.yadav@ti.com> # on mt35xu512aba, s28hs512t
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20220223134358.1914798-29-michael@walle.cc
drivers/mtd/spi-nor/core.c
drivers/mtd/spi-nor/spansion.c
include/linux/mtd/spi-nor.h

index ac0faed..e2b8b0a 100644 (file)
@@ -554,33 +554,6 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear)
        return ret;
 }
 
-/**
- * spi_nor_clear_sr() - Clear the Status Register.
- * @nor:       pointer to 'struct spi_nor'.
- */
-static void spi_nor_clear_sr(struct spi_nor *nor)
-{
-       int ret;
-
-       if (nor->spimem) {
-               struct spi_mem_op op =
-                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0),
-                                  SPI_MEM_OP_NO_ADDR,
-                                  SPI_MEM_OP_NO_DUMMY,
-                                  SPI_MEM_OP_NO_DATA);
-
-               spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-
-               ret = spi_mem_exec_op(nor->spimem, &op);
-       } else {
-               ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
-                                                      NULL, 0);
-       }
-
-       if (ret)
-               dev_dbg(nor->dev, "error %d clearing SR\n", ret);
-}
-
 /**
  * spi_nor_sr_ready() - Query the Status Register to see if the flash is ready
  * for new commands.
@@ -595,28 +568,6 @@ int spi_nor_sr_ready(struct spi_nor *nor)
        if (ret)
                return ret;
 
-       if (nor->flags & SNOR_F_USE_CLSR &&
-           nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
-               if (nor->bouncebuf[0] & SR_E_ERR)
-                       dev_err(nor->dev, "Erase Error occurred\n");
-               else
-                       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;
-       }
-
        return !(nor->bouncebuf[0] & SR_WIP);
 }
 
index 1a0e721..dbafe97 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "core.h"
 
+#define SPINOR_OP_CLSR         0x30    /* Clear status register 1 */
 #define SPINOR_OP_RD_ANY_REG                   0x65    /* Read any register */
 #define SPINOR_OP_WR_ANY_REG                   0x71    /* Write any register */
 #define SPINOR_REG_CYPRESS_CFR2V               0x00800003
@@ -294,6 +295,72 @@ static const struct flash_info spansion_nor_parts[] = {
        },
 };
 
+/**
+ * spi_nor_clear_sr() - Clear the Status Register.
+ * @nor:       pointer to 'struct spi_nor'.
+ */
+static void spi_nor_clear_sr(struct spi_nor *nor)
+{
+       int ret;
+
+       if (nor->spimem) {
+               struct spi_mem_op op =
+                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0),
+                                  SPI_MEM_OP_NO_ADDR,
+                                  SPI_MEM_OP_NO_DUMMY,
+                                  SPI_MEM_OP_NO_DATA);
+
+               spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+
+               ret = spi_mem_exec_op(nor->spimem, &op);
+       } else {
+               ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
+                                                      NULL, 0);
+       }
+
+       if (ret)
+               dev_dbg(nor->dev, "error %d clearing SR\n", ret);
+}
+
+/**
+ * spi_nor_sr_ready_and_clear() - Query the Status Register to see if the flash
+ * is ready for new commands and clear it if there are any errors.
+ * @nor:       pointer to 'struct spi_nor'.
+ *
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
+ */
+static int spi_nor_sr_ready_and_clear(struct spi_nor *nor)
+{
+       int ret;
+
+       ret = spi_nor_read_sr(nor, nor->bouncebuf);
+       if (ret)
+               return ret;
+
+       if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
+               if (nor->bouncebuf[0] & SR_E_ERR)
+                       dev_err(nor->dev, "Erase Error occurred\n");
+               else
+                       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;
+       }
+
+       return !(nor->bouncebuf[0] & SR_WIP);
+}
+
 static void spansion_nor_late_init(struct spi_nor *nor)
 {
        if (nor->params->size > SZ_16M) {
@@ -302,6 +369,9 @@ static void spansion_nor_late_init(struct spi_nor *nor)
                nor->erase_opcode = SPINOR_OP_SE;
                nor->mtd.erasesize = nor->info->sector_size;
        }
+
+       if (nor->flags & SNOR_F_USE_CLSR)
+               nor->params->ready = spi_nor_sr_ready_and_clear;
 }
 
 static const struct spi_nor_fixups spansion_nor_fixups = {
index 4622251..5e25a7b 100644 (file)
@@ -90,7 +90,6 @@
 
 /* Used for Spansion flashes only. */
 #define SPINOR_OP_BRWR         0x17    /* Bank register write */
-#define SPINOR_OP_CLSR         0x30    /* Clear status register 1 */
 
 /* Used for Micron flashes only. */
 #define SPINOR_OP_RD_EVCR      0x65    /* Read EVCR register */