From: Tudor Ambarus <[email protected]>

The Status Register can be written with one or two bytes.

Merge:
static int write_sr(struct spi_nor *nor, u8 val)
static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
into
static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)

Avoid duplicating code by moving the calls to spi_nor_write_enable() and
spi_nor_wait_till_ready() inside spi_nor_write_sr().

Move the spi_nor_wait_till_ready() together with the spi_nor_ready()
methods to avoid forward declarations.

Signed-off-by: Tudor Ambarus <[email protected]>
---
 drivers/mtd/spi-nor/spi-nor.c | 426 +++++++++++++++++++-----------------------
 1 file changed, 191 insertions(+), 235 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index be5dee622d51..31a4622d1eb9 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -537,25 +537,198 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
        return ret;
 }
 
+static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
+{
+       if (nor->spimem) {
+               struct spi_mem_op op =
+                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 1),
+                                  SPI_MEM_OP_NO_ADDR,
+                                  SPI_MEM_OP_NO_DUMMY,
+                                  SPI_MEM_OP_DATA_IN(1, sr, 1));
+
+               return spi_mem_exec_op(nor->spimem, &op);
+       }
+
+       return nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR, sr, 1);
+}
+
+static int s3an_sr_ready(struct spi_nor *nor)
+{
+       int ret;
+
+       ret = spi_nor_xread_sr(nor, nor->bouncebuf);
+       if (ret < 0) {
+               dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
+               return ret;
+       }
+
+       return !!(nor->bouncebuf[0] & XSR_RDY);
+}
+
+static int spi_nor_clear_sr(struct spi_nor *nor)
+{
+       if (nor->spimem) {
+               struct spi_mem_op op =
+                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 1),
+                                  SPI_MEM_OP_NO_ADDR,
+                                  SPI_MEM_OP_NO_DUMMY,
+                                  SPI_MEM_OP_NO_DATA);
+
+               return spi_mem_exec_op(nor->spimem, &op);
+       }
+
+       return nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
+}
+
+static int spi_nor_sr_ready(struct spi_nor *nor)
+{
+       int ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+
+       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);
+               return -EIO;
+       }
+
+       return !(nor->bouncebuf[0] & SR_WIP);
+}
+
+static int spi_nor_clear_fsr(struct spi_nor *nor)
+{
+       if (nor->spimem) {
+               struct spi_mem_op op =
+                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 1),
+                                  SPI_MEM_OP_NO_ADDR,
+                                  SPI_MEM_OP_NO_DUMMY,
+                                  SPI_MEM_OP_NO_DATA);
+
+               return spi_mem_exec_op(nor->spimem, &op);
+       }
+
+       return nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
+}
+
+static int spi_nor_fsr_ready(struct spi_nor *nor)
+{
+       int ret = spi_nor_read_fsr(nor, &nor->bouncebuf[0]);
+
+       if (ret)
+               return ret;
+
+       if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) {
+               if (nor->bouncebuf[0] & FSR_E_ERR)
+                       dev_err(nor->dev, "Erase operation failed.\n");
+               else
+                       dev_err(nor->dev, "Program operation failed.\n");
+
+               if (nor->bouncebuf[0] & FSR_PT_ERR)
+                       dev_err(nor->dev,
+                               "Attempted to modify a protected sector.\n");
+
+               spi_nor_clear_fsr(nor);
+               return -EIO;
+       }
+
+       return nor->bouncebuf[0] & FSR_READY;
+}
+
+static int spi_nor_ready(struct spi_nor *nor)
+{
+       int sr, fsr;
+
+       if (nor->flags & SNOR_F_READY_XSR_RDY)
+               sr = s3an_sr_ready(nor);
+       else
+               sr = spi_nor_sr_ready(nor);
+       if (sr < 0)
+               return sr;
+       fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
+       if (fsr < 0)
+               return fsr;
+       return sr && fsr;
+}
+
 /*
- * Write status register 1 byte
- * Returns negative if error occurred.
+ * Service routine to read status register until ready, or timeout occurs.
+ * Returns non-zero if error.
+ */
+static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
+                                               unsigned long timeout_jiffies)
+{
+       unsigned long deadline;
+       int timeout = 0, ret;
+
+       deadline = jiffies + timeout_jiffies;
+
+       while (!timeout) {
+               if (time_after_eq(jiffies, deadline))
+                       timeout = 1;
+
+               ret = spi_nor_ready(nor);
+               if (ret < 0)
+                       return ret;
+               if (ret)
+                       return 0;
+
+               cond_resched();
+       }
+
+       dev_err(nor->dev, "flash operation timed out\n");
+
+       return -ETIMEDOUT;
+}
+
+static int spi_nor_wait_till_ready(struct spi_nor *nor)
+{
+       return spi_nor_wait_till_ready_with_timeout(nor,
+                                                   DEFAULT_READY_WAIT_JIFFIES);
+}
+
+/**
+ * spi_nor_write_sr() - Write the Status Register.
+ * @nor:       pointer to 'struct spi_nor'.
+ * @sr:                buffer to write to the Status Register.
+ * @len:       number of bytes to write to the Status Register.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
-static int write_sr(struct spi_nor *nor, u8 val)
+static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
 {
-       nor->bouncebuf[0] = val;
+       int ret;
+
+       ret = spi_nor_write_enable(nor);
+       if (ret)
+               return ret;
+
        if (nor->spimem) {
                struct spi_mem_op op =
                        SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1),
                                   SPI_MEM_OP_NO_ADDR,
                                   SPI_MEM_OP_NO_DUMMY,
-                                  SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+                                  SPI_MEM_OP_DATA_OUT(len, sr, 1));
 
-               return spi_mem_exec_op(nor->spimem, &op);
+               ret = spi_mem_exec_op(nor->spimem, &op);
+       } else {
+               ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
+                                                    sr, len);
        }
 
-       return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
-                                             nor->bouncebuf, 1);
+       if (ret) {
+               dev_err(nor->dev, "error while writing Status Register\n");
+               return ret;
+       }
+
+       ret = spi_nor_wait_till_ready(nor);
+
+       return ret;
 }
 
 static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
@@ -741,161 +914,6 @@ static int winbond_set_4byte(struct spi_nor *nor, bool 
enable)
        return ret;
 }
 
-static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
-{
-       if (nor->spimem) {
-               struct spi_mem_op op =
-                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 1),
-                                  SPI_MEM_OP_NO_ADDR,
-                                  SPI_MEM_OP_NO_DUMMY,
-                                  SPI_MEM_OP_DATA_IN(1, sr, 1));
-
-               return spi_mem_exec_op(nor->spimem, &op);
-       }
-
-       return nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR, sr, 1);
-}
-
-static int s3an_sr_ready(struct spi_nor *nor)
-{
-       int ret;
-
-       ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-       if (ret < 0) {
-               dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
-               return ret;
-       }
-
-       return !!(nor->bouncebuf[0] & XSR_RDY);
-}
-
-static int spi_nor_clear_sr(struct spi_nor *nor)
-{
-       if (nor->spimem) {
-               struct spi_mem_op op =
-                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 1),
-                                  SPI_MEM_OP_NO_ADDR,
-                                  SPI_MEM_OP_NO_DUMMY,
-                                  SPI_MEM_OP_NO_DATA);
-
-               return spi_mem_exec_op(nor->spimem, &op);
-       }
-
-       return nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
-}
-
-static int spi_nor_sr_ready(struct spi_nor *nor)
-{
-       int ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
-
-       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);
-               return -EIO;
-       }
-
-       return !(nor->bouncebuf[0] & SR_WIP);
-}
-
-static int spi_nor_clear_fsr(struct spi_nor *nor)
-{
-       if (nor->spimem) {
-               struct spi_mem_op op =
-                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 1),
-                                  SPI_MEM_OP_NO_ADDR,
-                                  SPI_MEM_OP_NO_DUMMY,
-                                  SPI_MEM_OP_NO_DATA);
-
-               return spi_mem_exec_op(nor->spimem, &op);
-       }
-
-       return nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
-}
-
-static int spi_nor_fsr_ready(struct spi_nor *nor)
-{
-       int ret = spi_nor_read_fsr(nor, &nor->bouncebuf[0]);
-
-       if (ret)
-               return ret;
-
-       if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) {
-               if (nor->bouncebuf[0] & FSR_E_ERR)
-                       dev_err(nor->dev, "Erase operation failed.\n");
-               else
-                       dev_err(nor->dev, "Program operation failed.\n");
-
-               if (nor->bouncebuf[0] & FSR_PT_ERR)
-                       dev_err(nor->dev,
-                               "Attempted to modify a protected sector.\n");
-
-               spi_nor_clear_fsr(nor);
-               return -EIO;
-       }
-
-       return nor->bouncebuf[0] & FSR_READY;
-}
-
-static int spi_nor_ready(struct spi_nor *nor)
-{
-       int sr, fsr;
-
-       if (nor->flags & SNOR_F_READY_XSR_RDY)
-               sr = s3an_sr_ready(nor);
-       else
-               sr = spi_nor_sr_ready(nor);
-       if (sr < 0)
-               return sr;
-       fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
-       if (fsr < 0)
-               return fsr;
-       return sr && fsr;
-}
-
-/*
- * Service routine to read status register until ready, or timeout occurs.
- * Returns non-zero if error.
- */
-static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
-                                               unsigned long timeout_jiffies)
-{
-       unsigned long deadline;
-       int timeout = 0, ret;
-
-       deadline = jiffies + timeout_jiffies;
-
-       while (!timeout) {
-               if (time_after_eq(jiffies, deadline))
-                       timeout = 1;
-
-               ret = spi_nor_ready(nor);
-               if (ret < 0)
-                       return ret;
-               if (ret)
-                       return 0;
-
-               cond_resched();
-       }
-
-       dev_err(nor->dev, "flash operation timed out\n");
-
-       return -ETIMEDOUT;
-}
-
-static int spi_nor_wait_till_ready(struct spi_nor *nor)
-{
-       return spi_nor_wait_till_ready_with_timeout(nor,
-                                                   DEFAULT_READY_WAIT_JIFFIES);
-}
-
 /*
  * Erase the whole flash memory
  *
@@ -1375,15 +1393,9 @@ static int write_sr_and_check(struct spi_nor *nor, u8 
status_new, u8 mask)
 {
        int ret;
 
-       ret = spi_nor_write_enable(nor);
-       if (ret)
-               return ret;
-
-       ret = write_sr(nor, status_new);
-       if (ret)
-               return ret;
+       nor->bouncebuf[0] = status_new;
 
-       ret = spi_nor_wait_till_ready(nor);
+       ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
        if (ret)
                return ret;
 
@@ -1713,49 +1725,6 @@ static int spi_nor_is_locked(struct mtd_info *mtd, 
loff_t ofs, uint64_t len)
        return ret;
 }
 
-/*
- * Write status Register and configuration register with 2 bytes
- * The first byte will be written to the status register, while the
- * second byte will be written to the configuration register.
- * Return negative if error occurred.
- */
-static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
-{
-       int ret;
-
-       ret = spi_nor_write_enable(nor);
-       if (ret)
-               return ret;
-
-       if (nor->spimem) {
-               struct spi_mem_op op =
-                       SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1),
-                                  SPI_MEM_OP_NO_ADDR,
-                                  SPI_MEM_OP_NO_DUMMY,
-                                  SPI_MEM_OP_DATA_OUT(2, sr_cr, 1));
-
-               ret = spi_mem_exec_op(nor->spimem, &op);
-       } else {
-               ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
-                                                    sr_cr, 2);
-       }
-
-       if (ret < 0) {
-               dev_err(nor->dev,
-                       "error while writing configuration register\n");
-               return -EINVAL;
-       }
-
-       ret = spi_nor_wait_till_ready(nor);
-       if (ret) {
-               dev_err(nor->dev,
-                       "timeout while writing configuration register\n");
-               return ret;
-       }
-
-       return 0;
-}
-
 /**
  * macronix_quad_enable() - set QE bit in Status Register.
  * @nor:       pointer to a 'struct spi_nor'
@@ -1777,13 +1746,9 @@ static int macronix_quad_enable(struct spi_nor *nor)
        if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
                return 0;
 
-       ret = spi_nor_write_enable(nor);
-       if (ret)
-               return ret;
-
-       write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
+       nor->bouncebuf[0] |= SR_QUAD_EN_MX;
 
-       ret = spi_nor_wait_till_ready(nor);
+       ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
        if (ret)
                return ret;
 
@@ -1830,7 +1795,7 @@ static int spansion_quad_enable(struct spi_nor *nor)
 
        sr_cr[0] = 0;
        sr_cr[1] = CR_QUAD_EN_SPAN;
-       ret = write_sr_cr(nor, sr_cr);
+       ret = spi_nor_write_sr(nor, sr_cr, 2);
        if (ret)
                return ret;
 
@@ -1872,7 +1837,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor 
*nor)
 
        sr_cr[1] = CR_QUAD_EN_SPAN;
 
-       return write_sr_cr(nor, sr_cr);
+       return spi_nor_write_sr(nor, sr_cr, 2);
 }
 
 /**
@@ -1908,7 +1873,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor 
*nor)
        if (ret)
                return ret;
 
-       ret = write_sr_cr(nor, sr_cr);
+       ret = spi_nor_write_sr(nor, sr_cr, 2);
        if (ret)
                return ret;
 
@@ -2026,19 +1991,10 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
        if (ret)
                return ret;
 
-       ret = spi_nor_write_enable(nor);
-       if (ret)
-               return ret;
+       nor->bouncebuf[0] &= mask;
 
-       ret = write_sr(nor, nor->bouncebuf[0] & ~mask);
-       if (ret) {
-               dev_err(nor->dev, "write to status register failed\n");
-               return ret;
-       }
+       ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
 
-       ret = spi_nor_wait_till_ready(nor);
-       if (ret)
-               dev_err(nor->dev, "timeout while writing status register\n");
        return ret;
 }
 
@@ -2077,7 +2033,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor 
*nor)
 
                sr_cr[0] &= ~mask;
 
-               ret = write_sr_cr(nor, sr_cr);
+               ret = spi_nor_write_sr(nor, sr_cr, 2);
                if (ret)
                        dev_err(nor->dev, "16-bit write register failed\n");
                return ret;
-- 
2.9.5

Reply via email to