From: Tudor Ambarus <[email protected]>

Rename clear_sr_bp()/disable_write_protection() to better indicate
what the function does.

Get rid of MFR handling and implement specific manufacturer
default_init() fixup hooks.

Signed-off-by: Tudor Ambarus <[email protected]>
---
 drivers/mtd/spi-nor/spi-nor.c | 64 +++++++++++++++++++++++++++++--------------
 include/linux/mtd/spi-nor.h   |  6 ++--
 2 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 95ca5dd96403..9b9f9b530207 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -4282,6 +4282,16 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
        return err;
 }
 
+static void atmel_set_default_init(struct spi_nor *nor)
+{
+       nor->disable_write_protection = spi_nor_clear_sr_bp;
+}
+
+static void intel_set_default_init(struct spi_nor *nor)
+{
+       nor->disable_write_protection = spi_nor_clear_sr_bp;
+}
+
 static void macronix_set_default_init(struct spi_nor *nor)
 {
        nor->quad_enable = macronix_quad_enable;
@@ -4303,6 +4313,14 @@ static void spi_nor_mfr_init_params(struct spi_nor *nor,
                                    struct spi_nor_flash_parameter *params)
 {
        switch (JEDEC_MFR(nor->info)) {
+       case SNOR_MFR_ATMEL:
+               atmel_set_default_init(nor);
+               break;
+
+       case SNOR_MFR_INTEL:
+               intel_set_default_init(nor);
+               break;
+
        case SNOR_MFR_MACRONIX:
                macronix_set_default_init(nor);
                break;
@@ -4649,6 +4667,23 @@ static int spi_nor_setup(struct spi_nor *nor,
        return err;
 }
 
+static int spi_nor_disable_write_protection(struct spi_nor *nor)
+{
+       if (!nor->disable_write_protection)
+               return 0;
+
+       /*
+        * In case of the legacy quad enable requirements are set, if the
+        * configuration register Quad Enable bit is one, only the the
+        * Write Status (01h) command with two data bytes may be used to clear
+        * the block protection bits.
+        */
+       if (nor->quad_enable == spansion_quad_enable)
+               nor->disable_write_protection = spi_nor_spansion_clear_sr_bp;
+
+       return nor->disable_write_protection(nor);
+}
+
 static int spi_nor_quad_enable(struct spi_nor *nor)
 {
        if (!nor->quad_enable)
@@ -4665,16 +4700,11 @@ static int spi_nor_init(struct spi_nor *nor)
 {
        int err;
 
-       if (nor->clear_sr_bp) {
-               if (nor->quad_enable == spansion_quad_enable)
-                       nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
-
-               err = nor->clear_sr_bp(nor);
-               if (err) {
-                       dev_err(nor->dev,
-                               "fail to clear block protection bits\n");
-                       return err;
-               }
+       err = spi_nor_disable_write_protection(nor);
+       if (err) {
+               dev_err(nor->dev,
+                       "fail to unlock the flash at init (err = %d)\n", err);
+               return err;
        }
 
        err = spi_nor_quad_enable(nor);
@@ -4797,23 +4827,15 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
        if (info->flags & SPI_S3AN)
                nor->flags |=  SNOR_F_READY_XSR_RDY;
 
-       /*
-        * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
-        * with the software protection bits set.
-        */
-       if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
-           JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
-           JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-           nor->info->flags & SPI_NOR_HAS_LOCK)
-               nor->clear_sr_bp = spi_nor_clear_sr_bp;
-
        /* Kept only for backward compatibility purpose. */
        nor->quad_enable = spansion_quad_enable;
        nor->set_4byte = spansion_set_4byte;
 
        /* Default locking operations. */
-       if (info->flags & SPI_NOR_HAS_LOCK)
+       if (info->flags & SPI_NOR_HAS_LOCK) {
                nor->locking_ops = &stm_locking_ops;
+               nor->disable_write_protection = spi_nor_clear_sr_bp;
+       }
 
        /* Init flash parameters based on flash_info struct and SFDP */
        spi_nor_init_params(nor, &params);
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index bd68ec5a10e7..185ca11bfb63 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -380,8 +380,8 @@ struct flash_info;
  * @quad_enable:       [FLASH-SPECIFIC] enables SPI NOR quad mode
  * @set_4byte:         [FLASH-SPECIFIC] puts the SPI NOR in 4 byte addressing
  *                      mode
- * @clear_sr_bp:       [FLASH-SPECIFIC] clears the Block Protection Bits from
- *                     the SPI NOR Status Register.
+ * @disable_write_protection: [FLASH-SPECIFIC] disable write protection during
+ *                            power-up
  *                     completely locked
  * @priv:              the private data
  */
@@ -423,7 +423,7 @@ struct spi_nor {
        int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
        int (*quad_enable)(struct spi_nor *nor);
        int (*set_4byte)(struct spi_nor *nor, bool enable);
-       int (*clear_sr_bp)(struct spi_nor *nor);
+       int (*disable_write_protection)(struct spi_nor *nor);
 
        const struct spi_nor_locking_ops *locking_ops;
 
-- 
2.9.5

Reply via email to