linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods
@ 2019-10-29 11:16 Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods Tudor.Ambarus
                   ` (31 more replies)
  0 siblings, 32 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Patches 1 - 20 are just clean up patches for the Flash Register
Operations.

Patches 21 - 32 deal with the Quad Enable and the (un)lock methods.
Fixed the clearing of QE bit on (un)lock() operations. Reworked the
Quad Enable methods and the disabling of the block write protection
at power-up.

Tested on s25fl116k and w25q128jv-q.

The patch set can be tested using mtd-utils:
1/ do a read-erase-write-read-back test immediately after boot, to check
the spi_nor_unlock_all() method. The focus is on the erase/write
methods, we want to see if the flash is unlocked at power-up.
        mtd_debug read /dev/mtd-yours offset size read-file
        hexdump read-file
        mtd_debug erase /dev/mtd-yours offset size
        dd if=/dev/urandom of=write-file bs=please-choose count=please-choose
        mtd_debug write /dev/mtd-yours offset write-file-size write-file
        mtd_debug read /dev/mtd-yours offset write-file-size read-file
        sha1sum read-file write-file
2/ lock flash then try to erase/write it, to see if the lock works
        flash_lock /dev/mtd-yours offset block-count
        Do the read-erase-write-read-back test from 1/. The contents of
        flash should not change in the erase and write steps.
3/ unlock flash and do the read-erase-write-read-back from 1/. The value of the
   QEE should not change and you should be able to erase and write the flash.
   Test 1/ should be successful.

v3: split patches, update retlen handling in sst_write.

v2:
- Introduce spi_nor_write_16bit_cr_and_check() as per Vignesh's suggestion. The
  Configuration Register contains bits that can be updated in future: FREEZE,
  CMP. Provide a generic method that allows updating all bits of the
  Configuration Register.
- Fix SNOR_F_NO_READ_CR case in
  "mtd: spi-nor: Rework the disabling of block write protection". When the flash
  doesn't support the CR Read command, we make an assumption about the value of
  the QE bit. In spi_nor_init(), call spi_nor_quad_enable() first, then
  spi_nor_unlock_all(), so that at the spi_nor_unlock_all() time we can be sure
  the QE bit has value one, because of the previous call to spi_nor_quad_enable().
- Fix if statement in spi_nor_write_sr_and_check():
  if (nor->flags & SNOR_F_HAS_16BIT_SR)
- Fix documentation warnings.
- New patch: "mtd: spi-nor: Check all the bits written, not just the BP ones".
- Drop Global Unlock patches, will send them in a different patch set.

Tudor Ambarus (32):
  mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods
  mtd: spi-nor: Drop duplicated new line
  mtd: spi-nor: Group all Reg Ops to avoid forward declarations
  mtd: spi-nor: Stop compare with negative in Reg Ops methods
  mtd: spi-nor: Drop explicit cast to int to already int value
  mtd: spi-nor: Use dev_err() instead of pr_err()
  mtd: spi-nor: Don't overwrite errno from Reg Ops
  mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr()
  mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr()
  mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr()
  mtd: spi-nor: Drop redundant error reports in Reg Ops callers
  mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr()
  mtd: spi-nor: Print error messages inside Reg Ops methods
  mtd: spi-nor: Fix retlen handling in sst_write()
  mtd: spi-nor: Check for errors after each Register Operation
  mtd: spi-nor: Rename label as it is no longer generic
  mtd: spi-nor: Move the WE and wait calls inside Write SR methods
  mtd: spi-nor: Constify data to write to the Status Register
  mtd: spi-nor: Merge spi_nor_write_sr() and spi_nor_write_sr_cr()
  mtd: spi-nor: Describe all the Reg Ops
  mtd: spi-nor: Drop spansion_quad_enable()
  mtd: spi-nor: Fix errno on Quad Enable methods
  mtd: spi-nor: Check all the bits written, not just the BP ones
  mtd: spi-nor: Print error message when the read back test fails
  mtd: spi-nor: Fix clearing of QE bit on lock()/unlock()
  mtd: spi-nor: Extend the QE Read Back test to the entire SR byte
  mtd: spi-nor: Extend the QE Read Back test to both SR1 and SR2
  mtd: spi-nor: Rename CR_QUAD_EN_SPAN to SR2_QUAD_EN_BIT1
  mtd: spi-nor: Merge spansion Quad Enable methods
  mtd: spi-nor: Rename macronix_quad_enable to
    spi_nor_sr1_bit6_quad_enable
  mtd: spi-nor: Prepend "spi_nor_" to "sr2_bit7_quad_enable"
  mtd: spi-nor: Rework the disabling of block write protection

 drivers/mtd/spi-nor/spi-nor.c | 1645 +++++++++++++++++++++++------------------
 include/linux/mtd/spi-nor.h   |   12 +-
 2 files changed, 924 insertions(+), 733 deletions(-)

-- 
2.9.5


^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
@ 2019-10-29 11:16 ` Tudor.Ambarus
  2019-10-31 10:34   ` Boris Brezillon
  2019-11-02 10:34   ` Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line Tudor.Ambarus
                   ` (30 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

All the core functions should begin with "spi_nor_".

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 110 +++++++++++++++++++++---------------------
 1 file changed, 56 insertions(+), 54 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index a6f9f833c862..aca8245fb6c4 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -393,7 +393,7 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
  * Return the status register value.
  * Returns negative if error occurred.
  */
-static int read_sr(struct spi_nor *nor)
+static int spi_nor_read_sr(struct spi_nor *nor)
 {
 	int ret;
 
@@ -423,7 +423,7 @@ static int read_sr(struct spi_nor *nor)
  * Return the status register value.
  * Returns negative if error occurred.
  */
-static int read_fsr(struct spi_nor *nor)
+static int spi_nor_read_fsr(struct spi_nor *nor)
 {
 	int ret;
 
@@ -453,7 +453,7 @@ static int read_fsr(struct spi_nor *nor)
  * location. Return the configuration register value.
  * Returns negative if error occurred.
  */
-static int read_cr(struct spi_nor *nor)
+static int spi_nor_read_cr(struct spi_nor *nor)
 {
 	int ret;
 
@@ -482,7 +482,7 @@ static int read_cr(struct spi_nor *nor)
  * Write status register 1 byte
  * Returns negative if error occurred.
  */
-static int write_sr(struct spi_nor *nor, u8 val)
+static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
 {
 	nor->bouncebuf[0] = val;
 	if (nor->spimem) {
@@ -503,7 +503,7 @@ static int write_sr(struct spi_nor *nor, u8 val)
  * Set write enable latch with Write Enable command.
  * Returns negative if error occurred.
  */
-static int write_enable(struct spi_nor *nor)
+static int spi_nor_write_enable(struct spi_nor *nor)
 {
 	if (nor->spimem) {
 		struct spi_mem_op op =
@@ -521,7 +521,7 @@ static int write_enable(struct spi_nor *nor)
 /*
  * Send write disable instruction to the chip.
  */
-static int write_disable(struct spi_nor *nor)
+static int spi_nor_write_disable(struct spi_nor *nor)
 {
 	if (nor->spimem) {
 		struct spi_mem_op op =
@@ -644,9 +644,9 @@ static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
 {
 	int ret;
 
-	write_enable(nor);
+	spi_nor_write_enable(nor);
 	ret = macronix_set_4byte(nor, enable);
-	write_disable(nor);
+	spi_nor_write_disable(nor);
 
 	return ret;
 }
@@ -700,9 +700,9 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable)
 	 * Register to be set to 1, so all 3-byte-address reads come from the
 	 * second 16M. We must clear the register to enable normal behavior.
 	 */
-	write_enable(nor);
+	spi_nor_write_enable(nor);
 	ret = spi_nor_write_ear(nor, 0);
-	write_disable(nor);
+	spi_nor_write_disable(nor);
 
 	return ret;
 }
@@ -752,7 +752,7 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
 
 static int spi_nor_sr_ready(struct spi_nor *nor)
 {
-	int sr = read_sr(nor);
+	int sr = spi_nor_read_sr(nor);
 	if (sr < 0)
 		return sr;
 
@@ -786,7 +786,7 @@ static int spi_nor_clear_fsr(struct spi_nor *nor)
 
 static int spi_nor_fsr_ready(struct spi_nor *nor)
 {
-	int fsr = read_fsr(nor);
+	int fsr = spi_nor_read_fsr(nor);
 	if (fsr < 0)
 		return fsr;
 
@@ -864,7 +864,7 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
  *
  * Returns 0 if successful, non-zero otherwise.
  */
-static int erase_chip(struct spi_nor *nor)
+static int spi_nor_erase_chip(struct spi_nor *nor)
 {
 	dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10));
 
@@ -1215,7 +1215,7 @@ static int spi_nor_erase_multi_sectors(struct spi_nor *nor, u64 addr, u32 len)
 	list_for_each_entry_safe(cmd, next, &erase_list, list) {
 		nor->erase_opcode = cmd->opcode;
 		while (cmd->count) {
-			write_enable(nor);
+			spi_nor_write_enable(nor);
 
 			ret = spi_nor_erase_sector(nor, addr);
 			if (ret)
@@ -1270,9 +1270,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
 		unsigned long timeout;
 
-		write_enable(nor);
+		spi_nor_write_enable(nor);
 
-		if (erase_chip(nor)) {
+		if (spi_nor_erase_chip(nor)) {
 			ret = -EIO;
 			goto erase_err;
 		}
@@ -1298,7 +1298,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	/* "sector"-at-a-time erase */
 	} else if (spi_nor_has_uniform_erase(nor)) {
 		while (len) {
-			write_enable(nor);
+			spi_nor_write_enable(nor);
 
 			ret = spi_nor_erase_sector(nor, addr);
 			if (ret)
@@ -1319,7 +1319,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 			goto erase_err;
 	}
 
-	write_disable(nor);
+	spi_nor_write_disable(nor);
 
 erase_err:
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
@@ -1328,12 +1328,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 /* Write status register and ensure bits in mask match written values */
-static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
+static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
+				      u8 mask)
 {
 	int ret;
 
-	write_enable(nor);
-	ret = write_sr(nor, status_new);
+	spi_nor_write_enable(nor);
+	ret = spi_nor_write_sr(nor, status_new);
 	if (ret)
 		return ret;
 
@@ -1341,7 +1342,7 @@ static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
 	if (ret)
 		return ret;
 
-	ret = read_sr(nor);
+	ret = spi_nor_read_sr(nor);
 	if (ret < 0)
 		return ret;
 
@@ -1447,7 +1448,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
 	bool use_top;
 
-	status_old = read_sr(nor);
+	status_old = spi_nor_read_sr(nor);
 	if (status_old < 0)
 		return status_old;
 
@@ -1509,7 +1510,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	if ((status_new & mask) < (status_old & mask))
 		return -EINVAL;
 
-	return write_sr_and_check(nor, status_new, mask);
+	return spi_nor_write_sr_and_check(nor, status_new, mask);
 }
 
 /*
@@ -1527,7 +1528,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
 	bool use_top;
 
-	status_old = read_sr(nor);
+	status_old = spi_nor_read_sr(nor);
 	if (status_old < 0)
 		return status_old;
 
@@ -1592,7 +1593,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	if ((status_new & mask) > (status_old & mask))
 		return -EINVAL;
 
-	return write_sr_and_check(nor, status_new, mask);
+	return spi_nor_write_sr_and_check(nor, status_new, mask);
 }
 
 /*
@@ -1606,7 +1607,7 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	int status;
 
-	status = read_sr(nor);
+	status = spi_nor_read_sr(nor);
 	if (status < 0)
 		return status;
 
@@ -1670,11 +1671,11 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
  * 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)
+static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
 {
 	int ret;
 
-	write_enable(nor);
+	spi_nor_write_enable(nor);
 
 	if (nor->spimem) {
 		struct spi_mem_op op =
@@ -1719,21 +1720,21 @@ static int macronix_quad_enable(struct spi_nor *nor)
 {
 	int ret, val;
 
-	val = read_sr(nor);
+	val = spi_nor_read_sr(nor);
 	if (val < 0)
 		return val;
 	if (val & SR_QUAD_EN_MX)
 		return 0;
 
-	write_enable(nor);
+	spi_nor_write_enable(nor);
 
-	write_sr(nor, val | SR_QUAD_EN_MX);
+	spi_nor_write_sr(nor, val | SR_QUAD_EN_MX);
 
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
 		return ret;
 
-	ret = read_sr(nor);
+	ret = spi_nor_read_sr(nor);
 	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
 		dev_err(nor->dev, "Macronix Quad bit not set\n");
 		return -EINVAL;
@@ -1758,7 +1759,8 @@ static int macronix_quad_enable(struct spi_nor *nor)
  * some very old and few memories don't support this instruction. If a pull-up
  * resistor is present on the MISO/IO1 line, we might still be able to pass the
  * "read back" test because the QSPI memory doesn't recognize the command,
- * so leaves the MISO/IO1 line state unchanged, hence read_cr() returns 0xFF.
+ * so leaves the MISO/IO1 line state unchanged, hence spi_nor_read_cr() returns
+ * 0xFF.
  *
  * bit 1 of the Configuration Register is the QE bit for Spansion like QSPI
  * memories.
@@ -1772,12 +1774,12 @@ 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_cr(nor, sr_cr);
 	if (ret)
 		return ret;
 
 	/* read back and check it */
-	ret = read_cr(nor);
+	ret = spi_nor_read_cr(nor);
 	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
 		dev_err(nor->dev, "Spansion Quad bit not set\n");
 		return -EINVAL;
@@ -1805,7 +1807,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 	int ret;
 
 	/* Keep the current value of the Status Register. */
-	ret = read_sr(nor);
+	ret = spi_nor_read_sr(nor);
 	if (ret < 0) {
 		dev_err(nor->dev, "error while reading status register\n");
 		return -EINVAL;
@@ -1813,7 +1815,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 	sr_cr[0] = ret;
 	sr_cr[1] = CR_QUAD_EN_SPAN;
 
-	return write_sr_cr(nor, sr_cr);
+	return spi_nor_write_sr_cr(nor, sr_cr);
 }
 
 /**
@@ -1836,7 +1838,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	int ret;
 
 	/* Check current Quad Enable bit value. */
-	ret = read_cr(nor);
+	ret = spi_nor_read_cr(nor);
 	if (ret < 0) {
 		dev_err(dev, "error while reading configuration register\n");
 		return -EINVAL;
@@ -1848,19 +1850,19 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	sr_cr[1] = ret | CR_QUAD_EN_SPAN;
 
 	/* Keep the current value of the Status Register. */
-	ret = read_sr(nor);
+	ret = spi_nor_read_sr(nor);
 	if (ret < 0) {
 		dev_err(dev, "error while reading status register\n");
 		return -EINVAL;
 	}
 	sr_cr[0] = ret;
 
-	ret = write_sr_cr(nor, sr_cr);
+	ret = spi_nor_write_sr_cr(nor, sr_cr);
 	if (ret)
 		return ret;
 
 	/* Read back and check it. */
-	ret = read_cr(nor);
+	ret = spi_nor_read_cr(nor);
 	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
 		dev_err(nor->dev, "Spansion Quad bit not set\n");
 		return -EINVAL;
@@ -1926,7 +1928,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	/* Update the Quad Enable bit. */
 	*sr2 |= SR2_QUAD_EN_BIT7;
 
-	write_enable(nor);
+	spi_nor_write_enable(nor);
 
 	ret = spi_nor_write_sr2(nor, sr2);
 	if (ret < 0) {
@@ -1964,15 +1966,15 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 	int ret;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 
-	ret = read_sr(nor);
+	ret = spi_nor_read_sr(nor);
 	if (ret < 0) {
 		dev_err(nor->dev, "error while reading status register\n");
 		return ret;
 	}
 
-	write_enable(nor);
+	spi_nor_write_enable(nor);
 
-	ret = write_sr(nor, ret & ~mask);
+	ret = spi_nor_write_sr(nor, ret & ~mask);
 	if (ret) {
 		dev_err(nor->dev, "write to status register failed\n");
 		return ret;
@@ -2004,7 +2006,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	u8 *sr_cr =  nor->bouncebuf;
 
 	/* Check current Quad Enable bit value. */
-	ret = read_cr(nor);
+	ret = spi_nor_read_cr(nor);
 	if (ret < 0) {
 		dev_err(nor->dev,
 			"error while reading configuration register\n");
@@ -2018,7 +2020,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	if (ret & CR_QUAD_EN_SPAN) {
 		sr_cr[1] = ret;
 
-		ret = read_sr(nor);
+		ret = spi_nor_read_sr(nor);
 		if (ret < 0) {
 			dev_err(nor->dev,
 				"error while reading status register\n");
@@ -2026,7 +2028,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 		}
 		sr_cr[0] = ret & ~mask;
 
-		ret = write_sr_cr(nor, sr_cr);
+		ret = spi_nor_write_sr_cr(nor, sr_cr);
 		if (ret)
 			dev_err(nor->dev, "16-bit write register failed\n");
 		return ret;
@@ -2602,7 +2604,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	if (ret)
 		return ret;
 
-	write_enable(nor);
+	spi_nor_write_enable(nor);
 
 	nor->sst_write_second = false;
 
@@ -2641,14 +2643,14 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	}
 	nor->sst_write_second = false;
 
-	write_disable(nor);
+	spi_nor_write_disable(nor);
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
 		goto sst_write_err;
 
 	/* Write out trailing byte if it exists. */
 	if (actual != len) {
-		write_enable(nor);
+		spi_nor_write_enable(nor);
 
 		nor->program_opcode = SPINOR_OP_BP;
 		ret = spi_nor_write_data(nor, to, 1, buf + actual);
@@ -2659,7 +2661,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
 			goto sst_write_err;
-		write_disable(nor);
+		spi_nor_write_disable(nor);
 		actual += 1;
 	}
 sst_write_err:
@@ -2711,7 +2713,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 		addr = spi_nor_convert_addr(nor, addr);
 
-		write_enable(nor);
+		spi_nor_write_enable(nor);
 		ret = spi_nor_write_data(nor, addr, page_remain, buf + i);
 		if (ret < 0)
 			goto write_err;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods Tudor.Ambarus
@ 2019-10-29 11:16 ` Tudor.Ambarus
  2019-10-31 10:34   ` Boris Brezillon
  2019-11-02 10:34   ` Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations Tudor.Ambarus
                   ` (29 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Two new lines, one after another, drop one.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index aca8245fb6c4..6e82df577eed 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -541,7 +541,6 @@ static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
 	return mtd->priv;
 }
 
-
 static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
 {
 	size_t i;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line Tudor.Ambarus
@ 2019-10-29 11:16 ` Tudor.Ambarus
  2019-10-31 10:35   ` Boris Brezillon
  2019-11-02 10:35   ` Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods Tudor.Ambarus
                   ` (28 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Group all register methods up in the file, to avoid forward
declarations.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 426 +++++++++++++++++++++---------------------
 1 file changed, 213 insertions(+), 213 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 6e82df577eed..24378d65fa2e 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -389,6 +389,43 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
 }
 
 /*
+ * Set write enable latch with Write Enable command.
+ * Returns negative if error occurred.
+ */
+static int spi_nor_write_enable(struct spi_nor *nor)
+{
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 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_WREN, NULL, 0);
+}
+
+/*
+ * Send write disable instruction to the chip.
+ */
+static int spi_nor_write_disable(struct spi_nor *nor)
+{
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 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_WRDI, NULL, 0);
+}
+
+/*
  * Read the status register, returning its value in the location
  * Return the status register value.
  * Returns negative if error occurred.
@@ -499,126 +536,6 @@ static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
 					      nor->bouncebuf, 1);
 }
 
-/*
- * Set write enable latch with Write Enable command.
- * Returns negative if error occurred.
- */
-static int spi_nor_write_enable(struct spi_nor *nor)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 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_WREN, NULL, 0);
-}
-
-/*
- * Send write disable instruction to the chip.
- */
-static int spi_nor_write_disable(struct spi_nor *nor)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 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_WRDI, NULL, 0);
-}
-
-static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
-{
-	return mtd->priv;
-}
-
-static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
-{
-	size_t i;
-
-	for (i = 0; i < size; i++)
-		if (table[i][0] == opcode)
-			return table[i][1];
-
-	/* No conversion found, keep input op code. */
-	return opcode;
-}
-
-static u8 spi_nor_convert_3to4_read(u8 opcode)
-{
-	static const u8 spi_nor_3to4_read[][2] = {
-		{ SPINOR_OP_READ,	SPINOR_OP_READ_4B },
-		{ SPINOR_OP_READ_FAST,	SPINOR_OP_READ_FAST_4B },
-		{ SPINOR_OP_READ_1_1_2,	SPINOR_OP_READ_1_1_2_4B },
-		{ SPINOR_OP_READ_1_2_2,	SPINOR_OP_READ_1_2_2_4B },
-		{ SPINOR_OP_READ_1_1_4,	SPINOR_OP_READ_1_1_4_4B },
-		{ SPINOR_OP_READ_1_4_4,	SPINOR_OP_READ_1_4_4_4B },
-		{ SPINOR_OP_READ_1_1_8,	SPINOR_OP_READ_1_1_8_4B },
-		{ SPINOR_OP_READ_1_8_8,	SPINOR_OP_READ_1_8_8_4B },
-
-		{ SPINOR_OP_READ_1_1_1_DTR,	SPINOR_OP_READ_1_1_1_DTR_4B },
-		{ SPINOR_OP_READ_1_2_2_DTR,	SPINOR_OP_READ_1_2_2_DTR_4B },
-		{ SPINOR_OP_READ_1_4_4_DTR,	SPINOR_OP_READ_1_4_4_DTR_4B },
-	};
-
-	return spi_nor_convert_opcode(opcode, spi_nor_3to4_read,
-				      ARRAY_SIZE(spi_nor_3to4_read));
-}
-
-static u8 spi_nor_convert_3to4_program(u8 opcode)
-{
-	static const u8 spi_nor_3to4_program[][2] = {
-		{ SPINOR_OP_PP,		SPINOR_OP_PP_4B },
-		{ SPINOR_OP_PP_1_1_4,	SPINOR_OP_PP_1_1_4_4B },
-		{ SPINOR_OP_PP_1_4_4,	SPINOR_OP_PP_1_4_4_4B },
-		{ SPINOR_OP_PP_1_1_8,	SPINOR_OP_PP_1_1_8_4B },
-		{ SPINOR_OP_PP_1_8_8,	SPINOR_OP_PP_1_8_8_4B },
-	};
-
-	return spi_nor_convert_opcode(opcode, spi_nor_3to4_program,
-				      ARRAY_SIZE(spi_nor_3to4_program));
-}
-
-static u8 spi_nor_convert_3to4_erase(u8 opcode)
-{
-	static const u8 spi_nor_3to4_erase[][2] = {
-		{ SPINOR_OP_BE_4K,	SPINOR_OP_BE_4K_4B },
-		{ SPINOR_OP_BE_32K,	SPINOR_OP_BE_32K_4B },
-		{ SPINOR_OP_SE,		SPINOR_OP_SE_4B },
-	};
-
-	return spi_nor_convert_opcode(opcode, spi_nor_3to4_erase,
-				      ARRAY_SIZE(spi_nor_3to4_erase));
-}
-
-static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
-{
-	nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
-	nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode);
-	nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
-
-	if (!spi_nor_has_uniform_erase(nor)) {
-		struct spi_nor_erase_map *map = &nor->params.erase_map;
-		struct spi_nor_erase_type *erase;
-		int i;
-
-		for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
-			erase = &map->erase_type[i];
-			erase->opcode =
-				spi_nor_convert_3to4_erase(erase->opcode);
-		}
-	}
-}
-
 static int macronix_set_4byte(struct spi_nor *nor, bool enable)
 {
 	if (nor->spimem) {
@@ -859,6 +776,99 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
 }
 
 /*
+ * 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 spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
+{
+	int ret;
+
+	spi_nor_write_enable(nor);
+
+	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;
+}
+
+/* Write status register and ensure bits in mask match written values */
+static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
+				      u8 mask)
+{
+	int ret;
+
+	spi_nor_write_enable(nor);
+	ret = spi_nor_write_sr(nor, status_new);
+	if (ret)
+		return ret;
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+
+	ret = spi_nor_read_sr(nor);
+	if (ret < 0)
+		return ret;
+
+	return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
+}
+
+static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
+{
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR2, 1),
+				   SPI_MEM_OP_NO_ADDR,
+				   SPI_MEM_OP_NO_DUMMY,
+				   SPI_MEM_OP_DATA_OUT(1, sr2, 1));
+
+		return spi_mem_exec_op(nor->spimem, &op);
+	}
+
+	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
+}
+
+static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
+{
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2, 1),
+				   SPI_MEM_OP_NO_ADDR,
+				   SPI_MEM_OP_NO_DUMMY,
+				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
+
+		return spi_mem_exec_op(nor->spimem, &op);
+	}
+
+	return nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
+}
+
+/*
  * Erase the whole flash memory
  *
  * Returns 0 if successful, non-zero otherwise.
@@ -881,6 +891,89 @@ static int spi_nor_erase_chip(struct spi_nor *nor)
 					      NULL, 0);
 }
 
+static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
+{
+	return mtd->priv;
+}
+
+static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
+{
+	size_t i;
+
+	for (i = 0; i < size; i++)
+		if (table[i][0] == opcode)
+			return table[i][1];
+
+	/* No conversion found, keep input op code. */
+	return opcode;
+}
+
+static u8 spi_nor_convert_3to4_read(u8 opcode)
+{
+	static const u8 spi_nor_3to4_read[][2] = {
+		{ SPINOR_OP_READ,	SPINOR_OP_READ_4B },
+		{ SPINOR_OP_READ_FAST,	SPINOR_OP_READ_FAST_4B },
+		{ SPINOR_OP_READ_1_1_2,	SPINOR_OP_READ_1_1_2_4B },
+		{ SPINOR_OP_READ_1_2_2,	SPINOR_OP_READ_1_2_2_4B },
+		{ SPINOR_OP_READ_1_1_4,	SPINOR_OP_READ_1_1_4_4B },
+		{ SPINOR_OP_READ_1_4_4,	SPINOR_OP_READ_1_4_4_4B },
+		{ SPINOR_OP_READ_1_1_8,	SPINOR_OP_READ_1_1_8_4B },
+		{ SPINOR_OP_READ_1_8_8,	SPINOR_OP_READ_1_8_8_4B },
+
+		{ SPINOR_OP_READ_1_1_1_DTR,	SPINOR_OP_READ_1_1_1_DTR_4B },
+		{ SPINOR_OP_READ_1_2_2_DTR,	SPINOR_OP_READ_1_2_2_DTR_4B },
+		{ SPINOR_OP_READ_1_4_4_DTR,	SPINOR_OP_READ_1_4_4_DTR_4B },
+	};
+
+	return spi_nor_convert_opcode(opcode, spi_nor_3to4_read,
+				      ARRAY_SIZE(spi_nor_3to4_read));
+}
+
+static u8 spi_nor_convert_3to4_program(u8 opcode)
+{
+	static const u8 spi_nor_3to4_program[][2] = {
+		{ SPINOR_OP_PP,		SPINOR_OP_PP_4B },
+		{ SPINOR_OP_PP_1_1_4,	SPINOR_OP_PP_1_1_4_4B },
+		{ SPINOR_OP_PP_1_4_4,	SPINOR_OP_PP_1_4_4_4B },
+		{ SPINOR_OP_PP_1_1_8,	SPINOR_OP_PP_1_1_8_4B },
+		{ SPINOR_OP_PP_1_8_8,	SPINOR_OP_PP_1_8_8_4B },
+	};
+
+	return spi_nor_convert_opcode(opcode, spi_nor_3to4_program,
+				      ARRAY_SIZE(spi_nor_3to4_program));
+}
+
+static u8 spi_nor_convert_3to4_erase(u8 opcode)
+{
+	static const u8 spi_nor_3to4_erase[][2] = {
+		{ SPINOR_OP_BE_4K,	SPINOR_OP_BE_4K_4B },
+		{ SPINOR_OP_BE_32K,	SPINOR_OP_BE_32K_4B },
+		{ SPINOR_OP_SE,		SPINOR_OP_SE_4B },
+	};
+
+	return spi_nor_convert_opcode(opcode, spi_nor_3to4_erase,
+				      ARRAY_SIZE(spi_nor_3to4_erase));
+}
+
+static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
+{
+	nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
+	nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode);
+	nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
+
+	if (!spi_nor_has_uniform_erase(nor)) {
+		struct spi_nor_erase_map *map = &nor->params.erase_map;
+		struct spi_nor_erase_type *erase;
+		int i;
+
+		for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
+			erase = &map->erase_type[i];
+			erase->opcode =
+				spi_nor_convert_3to4_erase(erase->opcode);
+		}
+	}
+}
+
 static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops)
 {
 	int ret = 0;
@@ -1326,28 +1419,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	return ret;
 }
 
-/* Write status register and ensure bits in mask match written values */
-static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
-				      u8 mask)
-{
-	int ret;
-
-	spi_nor_write_enable(nor);
-	ret = spi_nor_write_sr(nor, status_new);
-	if (ret)
-		return ret;
-
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		return ret;
-
-	ret = spi_nor_read_sr(nor);
-	if (ret < 0)
-		return ret;
-
-	return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
-}
-
 static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs,
 				 uint64_t *len)
 {
@@ -1664,47 +1735,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 spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
-{
-	int ret;
-
-	spi_nor_write_enable(nor);
-
-	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'
@@ -1870,36 +1900,6 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
-static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR2, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_OUT(1, sr2, 1));
-
-		return spi_mem_exec_op(nor->spimem, &op);
-	}
-
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
-}
-
-static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
-
-		return spi_mem_exec_op(nor->spimem, &op);
-	}
-
-	return nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
-}
-
 /**
  * sr2_bit7_quad_enable() - set QE bit in Status Register 2.
  * @nor:	pointer to a 'struct spi_nor'
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (2 preceding siblings ...)
  2019-10-29 11:16 ` [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations Tudor.Ambarus
@ 2019-10-29 11:16 ` Tudor.Ambarus
  2019-10-31 10:36   ` Boris Brezillon
  2019-11-02 10:36   ` Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value Tudor.Ambarus
                   ` (27 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

spi_mem_exec_op()
nor->controller_ops->write_reg()
nor->controller_ops->read_reg()
spi_nor_wait_till_ready()
Return 0 on success, -errno otherwise.

Stop compare with negative and compare with zero in all the register
operations methods.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 24378d65fa2e..4d3c37658ea5 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -447,7 +447,7 @@ static int spi_nor_read_sr(struct spi_nor *nor)
 						    nor->bouncebuf, 1);
 	}
 
-	if (ret < 0) {
+	if (ret) {
 		pr_err("error %d reading SR\n", (int) ret);
 		return ret;
 	}
@@ -477,7 +477,7 @@ static int spi_nor_read_fsr(struct spi_nor *nor)
 						    nor->bouncebuf, 1);
 	}
 
-	if (ret < 0) {
+	if (ret) {
 		pr_err("error %d reading FSR\n", ret);
 		return ret;
 	}
@@ -507,7 +507,7 @@ static int spi_nor_read_cr(struct spi_nor *nor)
 						    nor->bouncebuf, 1);
 	}
 
-	if (ret < 0) {
+	if (ret) {
 		dev_err(nor->dev, "error %d reading CR\n", ret);
 		return ret;
 	}
@@ -643,7 +643,7 @@ static int s3an_sr_ready(struct spi_nor *nor)
 	int ret;
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-	if (ret < 0) {
+	if (ret) {
 		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
 		return ret;
 	}
@@ -800,7 +800,7 @@ static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
 						     sr_cr, 2);
 	}
 
-	if (ret < 0) {
+	if (ret) {
 		dev_err(nor->dev,
 			"error while writing configuration register\n");
 		return -EINVAL;
@@ -1930,20 +1930,23 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	spi_nor_write_enable(nor);
 
 	ret = spi_nor_write_sr2(nor, sr2);
-	if (ret < 0) {
+	if (ret) {
 		dev_err(nor->dev, "error while writing status register 2\n");
 		return -EINVAL;
 	}
 
 	ret = spi_nor_wait_till_ready(nor);
-	if (ret < 0) {
+	if (ret) {
 		dev_err(nor->dev, "timeout while writing status register 2\n");
 		return ret;
 	}
 
 	/* Read back and check it. */
 	ret = spi_nor_read_sr2(nor, sr2);
-	if (!(ret > 0 && (*sr2 & SR2_QUAD_EN_BIT7))) {
+	if (ret)
+		return ret;
+
+	if (!(*sr2 & SR2_QUAD_EN_BIT7)) {
 		dev_err(nor->dev, "SR2 Quad bit not set\n");
 		return -EINVAL;
 	}
@@ -2534,7 +2537,7 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
 		tmp = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id,
 						    SPI_NOR_MAX_ID_LEN);
 	}
-	if (tmp < 0) {
+	if (tmp) {
 		dev_err(nor->dev, "error %d reading JEDEC ID\n", tmp);
 		return ERR_PTR(tmp);
 	}
@@ -2751,7 +2754,7 @@ static int s3an_nor_setup(struct spi_nor *nor,
 	int ret;
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-	if (ret < 0) {
+	if (ret) {
 		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
 		return ret;
 	}
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (3 preceding siblings ...)
  2019-10-29 11:16 ` [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods Tudor.Ambarus
@ 2019-10-29 11:16 ` Tudor.Ambarus
  2019-10-31 10:36   ` Boris Brezillon
  2019-11-02 10:37   ` Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err() Tudor.Ambarus
                   ` (26 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

ret is already of type int.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 4d3c37658ea5..e801f390728c 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -448,7 +448,7 @@ static int spi_nor_read_sr(struct spi_nor *nor)
 	}
 
 	if (ret) {
-		pr_err("error %d reading SR\n", (int) ret);
+		pr_err("error %d reading SR\n", ret);
 		return ret;
 	}
 
@@ -644,7 +644,7 @@ static int s3an_sr_ready(struct spi_nor *nor)
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
 	if (ret) {
-		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
+		dev_err(nor->dev, "error %d reading XRDSR\n", ret);
 		return ret;
 	}
 
@@ -2619,8 +2619,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_write_data(nor, to, 1, buf);
 		if (ret < 0)
 			goto sst_write_err;
-		WARN(ret != 1, "While writing 1 byte written %i bytes\n",
-		     (int)ret);
+		WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
 			goto sst_write_err;
@@ -2635,8 +2634,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_write_data(nor, to, 2, buf + actual);
 		if (ret < 0)
 			goto sst_write_err;
-		WARN(ret != 2, "While writing 2 bytes written %i bytes\n",
-		     (int)ret);
+		WARN(ret != 2, "While writing 2 bytes written %i bytes\n", ret);
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
 			goto sst_write_err;
@@ -2658,8 +2656,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_write_data(nor, to, 1, buf + actual);
 		if (ret < 0)
 			goto sst_write_err;
-		WARN(ret != 1, "While writing 1 byte written %i bytes\n",
-		     (int)ret);
+		WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
 			goto sst_write_err;
@@ -2755,7 +2752,7 @@ static int s3an_nor_setup(struct spi_nor *nor,
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
 	if (ret) {
-		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
+		dev_err(nor->dev, "error %d reading XRDSR\n", ret);
 		return ret;
 	}
 
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (4 preceding siblings ...)
  2019-10-29 11:16 ` [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value Tudor.Ambarus
@ 2019-10-29 11:16 ` Tudor.Ambarus
  2019-10-31 10:43   ` Boris Brezillon
  2019-11-02 10:38   ` Tudor.Ambarus
  2019-10-29 11:16 ` [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops Tudor.Ambarus
                   ` (25 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Print identifying information about struct device.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index e801f390728c..c794eff69fe9 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -448,7 +448,7 @@ static int spi_nor_read_sr(struct spi_nor *nor)
 	}
 
 	if (ret) {
-		pr_err("error %d reading SR\n", ret);
+		dev_err(nor->dev, "error %d reading SR\n", ret);
 		return ret;
 	}
 
@@ -478,7 +478,7 @@ static int spi_nor_read_fsr(struct spi_nor *nor)
 	}
 
 	if (ret) {
-		pr_err("error %d reading FSR\n", ret);
+		dev_err(nor->dev, "error %d reading FSR\n", ret);
 		return ret;
 	}
 
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (5 preceding siblings ...)
  2019-10-29 11:16 ` [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err() Tudor.Ambarus
@ 2019-10-29 11:16 ` Tudor.Ambarus
  2019-10-31 10:48   ` Boris Brezillon
  2019-11-02 10:39   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr() Tudor.Ambarus
                   ` (24 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:16 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Do not overwrite the error numbers received the Register Operations
methods.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c794eff69fe9..1a00438fd061 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1364,10 +1364,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 		spi_nor_write_enable(nor);
 
-		if (spi_nor_erase_chip(nor)) {
-			ret = -EIO;
+		ret = spi_nor_erase_chip(nor);
+		if (ret)
 			goto erase_err;
-		}
 
 		/*
 		 * Scale the timeout linearly with the size of the flash, with
@@ -1839,7 +1838,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 	ret = spi_nor_read_sr(nor);
 	if (ret < 0) {
 		dev_err(nor->dev, "error while reading status register\n");
-		return -EINVAL;
+		return ret;
 	}
 	sr_cr[0] = ret;
 	sr_cr[1] = CR_QUAD_EN_SPAN;
@@ -1870,7 +1869,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	ret = spi_nor_read_cr(nor);
 	if (ret < 0) {
 		dev_err(dev, "error while reading configuration register\n");
-		return -EINVAL;
+		return ret;
 	}
 
 	if (ret & CR_QUAD_EN_SPAN)
@@ -1882,7 +1881,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	ret = spi_nor_read_sr(nor);
 	if (ret < 0) {
 		dev_err(dev, "error while reading status register\n");
-		return -EINVAL;
+		return ret;
 	}
 	sr_cr[0] = ret;
 
@@ -1932,7 +1931,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	ret = spi_nor_write_sr2(nor, sr2);
 	if (ret) {
 		dev_err(nor->dev, "error while writing status register 2\n");
-		return -EINVAL;
+		return ret;
 	}
 
 	ret = spi_nor_wait_till_ready(nor);
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (6 preceding siblings ...)
  2019-10-29 11:16 ` [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 10:51   ` Boris Brezillon
  2019-11-02 10:42   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr() Tudor.Ambarus
                   ` (23 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Let the callers pass the pointer to the DMA-able buffer where
the value of the Status Register will be written. This way we
avoid the casts between int and u8, which can be confusing.

Callers stop compare the return value of spi_nor_read_sr() with negative,
spi_nor_read_sr() returns 0 on success and -errno otherwise.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 117 +++++++++++++++++++++++-------------------
 1 file changed, 64 insertions(+), 53 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 1a00438fd061..dc44d1206f77 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -425,12 +425,15 @@ static int spi_nor_write_disable(struct spi_nor *nor)
 	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRDI, NULL, 0);
 }
 
-/*
- * Read the status register, returning its value in the location
- * Return the status register value.
- * Returns negative if error occurred.
+/**
+ * spi_nor_read_sr() - Read the Status Register.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @sr:		pointer to a DMA-able buffer where the value of the
+ *              Status Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
-static int spi_nor_read_sr(struct spi_nor *nor)
+static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
 {
 	int ret;
 
@@ -439,20 +442,18 @@ static int spi_nor_read_sr(struct spi_nor *nor)
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 1),
 				   SPI_MEM_OP_NO_ADDR,
 				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+				   SPI_MEM_OP_DATA_IN(1, sr, 1));
 
 		ret = spi_mem_exec_op(nor->spimem, &op);
 	} else {
 		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR,
-						    nor->bouncebuf, 1);
+						    sr, 1);
 	}
 
-	if (ret) {
+	if (ret)
 		dev_err(nor->dev, "error %d reading SR\n", ret);
-		return ret;
-	}
 
-	return nor->bouncebuf[0];
+	return ret;
 }
 
 /*
@@ -668,12 +669,14 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
 
 static int spi_nor_sr_ready(struct spi_nor *nor)
 {
-	int sr = spi_nor_read_sr(nor);
-	if (sr < 0)
-		return sr;
+	int ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
 
-	if (nor->flags & SNOR_F_USE_CLSR && sr & (SR_E_ERR | SR_P_ERR)) {
-		if (sr & SR_E_ERR)
+	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");
@@ -682,7 +685,7 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
 		return -EIO;
 	}
 
-	return !(sr & SR_WIP);
+	return !(nor->bouncebuf[0] & SR_WIP);
 }
 
 static int spi_nor_clear_fsr(struct spi_nor *nor)
@@ -831,11 +834,11 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 	if (ret)
 		return ret;
 
-	ret = spi_nor_read_sr(nor);
-	if (ret < 0)
+	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+	if (ret)
 		return ret;
 
-	return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
+	return ((nor->bouncebuf[0] & mask) != (status_new & mask)) ? -EIO : 0;
 }
 
 static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
@@ -1510,16 +1513,18 @@ static int stm_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
 static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = &nor->mtd;
-	int status_old, status_new;
+	int ret, status_old, status_new;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 	u8 shift = ffs(mask) - 1, pow, val;
 	loff_t lock_len;
 	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
 	bool use_top;
 
-	status_old = spi_nor_read_sr(nor);
-	if (status_old < 0)
-		return status_old;
+	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+	if (ret)
+		return ret;
+
+	status_old = nor->bouncebuf[0];
 
 	/* If nothing in our range is unlocked, we don't need to do anything */
 	if (stm_is_locked_sr(nor, ofs, len, status_old))
@@ -1590,16 +1595,18 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = &nor->mtd;
-	int status_old, status_new;
+	int ret, status_old, status_new;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 	u8 shift = ffs(mask) - 1, pow, val;
 	loff_t lock_len;
 	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
 	bool use_top;
 
-	status_old = spi_nor_read_sr(nor);
-	if (status_old < 0)
-		return status_old;
+	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+	if (ret)
+		return ret;
+
+	status_old = nor->bouncebuf[0];
 
 	/* If nothing in our range is locked, we don't need to do anything */
 	if (stm_is_unlocked_sr(nor, ofs, len, status_old))
@@ -1674,13 +1681,13 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
  */
 static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
-	int status;
+	int ret;
 
-	status = spi_nor_read_sr(nor);
-	if (status < 0)
-		return status;
+	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+	if (ret)
+		return ret;
 
-	return stm_is_locked_sr(nor, ofs, len, status);
+	return stm_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]);
 }
 
 static const struct spi_nor_locking_ops stm_locking_ops = {
@@ -1746,24 +1753,28 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
  */
 static int macronix_quad_enable(struct spi_nor *nor)
 {
-	int ret, val;
+	int ret;
+
+	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+	if (ret)
+		return ret;
 
-	val = spi_nor_read_sr(nor);
-	if (val < 0)
-		return val;
-	if (val & SR_QUAD_EN_MX)
+	if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
 		return 0;
 
 	spi_nor_write_enable(nor);
 
-	spi_nor_write_sr(nor, val | SR_QUAD_EN_MX);
+	spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
 
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
 		return ret;
 
-	ret = spi_nor_read_sr(nor);
-	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+	if (ret)
+		return ret;
+
+	if (!(nor->bouncebuf[0] & SR_QUAD_EN_MX)) {
 		dev_err(nor->dev, "Macronix Quad bit not set\n");
 		return -EINVAL;
 	}
@@ -1835,12 +1846,12 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 	int ret;
 
 	/* Keep the current value of the Status Register. */
-	ret = spi_nor_read_sr(nor);
-	if (ret < 0) {
+	ret = spi_nor_read_sr(nor, &sr_cr[0]);
+	if (ret) {
 		dev_err(nor->dev, "error while reading status register\n");
 		return ret;
 	}
-	sr_cr[0] = ret;
+
 	sr_cr[1] = CR_QUAD_EN_SPAN;
 
 	return spi_nor_write_sr_cr(nor, sr_cr);
@@ -1878,12 +1889,11 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	sr_cr[1] = ret | CR_QUAD_EN_SPAN;
 
 	/* Keep the current value of the Status Register. */
-	ret = spi_nor_read_sr(nor);
-	if (ret < 0) {
+	ret = spi_nor_read_sr(nor, &sr_cr[0]);
+	if (ret) {
 		dev_err(dev, "error while reading status register\n");
 		return ret;
 	}
-	sr_cr[0] = ret;
 
 	ret = spi_nor_write_sr_cr(nor, sr_cr);
 	if (ret)
@@ -1967,15 +1977,15 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 	int ret;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 
-	ret = spi_nor_read_sr(nor);
-	if (ret < 0) {
+	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+	if (ret) {
 		dev_err(nor->dev, "error while reading status register\n");
 		return ret;
 	}
 
 	spi_nor_write_enable(nor);
 
-	ret = spi_nor_write_sr(nor, ret & ~mask);
+	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
 	if (ret) {
 		dev_err(nor->dev, "write to status register failed\n");
 		return ret;
@@ -2021,13 +2031,14 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	if (ret & CR_QUAD_EN_SPAN) {
 		sr_cr[1] = ret;
 
-		ret = spi_nor_read_sr(nor);
-		if (ret < 0) {
+		ret = spi_nor_read_sr(nor, &sr_cr[0]);
+		if (ret) {
 			dev_err(nor->dev,
 				"error while reading status register\n");
 			return ret;
 		}
-		sr_cr[0] = ret & ~mask;
+
+		sr_cr[0] &= ~mask;
 
 		ret = spi_nor_write_sr_cr(nor, sr_cr);
 		if (ret)
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (7 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 10:53   ` Boris Brezillon
  2019-11-02 10:44   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr() Tudor.Ambarus
                   ` (22 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Let the callers pass the pointer to the DMA-able buffer where
the value of the Flag Status Register will be written. This way we
avoid the casts between int and u8, which can be confusing.

Caller stops compare the return value of spi_nor_read_fsr() with negative,
spi_nor_read_fsr() returns 0 on success and -errno otherwise.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index dc44d1206f77..0d38aede4de7 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -456,12 +456,15 @@ static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
 	return ret;
 }
 
-/*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
- * Returns negative if error occurred.
+/**
+ * spi_nor_read_fsr() - Read the Flag Status Register.
+ * @nor:	pointer to 'struct spi_nor'
+ * @fsr:	pointer to a DMA-able buffer where the value of the
+ *              Flag Status Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
-static int spi_nor_read_fsr(struct spi_nor *nor)
+static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
 {
 	int ret;
 
@@ -470,20 +473,18 @@ static int spi_nor_read_fsr(struct spi_nor *nor)
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 1),
 				   SPI_MEM_OP_NO_ADDR,
 				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+				   SPI_MEM_OP_DATA_IN(1, fsr, 1));
 
 		ret = spi_mem_exec_op(nor->spimem, &op);
 	} else {
 		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDFSR,
-						    nor->bouncebuf, 1);
+						    fsr, 1);
 	}
 
-	if (ret) {
+	if (ret)
 		dev_err(nor->dev, "error %d reading FSR\n", ret);
-		return ret;
-	}
 
-	return nor->bouncebuf[0];
+	return ret;
 }
 
 /*
@@ -705,17 +706,18 @@ static int spi_nor_clear_fsr(struct spi_nor *nor)
 
 static int spi_nor_fsr_ready(struct spi_nor *nor)
 {
-	int fsr = spi_nor_read_fsr(nor);
-	if (fsr < 0)
-		return fsr;
+	int ret = spi_nor_read_fsr(nor, &nor->bouncebuf[0]);
+
+	if (ret)
+		return ret;
 
-	if (fsr & (FSR_E_ERR | FSR_P_ERR)) {
-		if (fsr & FSR_E_ERR)
+	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 (fsr & FSR_PT_ERR)
+		if (nor->bouncebuf[0] & FSR_PT_ERR)
 			dev_err(nor->dev,
 			"Attempted to modify a protected sector.\n");
 
@@ -723,7 +725,7 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
 		return -EIO;
 	}
 
-	return fsr & FSR_READY;
+	return nor->bouncebuf[0] & FSR_READY;
 }
 
 static int spi_nor_ready(struct spi_nor *nor)
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (8 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 10:58   ` Boris Brezillon
  2019-11-02 10:45   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers Tudor.Ambarus
                   ` (21 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Let the callers pass the pointer to the DMA-able buffer where
the value of the Configuration Register will be written. This way we
avoid the casts between int and u8, which can be confusing.

Callers stop compare the return value of spi_nor_read_cr() with negative,
spi_nor_read_cr() returns 0 on success and -errno otherwise.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 55 +++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0d38aede4de7..ec179eac2069 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -487,12 +487,16 @@ static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
 	return ret;
 }
 
-/*
- * Read configuration register, returning its value in the
- * location. Return the configuration register value.
- * Returns negative if error occurred.
+/**
+ * spi_nor_read_cr() - Read the Configuration Register using the
+ * SPINOR_OP_RDCR (35h) command.
+ * @nor:	pointer to 'struct spi_nor'
+ * @cr:		pointer to a DMA-able buffer where the value of the
+ *              Configuration Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
-static int spi_nor_read_cr(struct spi_nor *nor)
+static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
 {
 	int ret;
 
@@ -501,20 +505,17 @@ static int spi_nor_read_cr(struct spi_nor *nor)
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDCR, 1),
 				   SPI_MEM_OP_NO_ADDR,
 				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+				   SPI_MEM_OP_DATA_IN(1, cr, 1));
 
 		ret = spi_mem_exec_op(nor->spimem, &op);
 	} else {
-		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDCR,
-						    nor->bouncebuf, 1);
+		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDCR, cr, 1);
 	}
 
-	if (ret) {
+	if (ret)
 		dev_err(nor->dev, "error %d reading CR\n", ret);
-		return ret;
-	}
 
-	return nor->bouncebuf[0];
+	return ret;
 }
 
 /*
@@ -1820,8 +1821,11 @@ static int spansion_quad_enable(struct spi_nor *nor)
 		return ret;
 
 	/* read back and check it */
-	ret = spi_nor_read_cr(nor);
-	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+	ret = spi_nor_read_cr(nor, &nor->bouncebuf[0]);
+	if (ret)
+		return ret;
+
+	if (!(nor->bouncebuf[0] & CR_QUAD_EN_SPAN)) {
 		dev_err(nor->dev, "Spansion Quad bit not set\n");
 		return -EINVAL;
 	}
@@ -1879,16 +1883,16 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	int ret;
 
 	/* Check current Quad Enable bit value. */
-	ret = spi_nor_read_cr(nor);
-	if (ret < 0) {
+	ret = spi_nor_read_cr(nor, &sr_cr[1]);
+	if (ret) {
 		dev_err(dev, "error while reading configuration register\n");
 		return ret;
 	}
 
-	if (ret & CR_QUAD_EN_SPAN)
+	if (sr_cr[1] & CR_QUAD_EN_SPAN)
 		return 0;
 
-	sr_cr[1] = ret | CR_QUAD_EN_SPAN;
+	sr_cr[1] |= CR_QUAD_EN_SPAN;
 
 	/* Keep the current value of the Status Register. */
 	ret = spi_nor_read_sr(nor, &sr_cr[0]);
@@ -1902,8 +1906,11 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 		return ret;
 
 	/* Read back and check it. */
-	ret = spi_nor_read_cr(nor);
-	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+	ret = spi_nor_read_cr(nor, &sr_cr[1]);
+	if (ret)
+		return ret;
+
+	if (!(sr_cr[1] & CR_QUAD_EN_SPAN)) {
 		dev_err(nor->dev, "Spansion Quad bit not set\n");
 		return -EINVAL;
 	}
@@ -2019,8 +2026,8 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	u8 *sr_cr =  nor->bouncebuf;
 
 	/* Check current Quad Enable bit value. */
-	ret = spi_nor_read_cr(nor);
-	if (ret < 0) {
+	ret = spi_nor_read_cr(nor, &sr_cr[1]);
+	if (ret) {
 		dev_err(nor->dev,
 			"error while reading configuration register\n");
 		return ret;
@@ -2030,9 +2037,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	 * When the configuration register Quad Enable bit is one, only the
 	 * Write Status (01h) command with two data bytes may be used.
 	 */
-	if (ret & CR_QUAD_EN_SPAN) {
-		sr_cr[1] = ret;
-
+	if (sr_cr[1] & CR_QUAD_EN_SPAN) {
 		ret = spi_nor_read_sr(nor, &sr_cr[0]);
 		if (ret) {
 			dev_err(nor->dev,
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (9 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 10:59   ` Boris Brezillon
  2019-11-02 10:46   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 12/32] mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr() Tudor.Ambarus
                   ` (20 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Drop the error messages from the callers, since the callees
already print an error message in case of failure.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 50 +++++++++----------------------------------
 1 file changed, 10 insertions(+), 40 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index ec179eac2069..4a1ecf452a39 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -812,14 +812,7 @@ static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
 		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;
+	return spi_nor_wait_till_ready(nor);
 }
 
 /* Write status register and ensure bits in mask match written values */
@@ -1853,10 +1846,8 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 
 	/* Keep the current value of the Status Register. */
 	ret = spi_nor_read_sr(nor, &sr_cr[0]);
-	if (ret) {
-		dev_err(nor->dev, "error while reading status register\n");
+	if (ret)
 		return ret;
-	}
 
 	sr_cr[1] = CR_QUAD_EN_SPAN;
 
@@ -1878,16 +1869,13 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
  */
 static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 {
-	struct device *dev = nor->dev;
 	u8 *sr_cr = nor->bouncebuf;
 	int ret;
 
 	/* Check current Quad Enable bit value. */
 	ret = spi_nor_read_cr(nor, &sr_cr[1]);
-	if (ret) {
-		dev_err(dev, "error while reading configuration register\n");
+	if (ret)
 		return ret;
-	}
 
 	if (sr_cr[1] & CR_QUAD_EN_SPAN)
 		return 0;
@@ -1896,10 +1884,8 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 
 	/* Keep the current value of the Status Register. */
 	ret = spi_nor_read_sr(nor, &sr_cr[0]);
-	if (ret) {
-		dev_err(dev, "error while reading status register\n");
+	if (ret)
 		return ret;
-	}
 
 	ret = spi_nor_write_sr_cr(nor, sr_cr);
 	if (ret)
@@ -1954,10 +1940,8 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	}
 
 	ret = spi_nor_wait_till_ready(nor);
-	if (ret) {
-		dev_err(nor->dev, "timeout while writing status register 2\n");
+	if (ret)
 		return ret;
-	}
 
 	/* Read back and check it. */
 	ret = spi_nor_read_sr2(nor, sr2);
@@ -1987,10 +1971,8 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 
 	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
-	if (ret) {
-		dev_err(nor->dev, "error while reading status register\n");
+	if (ret)
 		return ret;
-	}
 
 	spi_nor_write_enable(nor);
 
@@ -2000,10 +1982,7 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 		return ret;
 	}
 
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		dev_err(nor->dev, "timeout while writing status register\n");
-	return ret;
+	return spi_nor_wait_till_ready(nor);
 }
 
 /**
@@ -2027,11 +2006,8 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 
 	/* Check current Quad Enable bit value. */
 	ret = spi_nor_read_cr(nor, &sr_cr[1]);
-	if (ret) {
-		dev_err(nor->dev,
-			"error while reading configuration register\n");
+	if (ret)
 		return ret;
-	}
 
 	/*
 	 * When the configuration register Quad Enable bit is one, only the
@@ -2039,18 +2015,12 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	 */
 	if (sr_cr[1] & CR_QUAD_EN_SPAN) {
 		ret = spi_nor_read_sr(nor, &sr_cr[0]);
-		if (ret) {
-			dev_err(nor->dev,
-				"error while reading status register\n");
+		if (ret)
 			return ret;
-		}
 
 		sr_cr[0] &= ~mask;
 
-		ret = spi_nor_write_sr_cr(nor, sr_cr);
-		if (ret)
-			dev_err(nor->dev, "16-bit write register failed\n");
-		return ret;
+		return spi_nor_write_sr_cr(nor, sr_cr);
 	}
 
 	/*
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 12/32] mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (10 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 11:02   ` Boris Brezillon
  2019-10-29 11:17 ` [PATCH v3 13/32] mtd: spi-nor: Print error messages inside Reg Ops methods Tudor.Ambarus
                   ` (19 subsequent siblings)
  31 siblings, 1 reply; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

spi_nor_clear_sr() and spi_nor_clear_fsr() are called just in case
of errors. The callers didn't check their return value, make them
of type void.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 4a1ecf452a39..e5ed9012cd50 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -654,7 +654,7 @@ static int s3an_sr_ready(struct spi_nor *nor)
 	return !!(nor->bouncebuf[0] & XSR_RDY);
 }
 
-static int spi_nor_clear_sr(struct spi_nor *nor)
+static void spi_nor_clear_sr(struct spi_nor *nor)
 {
 	if (nor->spimem) {
 		struct spi_mem_op op =
@@ -690,7 +690,7 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
 	return !(nor->bouncebuf[0] & SR_WIP);
 }
 
-static int spi_nor_clear_fsr(struct spi_nor *nor)
+static void spi_nor_clear_fsr(struct spi_nor *nor)
 {
 	if (nor->spimem) {
 		struct spi_mem_op op =
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 13/32] mtd: spi-nor: Print error messages inside Reg Ops methods
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (11 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 12/32] mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 11:05   ` Boris Brezillon
  2019-10-29 11:17 ` [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write() Tudor.Ambarus
                   ` (18 subsequent siblings)
  31 siblings, 1 reply; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Spare the callers of printing error messages by themselves.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 165 +++++++++++++++++++++++++++++++-----------
 1 file changed, 123 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index e5ed9012cd50..bc46b946ac77 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -394,6 +394,8 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
  */
 static int spi_nor_write_enable(struct spi_nor *nor)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 1),
@@ -401,10 +403,16 @@ static int spi_nor_write_enable(struct spi_nor *nor)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_NO_DATA);
 
-		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_WREN,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d on Write Enable\n", ret);
+
+	return ret;
 }
 
 /*
@@ -412,6 +420,8 @@ static int spi_nor_write_enable(struct spi_nor *nor)
  */
 static int spi_nor_write_disable(struct spi_nor *nor)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 1),
@@ -419,10 +429,16 @@ static int spi_nor_write_disable(struct spi_nor *nor)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_NO_DATA);
 
-		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_WRDI,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRDI, NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d on Write Disable\n", ret);
+
+	return ret;
 }
 
 /**
@@ -524,6 +540,8 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
  */
 static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
 {
+	int ret;
+
 	nor->bouncebuf[0] = val;
 	if (nor->spimem) {
 		struct spi_mem_op op =
@@ -532,15 +550,23 @@ static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 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,
+						     nor->bouncebuf, 1);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
-					      nor->bouncebuf, 1);
+	if (ret)
+		dev_err(nor->dev, "error %d writing SR\n", ret);
+
+	return ret;
+
 }
 
 static int macronix_set_4byte(struct spi_nor *nor, bool enable)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(enable ?
@@ -551,12 +577,18 @@ static int macronix_set_4byte(struct spi_nor *nor, bool enable)
 				  SPI_MEM_OP_NO_DUMMY,
 				  SPI_MEM_OP_NO_DATA);
 
-		return spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->write_reg(nor,
+						     enable ? SPINOR_OP_EN4B :
+							      SPINOR_OP_EX4B,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, enable ? SPINOR_OP_EN4B :
-							    SPINOR_OP_EX4B,
-					      NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d setting 4-byte mode\n", ret);
+
+	return ret;
 }
 
 static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
@@ -572,6 +604,8 @@ static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
 
 static int spansion_set_4byte(struct spi_nor *nor, bool enable)
 {
+	int ret;
+
 	nor->bouncebuf[0] = enable << 7;
 
 	if (nor->spimem) {
@@ -581,15 +615,22 @@ static int spansion_set_4byte(struct spi_nor *nor, bool enable)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 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_BRWR,
+						     nor->bouncebuf, 1);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_BRWR,
-					      nor->bouncebuf, 1);
+	if (ret)
+		dev_err(nor->dev, "error %d setting 4-byte mode\n", ret);
+
+	return ret;
 }
 
 static int spi_nor_write_ear(struct spi_nor *nor, u8 ear)
 {
+	int ret;
+
 	nor->bouncebuf[0] = ear;
 
 	if (nor->spimem) {
@@ -599,11 +640,16 @@ static int spi_nor_write_ear(struct spi_nor *nor, u8 ear)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 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_WREAR,
+						     nor->bouncebuf, 1);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WREAR,
-					      nor->bouncebuf, 1);
+	if (ret)
+		dev_err(nor->dev, "error %d writing EAR\n", ret);
+
+	return ret;
 }
 
 static int winbond_set_4byte(struct spi_nor *nor, bool enable)
@@ -628,6 +674,8 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable)
 
 static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 1),
@@ -635,10 +683,16 @@ static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_DATA_IN(1, sr, 1));
 
-		return spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR,
+						    sr, 1);
 	}
 
-	return nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR, sr, 1);
+	if (ret)
+		dev_err(nor->dev, "error %d reading XRDSR\n", ret);
+
+	return ret;
 }
 
 static int s3an_sr_ready(struct spi_nor *nor)
@@ -646,16 +700,16 @@ static int s3an_sr_ready(struct spi_nor *nor)
 	int ret;
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-	if (ret) {
-		dev_err(nor->dev, "error %d reading XRDSR\n", ret);
+	if (ret)
 		return ret;
-	}
 
 	return !!(nor->bouncebuf[0] & XSR_RDY);
 }
 
 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, 1),
@@ -663,10 +717,14 @@ static void spi_nor_clear_sr(struct spi_nor *nor)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_NO_DATA);
 
-		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_CLSR,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d clearing SR\n", ret);
 }
 
 static int spi_nor_sr_ready(struct spi_nor *nor)
@@ -692,6 +750,8 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
 
 static void spi_nor_clear_fsr(struct spi_nor *nor)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 1),
@@ -699,10 +759,14 @@ static void spi_nor_clear_fsr(struct spi_nor *nor)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_NO_DATA);
 
-		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_CLFSR,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d clearing FSR\n", ret);
 }
 
 static int spi_nor_fsr_ready(struct spi_nor *nor)
@@ -839,6 +903,8 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 
 static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR2, 1),
@@ -846,14 +912,22 @@ static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_DATA_OUT(1, sr2, 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_WRSR2,
+						     sr2, 1);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
+	if (ret)
+		dev_err(nor->dev, "error %d writing SR2\n", ret);
+
+	return ret;
 }
 
 static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2, 1),
@@ -861,10 +935,16 @@ static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
 
-		return spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2,
+						    sr2, 1);
 	}
 
-	return nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
+	if (ret)
+		dev_err(nor->dev, "error %d reading SR2\n", ret);
+
+	return ret;
 }
 
 /*
@@ -874,6 +954,8 @@ static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
  */
 static int spi_nor_erase_chip(struct spi_nor *nor)
 {
+	int ret;
+
 	dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10));
 
 	if (nor->spimem) {
@@ -883,11 +965,16 @@ static int spi_nor_erase_chip(struct spi_nor *nor)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_NO_DATA);
 
-		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_CHIP_ERASE,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_CHIP_ERASE,
-					      NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d erasing chip\n", ret);
+
+	return ret;
 }
 
 static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
@@ -1934,10 +2021,8 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	spi_nor_write_enable(nor);
 
 	ret = spi_nor_write_sr2(nor, sr2);
-	if (ret) {
-		dev_err(nor->dev, "error while writing status register 2\n");
+	if (ret)
 		return ret;
-	}
 
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
@@ -1977,10 +2062,8 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 	spi_nor_write_enable(nor);
 
 	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
-	if (ret) {
-		dev_err(nor->dev, "write to status register failed\n");
+	if (ret)
 		return ret;
-	}
 
 	return spi_nor_wait_till_ready(nor);
 }
@@ -2738,10 +2821,8 @@ static int s3an_nor_setup(struct spi_nor *nor,
 	int ret;
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-	if (ret) {
-		dev_err(nor->dev, "error %d reading XRDSR\n", ret);
+	if (ret)
 		return ret;
-	}
 
 	nor->erase_opcode = SPINOR_OP_XSE;
 	nor->program_opcode = SPINOR_OP_XPP;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (12 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 13/32] mtd: spi-nor: Print error messages inside Reg Ops methods Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 11:12   ` Boris Brezillon
  2019-11-02 10:47   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 15/32] mtd: spi-nor: Check for errors after each Register Operation Tudor.Ambarus
                   ` (17 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

In case the write of the first byte failed, retlen was incorrectly
incremented to *retlen += actual; on the exit path. retlen should be
incremented when actual data was written to the flash.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index bc46b946ac77..889fd77dbe96 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2667,7 +2667,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		size_t *retlen, const u_char *buf)
 {
 	struct spi_nor *nor = mtd_to_spi_nor(mtd);
-	size_t actual;
+	size_t actual = 0;
 	int ret;
 
 	dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
@@ -2680,9 +2680,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 	nor->sst_write_second = false;
 
-	actual = to % 2;
 	/* Start write from odd address. */
-	if (actual) {
+	if (to % 2) {
 		nor->program_opcode = SPINOR_OP_BP;
 
 		/* write one byte. */
@@ -2693,8 +2692,10 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
 			goto sst_write_err;
+
+		to++;
+		actual++;
 	}
-	to += actual;
 
 	/* Write out most of the data here. */
 	for (; actual < len - 1; actual += 2) {
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 15/32] mtd: spi-nor: Check for errors after each Register Operation
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (13 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31  6:57   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 16/32] mtd: spi-nor: Rename label as it is no longer generic Tudor.Ambarus
                   ` (16 subsequent siblings)
  31 siblings, 1 reply; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Check for the return vales of each Register Operation.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 81 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 60 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 889fd77dbe96..21f01fdcfa16 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -595,11 +595,15 @@ static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
 {
 	int ret;
 
-	spi_nor_write_enable(nor);
+	ret == spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
+
 	ret = macronix_set_4byte(nor, enable);
-	spi_nor_write_disable(nor);
+	if (ret)
+		return ret;
 
-	return ret;
+	return spi_nor_write_disable(nor);
 }
 
 static int spansion_set_4byte(struct spi_nor *nor, bool enable)
@@ -665,11 +669,15 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable)
 	 * Register to be set to 1, so all 3-byte-address reads come from the
 	 * second 16M. We must clear the register to enable normal behavior.
 	 */
-	spi_nor_write_enable(nor);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
+
 	ret = spi_nor_write_ear(nor, 0);
-	spi_nor_write_disable(nor);
+	if (ret)
+		return ret;
 
-	return ret;
+	return spi_nor_write_disable(nor);
 }
 
 static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
@@ -855,7 +863,9 @@ static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
 {
 	int ret;
 
-	spi_nor_write_enable(nor);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
 
 	if (nor->spimem) {
 		struct spi_mem_op op =
@@ -885,7 +895,10 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 {
 	int ret;
 
-	spi_nor_write_enable(nor);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
+
 	ret = spi_nor_write_sr(nor, status_new);
 	if (ret)
 		return ret;
@@ -1393,7 +1406,9 @@ static int spi_nor_erase_multi_sectors(struct spi_nor *nor, u64 addr, u32 len)
 	list_for_each_entry_safe(cmd, next, &erase_list, list) {
 		nor->erase_opcode = cmd->opcode;
 		while (cmd->count) {
-			spi_nor_write_enable(nor);
+			ret = spi_nor_write_enable(nor);
+			if (ret)
+				goto destroy_erase_cmd_list;
 
 			ret = spi_nor_erase_sector(nor, addr);
 			if (ret)
@@ -1448,7 +1463,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
 		unsigned long timeout;
 
-		spi_nor_write_enable(nor);
+		ret = spi_nor_write_enable(nor);
+		if (ret)
+			goto erase_err;
 
 		ret = spi_nor_erase_chip(nor);
 		if (ret)
@@ -1475,7 +1492,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	/* "sector"-at-a-time erase */
 	} else if (spi_nor_has_uniform_erase(nor)) {
 		while (len) {
-			spi_nor_write_enable(nor);
+			ret = spi_nor_write_enable(nor);
+			if (ret)
+				goto erase_err;
 
 			ret = spi_nor_erase_sector(nor, addr);
 			if (ret)
@@ -1496,7 +1515,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 			goto erase_err;
 	}
 
-	spi_nor_write_disable(nor);
+	ret = spi_nor_write_disable(nor);
 
 erase_err:
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
@@ -1845,9 +1864,13 @@ static int macronix_quad_enable(struct spi_nor *nor)
 	if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
 		return 0;
 
-	spi_nor_write_enable(nor);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
 
-	spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
+	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
+	if (ret)
+		return ret;
 
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
@@ -2018,7 +2041,9 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	/* Update the Quad Enable bit. */
 	*sr2 |= SR2_QUAD_EN_BIT7;
 
-	spi_nor_write_enable(nor);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
 
 	ret = spi_nor_write_sr2(nor, sr2);
 	if (ret)
@@ -2059,7 +2084,9 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	spi_nor_write_enable(nor);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
 
 	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
 	if (ret)
@@ -2676,7 +2703,9 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	if (ret)
 		return ret;
 
-	spi_nor_write_enable(nor);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		goto sst_write_err;
 
 	nor->sst_write_second = false;
 
@@ -2714,14 +2743,19 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	}
 	nor->sst_write_second = false;
 
-	spi_nor_write_disable(nor);
+	ret = spi_nor_write_disable(nor);
+	if (ret)
+		goto sst_write_err;
+
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
 		goto sst_write_err;
 
 	/* Write out trailing byte if it exists. */
 	if (actual != len) {
-		spi_nor_write_enable(nor);
+		ret = spi_nor_write_enable(nor);
+		if (ret)
+			goto sst_write_err;
 
 		nor->program_opcode = SPINOR_OP_BP;
 		ret = spi_nor_write_data(nor, to, 1, buf + actual);
@@ -2731,8 +2765,10 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
 			goto sst_write_err;
-		spi_nor_write_disable(nor);
+
 		actual += 1;
+
+		ret = spi_nor_write_disable(nor);
 	}
 sst_write_err:
 	*retlen += actual;
@@ -2783,7 +2819,10 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 		addr = spi_nor_convert_addr(nor, addr);
 
-		spi_nor_write_enable(nor);
+		ret = spi_nor_write_enable(nor);
+		if (ret)
+			goto write_err;
+
 		ret = spi_nor_write_data(nor, addr, page_remain, buf + i);
 		if (ret < 0)
 			goto write_err;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 16/32] mtd: spi-nor: Rename label as it is no longer generic
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (14 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 15/32] mtd: spi-nor: Check for errors after each Register Operation Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 11:14   ` Boris Brezillon
  2019-10-29 11:17 ` [PATCH v3 17/32] mtd: spi-nor: Move the WE and wait calls inside Write SR methods Tudor.Ambarus
                   ` (15 subsequent siblings)
  31 siblings, 1 reply; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Rename 'sst_write_err' label to 'out' as it is no longer generic for
all the errors in the sst_write() method, and may introduce confusion.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 21f01fdcfa16..ed7c233a7208 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2705,7 +2705,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 	ret = spi_nor_write_enable(nor);
 	if (ret)
-		goto sst_write_err;
+		goto out;
 
 	nor->sst_write_second = false;
 
@@ -2716,11 +2716,11 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		/* write one byte. */
 		ret = spi_nor_write_data(nor, to, 1, buf);
 		if (ret < 0)
-			goto sst_write_err;
+			goto out;
 		WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
-			goto sst_write_err;
+			goto out;
 
 		to++;
 		actual++;
@@ -2733,11 +2733,11 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		/* write two bytes. */
 		ret = spi_nor_write_data(nor, to, 2, buf + actual);
 		if (ret < 0)
-			goto sst_write_err;
+			goto out;
 		WARN(ret != 2, "While writing 2 bytes written %i bytes\n", ret);
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
-			goto sst_write_err;
+			goto out;
 		to += 2;
 		nor->sst_write_second = true;
 	}
@@ -2745,32 +2745,32 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 	ret = spi_nor_write_disable(nor);
 	if (ret)
-		goto sst_write_err;
+		goto out;
 
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
-		goto sst_write_err;
+		goto out;
 
 	/* Write out trailing byte if it exists. */
 	if (actual != len) {
 		ret = spi_nor_write_enable(nor);
 		if (ret)
-			goto sst_write_err;
+			goto out;
 
 		nor->program_opcode = SPINOR_OP_BP;
 		ret = spi_nor_write_data(nor, to, 1, buf + actual);
 		if (ret < 0)
-			goto sst_write_err;
+			goto out;
 		WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
 		ret = spi_nor_wait_till_ready(nor);
 		if (ret)
-			goto sst_write_err;
+			goto out;
 
 		actual += 1;
 
 		ret = spi_nor_write_disable(nor);
 	}
-sst_write_err:
+out:
 	*retlen += actual;
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
 	return ret;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 17/32] mtd: spi-nor: Move the WE and wait calls inside Write SR methods
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (15 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 16/32] mtd: spi-nor: Rename label as it is no longer generic Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 11:15   ` Boris Brezillon
  2019-10-29 11:17 ` [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register Tudor.Ambarus
                   ` (14 subsequent siblings)
  31 siblings, 1 reply; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Avoid duplicating code by moving the calls to spi_nor_write_enable() and
spi_nor_wait_till_ready() inside the Write Status Register methods.

Move spi_nor_write_sr() to avoid forward declaration of
spi_nor_wait_till_ready().

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 108 +++++++++++++++++-------------------------
 1 file changed, 44 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index ed7c233a7208..5fb4d953b5c7 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -534,35 +534,6 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
 	return ret;
 }
 
-/*
- * Write status register 1 byte
- * Returns negative if error occurred.
- */
-static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
-{
-	int ret;
-
-	nor->bouncebuf[0] = val;
-	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(1, nor->bouncebuf, 1));
-
-		ret = spi_mem_exec_op(nor->spimem, &op);
-	} else {
-		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
-						     nor->bouncebuf, 1);
-	}
-
-	if (ret)
-		dev_err(nor->dev, "error %d writing SR\n", ret);
-
-	return ret;
-
-}
-
 static int macronix_set_4byte(struct spi_nor *nor, bool enable)
 {
 	int ret;
@@ -854,6 +825,41 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
 }
 
 /*
+ * Write status register 1 byte
+ * Returns negative if error occurred.
+ */
+static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
+{
+	int ret;
+
+	nor->bouncebuf[0] = val;
+
+	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(1, nor->bouncebuf, 1));
+
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
+						     nor->bouncebuf, 1);
+	}
+
+	if (ret) {
+		dev_err(nor->dev, "error %d writing SR\n", ret);
+		return ret;
+	}
+
+	return spi_nor_wait_till_ready(nor);
+}
+
+/*
  * 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.
@@ -895,18 +901,10 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 {
 	int ret;
 
-	ret = spi_nor_write_enable(nor);
-	if (ret)
-		return ret;
-
 	ret = spi_nor_write_sr(nor, status_new);
 	if (ret)
 		return ret;
 
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		return ret;
-
 	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
 	if (ret)
 		return ret;
@@ -918,6 +916,10 @@ static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
 {
 	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_WRSR2, 1),
@@ -931,10 +933,12 @@ static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
 						     sr2, 1);
 	}
 
-	if (ret)
+	if (ret) {
 		dev_err(nor->dev, "error %d writing SR2\n", ret);
+		return ret;
+	}
 
-	return ret;
+	return spi_nor_wait_till_ready(nor);
 }
 
 static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
@@ -1864,18 +1868,10 @@ 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;
-
 	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
 	if (ret)
 		return ret;
 
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		return ret;
-
 	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
 	if (ret)
 		return ret;
@@ -2041,18 +2037,10 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	/* Update the Quad Enable bit. */
 	*sr2 |= SR2_QUAD_EN_BIT7;
 
-	ret = spi_nor_write_enable(nor);
-	if (ret)
-		return ret;
-
 	ret = spi_nor_write_sr2(nor, sr2);
 	if (ret)
 		return ret;
 
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		return ret;
-
 	/* Read back and check it. */
 	ret = spi_nor_read_sr2(nor, sr2);
 	if (ret)
@@ -2084,15 +2072,7 @@ 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;
-
-	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
-	if (ret)
-		return ret;
-
-	return spi_nor_wait_till_ready(nor);
+	return spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
 }
 
 /**
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (16 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 17/32] mtd: spi-nor: Move the WE and wait calls inside Write SR methods Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 11:16   ` Boris Brezillon
  2019-11-02 10:48   ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 19/32] mtd: spi-nor: Merge spi_nor_write_sr() and spi_nor_write_sr_cr() Tudor.Ambarus
                   ` (13 subsequent siblings)
  31 siblings, 2 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Constify the data to write to the Status Register.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 5fb4d953b5c7..274786e1988f 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -865,7 +865,7 @@ static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
  * second byte will be written to the configuration register.
  * Return negative if error occurred.
  */
-static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
+static int spi_nor_write_sr_cr(struct spi_nor *nor, const u8 *sr_cr)
 {
 	int ret;
 
@@ -912,7 +912,7 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 	return ((nor->bouncebuf[0] & mask) != (status_new & mask)) ? -EIO : 0;
 }
 
-static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
+static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)
 {
 	int ret;
 
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 19/32] mtd: spi-nor: Merge spi_nor_write_sr() and spi_nor_write_sr_cr()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (17 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-31 11:17   ` Boris Brezillon
  2019-10-29 11:17 ` [PATCH v3 20/32] mtd: spi-nor: Describe all the Reg Ops Tudor.Ambarus
                   ` (12 subsequent siblings)
  31 siblings, 1 reply; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

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

The Status Register can be written with one or two bytes. Merge
the two functions to avoid code duplication.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 74 ++++++++++++++-----------------------------
 1 file changed, 23 insertions(+), 51 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 274786e1988f..823b9b06d34d 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -824,16 +824,18 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
 						    DEFAULT_READY_WAIT_JIFFIES);
 }
 
-/*
- * Write status register 1 byte
- * Returns negative if error occurred.
+/**
+ * spi_nor_write_sr() - Write the Status Register.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @sr:		pointer to DMA-able 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 spi_nor_write_sr(struct spi_nor *nor, u8 val)
+static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
 {
 	int ret;
 
-	nor->bouncebuf[0] = val;
-
 	ret = spi_nor_write_enable(nor);
 	if (ret)
 		return ret;
@@ -843,12 +845,12 @@ static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
 			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(1, nor->bouncebuf, 1));
+				   SPI_MEM_OP_DATA_OUT(len, sr, 1));
 
 		ret = spi_mem_exec_op(nor->spimem, &op);
 	} else {
 		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
-						     nor->bouncebuf, 1);
+						     sr, len);
 	}
 
 	if (ret) {
@@ -859,49 +861,15 @@ static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
 	return spi_nor_wait_till_ready(nor);
 }
 
-/*
- * 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 spi_nor_write_sr_cr(struct spi_nor *nor, const 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) {
-		dev_err(nor->dev,
-			"error while writing configuration register\n");
-		return -EINVAL;
-	}
-
-	return spi_nor_wait_till_ready(nor);
-}
-
 /* Write status register and ensure bits in mask match written values */
 static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 				      u8 mask)
 {
 	int ret;
 
-	ret = spi_nor_write_sr(nor, status_new);
+	nor->bouncebuf[0] = status_new;
+
+	ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
 	if (ret)
 		return ret;
 
@@ -1868,7 +1836,9 @@ static int macronix_quad_enable(struct spi_nor *nor)
 	if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
 		return 0;
 
-	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
+	nor->bouncebuf[0] |= SR_QUAD_EN_MX;
+
+	ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
 	if (ret)
 		return ret;
 
@@ -1915,7 +1885,7 @@ static int spansion_quad_enable(struct spi_nor *nor)
 
 	sr_cr[0] = 0;
 	sr_cr[1] = CR_QUAD_EN_SPAN;
-	ret = spi_nor_write_sr_cr(nor, sr_cr);
+	ret = spi_nor_write_sr(nor, sr_cr, 2);
 	if (ret)
 		return ret;
 
@@ -1957,7 +1927,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 
 	sr_cr[1] = CR_QUAD_EN_SPAN;
 
-	return spi_nor_write_sr_cr(nor, sr_cr);
+	return spi_nor_write_sr(nor, sr_cr, 2);
 }
 
 /**
@@ -1993,7 +1963,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	ret = spi_nor_write_sr_cr(nor, sr_cr);
+	ret = spi_nor_write_sr(nor, sr_cr, 2);
 	if (ret)
 		return ret;
 
@@ -2072,7 +2042,9 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	return spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
+	nor->bouncebuf[0] &= ~mask;
+
+	return spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
 }
 
 /**
@@ -2110,7 +2082,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 
 		sr_cr[0] &= ~mask;
 
-		return spi_nor_write_sr_cr(nor, sr_cr);
+		return spi_nor_write_sr(nor, sr_cr, 2);
 	}
 
 	/*
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 20/32] mtd: spi-nor: Describe all the Reg Ops
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (18 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 19/32] mtd: spi-nor: Merge spi_nor_write_sr() and spi_nor_write_sr_cr() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 21/32] mtd: spi-nor: Drop spansion_quad_enable() Tudor.Ambarus
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Document all the Register Operations.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 138 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 127 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 823b9b06d34d..6102318cfd03 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -388,9 +388,11 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
 	return nor->controller_ops->write(nor, to, len, buf);
 }
 
-/*
- * Set write enable latch with Write Enable command.
- * Returns negative if error occurred.
+/**
+ * spi_nor_write_enable() - Set write enable latch with Write Enable command.
+ * @nor:	pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
 static int spi_nor_write_enable(struct spi_nor *nor)
 {
@@ -415,8 +417,11 @@ static int spi_nor_write_enable(struct spi_nor *nor)
 	return ret;
 }
 
-/*
- * Send write disable instruction to the chip.
+/**
+ * spi_nor_write_disable() - Send Write Disable instruction to the chip.
+ * @nor:	pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
 static int spi_nor_write_disable(struct spi_nor *nor)
 {
@@ -534,6 +539,14 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
 	return ret;
 }
 
+/**
+ * macronix_set_4byte() - Set 4-byte address mode for Macronix flashes.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @enable:	true to enter the 4-byte address mode, false to exit the 4-byte
+ *		address mode.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int macronix_set_4byte(struct spi_nor *nor, bool enable)
 {
 	int ret;
@@ -562,6 +575,14 @@ static int macronix_set_4byte(struct spi_nor *nor, bool enable)
 	return ret;
 }
 
+/**
+ * st_micron_set_4byte() - Set 4-byte address mode for ST and Micron flashes.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @enable:	true to enter the 4-byte address mode, false to exit the 4-byte
+ *		address mode.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
 {
 	int ret;
@@ -577,6 +598,14 @@ static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
 	return spi_nor_write_disable(nor);
 }
 
+/**
+ * spansion_set_4byte() - Set 4-byte address mode for Spansion flashes.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @enable:	true to enter the 4-byte address mode, false to exit the 4-byte
+ *		address mode.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spansion_set_4byte(struct spi_nor *nor, bool enable)
 {
 	int ret;
@@ -602,6 +631,13 @@ static int spansion_set_4byte(struct spi_nor *nor, bool enable)
 	return ret;
 }
 
+/**
+ * spi_nor_write_ear() - Write Extended Address Register.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @ear:	value to write to the Extended Address Register.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_write_ear(struct spi_nor *nor, u8 ear)
 {
 	int ret;
@@ -627,6 +663,14 @@ static int spi_nor_write_ear(struct spi_nor *nor, u8 ear)
 	return ret;
 }
 
+/**
+ * winbond_set_4byte() - Set 4-byte address mode for Winbond flashes.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @enable:	true to enter the 4-byte address mode, false to exit the 4-byte
+ *		address mode.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int winbond_set_4byte(struct spi_nor *nor, bool enable)
 {
 	int ret;
@@ -651,6 +695,14 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable)
 	return spi_nor_write_disable(nor);
 }
 
+/**
+ * spi_nor_xread_sr() - Read the Status Register on S3AN flashes.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @sr:		pointer to a DMA-able buffer where the value of the
+ *              Status Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
 {
 	int ret;
@@ -674,6 +726,13 @@ static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
 	return ret;
 }
 
+/**
+ * s3an_sr_ready() - Query the Status Register of the S3AN flash to see if the
+ * flash is ready for new commands.
+ * @nor:	pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int s3an_sr_ready(struct spi_nor *nor)
 {
 	int ret;
@@ -685,6 +744,10 @@ static int s3an_sr_ready(struct spi_nor *nor)
 	return !!(nor->bouncebuf[0] & XSR_RDY);
 }
 
+/**
+ * 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;
@@ -706,6 +769,13 @@ static void spi_nor_clear_sr(struct spi_nor *nor)
 		dev_err(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.
+ * @nor:	pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_sr_ready(struct spi_nor *nor)
 {
 	int ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
@@ -727,6 +797,10 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
 	return !(nor->bouncebuf[0] & SR_WIP);
 }
 
+/**
+ * spi_nor_clear_fsr() - Clear the Flag Status Register.
+ * @nor:	pointer to 'struct spi_nor'.
+ */
 static void spi_nor_clear_fsr(struct spi_nor *nor)
 {
 	int ret;
@@ -748,6 +822,13 @@ static void spi_nor_clear_fsr(struct spi_nor *nor)
 		dev_err(nor->dev, "error %d clearing FSR\n", ret);
 }
 
+/**
+ * spi_nor_fsr_ready() - Query the Flag Status Register to see if the flash is
+ * ready for new commands.
+ * @nor:	pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_fsr_ready(struct spi_nor *nor)
 {
 	int ret = spi_nor_read_fsr(nor, &nor->bouncebuf[0]);
@@ -772,6 +853,12 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
 	return nor->bouncebuf[0] & FSR_READY;
 }
 
+/**
+ * spi_nor_ready() - Query the flash to see if it is ready for new commands.
+ * @nor:	pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_ready(struct spi_nor *nor)
 {
 	int sr, fsr;
@@ -788,9 +875,13 @@ static int spi_nor_ready(struct spi_nor *nor)
 	return sr && fsr;
 }
 
-/*
- * Service routine to read status register until ready, or timeout occurs.
- * Returns non-zero if error.
+/**
+ * spi_nor_wait_till_ready_with_timeout() - Service routine to read the
+ * Status Register until ready, or timeout occurs.
+ * @nor:		pointer to "struct spi_nor".
+ * @timeout_jiffies:	jiffies to wait until timeout.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
 static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
 						unsigned long timeout_jiffies)
@@ -818,6 +909,13 @@ static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
 	return -ETIMEDOUT;
 }
 
+/**
+ * spi_nor_wait_till_ready() - Wait for a predefined amount of time for the
+ * flash to be ready, or timeout occurs.
+ * @nor:	pointer to "struct spi_nor".
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_wait_till_ready(struct spi_nor *nor)
 {
 	return spi_nor_wait_till_ready_with_timeout(nor,
@@ -880,6 +978,14 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 	return ((nor->bouncebuf[0] & mask) != (status_new & mask)) ? -EIO : 0;
 }
 
+/**
+ * spi_nor_write_sr2() - Write the Status Register 2 using the
+ * SPINOR_OP_WRSR2 (3eh) command.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @sr2:	pointer to DMA-able buffer to write to the Status Register 2.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)
 {
 	int ret;
@@ -909,6 +1015,15 @@ static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)
 	return spi_nor_wait_till_ready(nor);
 }
 
+/**
+ * spi_nor_read_sr2() - Read the Status Register 2 using the
+ * SPINOR_OP_RDSR2 (3fh) command.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @sr2:	pointer to DMA-able buffer where the value of the
+ *		Status Register 2 will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
 {
 	int ret;
@@ -932,10 +1047,11 @@ static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
 	return ret;
 }
 
-/*
- * Erase the whole flash memory
+/**
+ * spi_nor_erase_chip() - Erase the entire flash memory.
+ * @nor:	pointer to 'struct spi_nor'.
  *
- * Returns 0 if successful, non-zero otherwise.
+ * Return: 0 on success, -errno otherwise.
  */
 static int spi_nor_erase_chip(struct spi_nor *nor)
 {
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 21/32] mtd: spi-nor: Drop spansion_quad_enable()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (19 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 20/32] mtd: spi-nor: Describe all the Reg Ops Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 22/32] mtd: spi-nor: Fix errno on Quad Enable methods Tudor.Ambarus
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Drop the default spansion_quad_enable() method and replace it with
spansion_read_cr_quad_enable().

The function was buggy, it didn't care about the previous values
of the Status and Configuration Registers. spansion_read_cr_quad_enable()
is a Read-Modify-Write-Check function that keeps track of what were
the previous values of the Status and Configuration Registers.

In terms of instruction types sent to the flash, the only difference
between the spansion_quad_enable() and spansion_read_cr_quad_enable()
is that the later calls spi_nor_read_sr(). We can safely assume that all
flashes support spi_nor_read_sr(), because all flashes call it in
spi_nor_sr_ready(). The transition from spansion_quad_enable() to
spansion_read_cr_quad_enable() will not affect anybody, drop the buggy
code.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 58 ++++---------------------------------------
 1 file changed, 5 insertions(+), 53 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 6102318cfd03..721e5307fabf 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1971,54 +1971,6 @@ static int macronix_quad_enable(struct spi_nor *nor)
 }
 
 /**
- * spansion_quad_enable() - set QE bit in Configuraiton Register.
- * @nor:	pointer to a 'struct spi_nor'
- *
- * Set the Quad Enable (QE) bit in the Configuration Register.
- * This function is kept for legacy purpose because it has been used for a
- * long time without anybody complaining but it should be considered as
- * deprecated and maybe buggy.
- * First, this function doesn't care about the previous values of the Status
- * and Configuration Registers when it sets the QE bit (bit 1) in the
- * Configuration Register: all other bits are cleared, which may have unwanted
- * side effects like removing some block protections.
- * Secondly, it uses the Read Configuration Register (35h) instruction though
- * some very old and few memories don't support this instruction. If a pull-up
- * resistor is present on the MISO/IO1 line, we might still be able to pass the
- * "read back" test because the QSPI memory doesn't recognize the command,
- * so leaves the MISO/IO1 line state unchanged, hence spi_nor_read_cr() returns
- * 0xFF.
- *
- * bit 1 of the Configuration Register is the QE bit for Spansion like QSPI
- * memories.
- *
- * Return: 0 on success, -errno otherwise.
- */
-static int spansion_quad_enable(struct spi_nor *nor)
-{
-	u8 *sr_cr = nor->bouncebuf;
-	int ret;
-
-	sr_cr[0] = 0;
-	sr_cr[1] = CR_QUAD_EN_SPAN;
-	ret = spi_nor_write_sr(nor, sr_cr, 2);
-	if (ret)
-		return ret;
-
-	/* read back and check it */
-	ret = spi_nor_read_cr(nor, &nor->bouncebuf[0]);
-	if (ret)
-		return ret;
-
-	if (!(nor->bouncebuf[0] & CR_QUAD_EN_SPAN)) {
-		dev_err(nor->dev, "Spansion Quad bit not set\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/**
  * spansion_no_read_cr_quad_enable() - set QE bit in Configuration Register.
  * @nor:	pointer to a 'struct spi_nor'
  *
@@ -2170,9 +2122,9 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
  *
  * Read-modify-write function that clears the Block Protection bits from the
  * Status Register without affecting other bits. The function is tightly
- * coupled with the spansion_quad_enable() function. Both assume that the Write
- * Register with 16 bits, together with the Read Configuration Register (35h)
- * instructions are supported.
+ * coupled with the spansion_read_cr_quad_enable() function. Both assume that
+ * the Write Register with 16 bits, together with the Read Configuration
+ * Register (35h) instructions are supported.
  *
  * Return: 0 on success, -errno otherwise.
  */
@@ -4654,7 +4606,7 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	u8 i, erase_mask;
 
 	/* Initialize legacy flash parameters and settings. */
-	params->quad_enable = spansion_quad_enable;
+	params->quad_enable = spansion_read_cr_quad_enable;
 	params->set_4byte = spansion_set_4byte;
 	params->setup = spi_nor_default_setup;
 
@@ -4869,7 +4821,7 @@ static int spi_nor_init(struct spi_nor *nor)
 	int err;
 
 	if (nor->clear_sr_bp) {
-		if (nor->params.quad_enable == spansion_quad_enable)
+		if (nor->params.quad_enable == spansion_read_cr_quad_enable)
 			nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
 
 		err = nor->clear_sr_bp(nor);
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 22/32] mtd: spi-nor: Fix errno on Quad Enable methods
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (20 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 21/32] mtd: spi-nor: Drop spansion_quad_enable() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 23/32] mtd: spi-nor: Check all the bits written, not just the BP ones Tudor.Ambarus
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

When the Read-Modify-Write-Read-Back Quad Enable methods failed on
the Read-Back, they returned -EINVAL. Since this is an I/O error,
return -EIO.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 721e5307fabf..21a974b88c3b 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1964,7 +1964,7 @@ static int macronix_quad_enable(struct spi_nor *nor)
 
 	if (!(nor->bouncebuf[0] & SR_QUAD_EN_MX)) {
 		dev_err(nor->dev, "Macronix Quad bit not set\n");
-		return -EINVAL;
+		return -EIO;
 	}
 
 	return 0;
@@ -2042,7 +2042,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 
 	if (!(sr_cr[1] & CR_QUAD_EN_SPAN)) {
 		dev_err(nor->dev, "Spansion Quad bit not set\n");
-		return -EINVAL;
+		return -EIO;
 	}
 
 	return 0;
@@ -2086,7 +2086,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 
 	if (!(*sr2 & SR2_QUAD_EN_BIT7)) {
 		dev_err(nor->dev, "SR2 Quad bit not set\n");
-		return -EINVAL;
+		return -EIO;
 	}
 
 	return 0;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 23/32] mtd: spi-nor: Check all the bits written, not just the BP ones
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (21 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 22/32] mtd: spi-nor: Fix errno on Quad Enable methods Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 24/32] mtd: spi-nor: Print error message when the read back test fails Tudor.Ambarus
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Check that all the bits written in the write_sr_and_check() method
match the status_new received value. Failing to write the other bits
is dangerous too, extend the check.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 21a974b88c3b..5b30fc73fdba 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -960,8 +960,7 @@ static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
 }
 
 /* Write status register and ensure bits in mask match written values */
-static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
-				      u8 mask)
+static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new)
 {
 	int ret;
 
@@ -975,7 +974,7 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
 	if (ret)
 		return ret;
 
-	return ((nor->bouncebuf[0] & mask) != (status_new & mask)) ? -EIO : 0;
+	return (nor->bouncebuf[0] != status_new) ? -EIO : 0;
 }
 
 /**
@@ -1774,7 +1773,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	if ((status_new & mask) < (status_old & mask))
 		return -EINVAL;
 
-	return spi_nor_write_sr_and_check(nor, status_new, mask);
+	return spi_nor_write_sr_and_check(nor, status_new);
 }
 
 /*
@@ -1859,7 +1858,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	if ((status_new & mask) > (status_old & mask))
 		return -EINVAL;
 
-	return spi_nor_write_sr_and_check(nor, status_new, mask);
+	return spi_nor_write_sr_and_check(nor, status_new);
 }
 
 /*
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 24/32] mtd: spi-nor: Print error message when the read back test fails
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (22 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 23/32] mtd: spi-nor: Check all the bits written, not just the BP ones Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 25/32] mtd: spi-nor: Fix clearing of QE bit on lock()/unlock() Tudor.Ambarus
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Demystify where the EIO error occurs.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 5b30fc73fdba..30ce83426266 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -974,7 +974,12 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new)
 	if (ret)
 		return ret;
 
-	return (nor->bouncebuf[0] != status_new) ? -EIO : 0;
+	if (nor->bouncebuf[0] != status_new) {
+		dev_err(nor->dev, "SR: read back test failed\n");
+		return -EIO;
+	}
+
+	return 0;
 }
 
 /**
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 25/32] mtd: spi-nor: Fix clearing of QE bit on lock()/unlock()
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (23 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 24/32] mtd: spi-nor: Print error message when the read back test fails Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 26/32] mtd: spi-nor: Extend the QE Read Back test to the entire SR byte Tudor.Ambarus
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Make sure that when doing a lock() or an unlock() operation we don't clear
the QE bit from Status Register 2.

JESD216 revB or later offers information about the *default* Status
Register commands to use (see BFPT DWORDS[15], bits 22:20). In this
standard, Status Register 1 refers to the first data byte transferred on a
Read Status (05h) or Write Status (01h) command. Status register 2 refers
to the byte read using instruction 35h. Status register 2 is the second
byte transferred in a Write Status (01h) command.

Industry naming and definitions of these Status Registers may differ.
The definitions are described in JESD216B, BFPT DWORDS[15], bits 22:20.
There are cases in which writing only one byte to the Status Register 1
has the side-effect of clearing Status Register 2 and implicitly the Quad
Enable bit. This side-effect is hit just by the
BFPT_DWORD15_QER_SR2_BIT1_BUGGY and BFPT_DWORD15_QER_SR2_BIT1 cases.

Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 120 ++++++++++++++++++++++++++++++++++++++++--
 include/linux/mtd/spi-nor.h   |   3 ++
 2 files changed, 118 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 30ce83426266..0dcc4f12e4de 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -959,12 +959,19 @@ static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
 	return spi_nor_wait_till_ready(nor);
 }
 
-/* Write status register and ensure bits in mask match written values */
-static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new)
+/**
+ * spi_nor_write_sr1_and_check() - Write one byte to the Status Register 1 and
+ * ensure that the byte written match the received value.
+ * @nor:	pointer to a 'struct spi_nor'.
+ * @sr1:	byte value to be written to the Status Register.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_write_sr1_and_check(struct spi_nor *nor, u8 sr1)
 {
 	int ret;
 
-	nor->bouncebuf[0] = status_new;
+	nor->bouncebuf[0] = sr1;
 
 	ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
 	if (ret)
@@ -974,8 +981,73 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new)
 	if (ret)
 		return ret;
 
-	if (nor->bouncebuf[0] != status_new) {
-		dev_err(nor->dev, "SR: read back test failed\n");
+	if (nor->bouncebuf[0] != sr1) {
+		dev_err(nor->dev, "SR1: read back test failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * spi_nor_write_16bit_sr_and_check() - Write the Status Register 1 and the
+ * Status Register 2 in one shot. Ensure that the byte written in the Status
+ * Register 1 match the received value, and that the 16-bit Write did not
+ * affect what was already in the Status Register 2.
+ * @nor:	pointer to a 'struct spi_nor'.
+ * @sr1:	byte value to be written to the Status Register 1.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)
+{
+	int ret;
+	u8 *sr_cr = nor->bouncebuf;
+	u8 cr_written;
+
+	/* Make sure we don't overwrite the contents of Status Register 2. */
+	if (!(nor->flags & SNOR_F_NO_READ_CR)) {
+		ret = spi_nor_read_cr(nor, &sr_cr[1]);
+		if (ret)
+			return ret;
+	} else if (nor->params.quad_enable) {
+		/*
+		 * If the Status Register 2 Read command (35h) is not
+		 * supported, we should at least be sure we don't
+		 * change the value of the SR2 Quad Enable bit.
+		 *
+		 * We can safely assume that when the Quad Enable method is
+		 * set, the value of the QE bit is one, as a consequence of the
+		 * nor->params.quad_enable() call.
+		 *
+		 * We can safely assume that the Quad Enable bit is present in
+		 * the Status Register 2 at BIT(1). According to the JESD216
+		 * revB standard, BFPT DWORDS[15], bits 22:20, the 16-bit
+		 * Write Status (01h) command is available just for the cases
+		 * in which the QE bit is described in SR2 at BIT(1).
+		 */
+		sr_cr[1] = CR_QUAD_EN_SPAN;
+	} else {
+		sr_cr[1] = 0;
+	}
+
+	sr_cr[0] = sr1;
+
+	ret = spi_nor_write_sr(nor, sr_cr, 2);
+	if (ret)
+		return ret;
+
+	if (nor->flags & SNOR_F_NO_READ_CR)
+		return 0;
+
+	cr_written = sr_cr[1];
+
+	ret = spi_nor_read_cr(nor, &sr_cr[1]);
+	if (ret)
+		return ret;
+
+	if (cr_written != sr_cr[1]) {
+		dev_err(nor->dev, "CR: read back test failed\n");
 		return -EIO;
 	}
 
@@ -983,6 +1055,23 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new)
 }
 
 /**
+ * spi_nor_write_sr_and_check() - Write the Status Register 1 and ensure that
+ * the byte written match the received value without affecting other bits in the
+ * Status Register 1 and 2.
+ * @nor:	pointer to a 'struct spi_nor'.
+ * @sr1:	byte value to be written to the Status Register.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1)
+{
+	if (nor->flags & SNOR_F_HAS_16BIT_SR)
+		return spi_nor_write_16bit_sr_and_check(nor, sr1);
+
+	return spi_nor_write_sr1_and_check(nor, sr1);
+}
+
+/**
  * spi_nor_write_sr2() - Write the Status Register 2 using the
  * SPINOR_OP_WRSR2 (3eh) command.
  * @nor:	pointer to 'struct spi_nor'.
@@ -3634,19 +3723,38 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		break;
 
 	case BFPT_DWORD15_QER_SR2_BIT1_BUGGY:
+		/*
+		 * Writing only one byte to the Status Register has the
+		 * side-effect of clearing Status Register 2.
+		 */
 	case BFPT_DWORD15_QER_SR2_BIT1_NO_RD:
+		/*
+		 * Read Configuration Register (35h) instruction is not
+		 * supported.
+		 */
+		nor->flags |= SNOR_F_HAS_16BIT_SR | SNOR_F_NO_READ_CR;
 		params->quad_enable = spansion_no_read_cr_quad_enable;
 		break;
 
 	case BFPT_DWORD15_QER_SR1_BIT6:
+		nor->flags &= ~SNOR_F_HAS_16BIT_SR;
 		params->quad_enable = macronix_quad_enable;
 		break;
 
 	case BFPT_DWORD15_QER_SR2_BIT7:
+		nor->flags &= ~SNOR_F_HAS_16BIT_SR;
 		params->quad_enable = sr2_bit7_quad_enable;
 		break;
 
 	case BFPT_DWORD15_QER_SR2_BIT1:
+		/*
+		 * JESD216 rev B or later does not specify if writing only one
+		 * byte to the Status Register clears or not the Status
+		 * Register 2, so let's be cautious and keep the default
+		 * assumption of a 16-bit Write Status (01h) command.
+		 */
+		nor->flags |= SNOR_F_HAS_16BIT_SR;
+
 		params->quad_enable = spansion_read_cr_quad_enable;
 		break;
 
@@ -4613,6 +4721,8 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	params->quad_enable = spansion_read_cr_quad_enable;
 	params->set_4byte = spansion_set_4byte;
 	params->setup = spi_nor_default_setup;
+	/* Default to 16-bit Write Status (01h) Command */
+	nor->flags |= SNOR_F_HAS_16BIT_SR;
 
 	/* Set SPI NOR sizes. */
 	params->size = (u64)info->sector_size * info->n_sectors;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index d1d736d3c8ab..d6ec55cc6d97 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -243,6 +243,9 @@ enum spi_nor_option_flags {
 	SNOR_F_4B_OPCODES	= BIT(6),
 	SNOR_F_HAS_4BAIT	= BIT(7),
 	SNOR_F_HAS_LOCK		= BIT(8),
+	SNOR_F_HAS_16BIT_SR	= BIT(9),
+	SNOR_F_NO_READ_CR	= BIT(10),
+
 };
 
 /**
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 26/32] mtd: spi-nor: Extend the QE Read Back test to the entire SR byte
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (24 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 25/32] mtd: spi-nor: Fix clearing of QE bit on lock()/unlock() Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 27/32] mtd: spi-nor: Extend the QE Read Back test to both SR1 and SR2 Tudor.Ambarus
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Extend the Quad Enable Read Back test to the entire Status
Register byte. Make sure that other bits were not changed.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0dcc4f12e4de..55a12a1d710e 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2047,20 +2047,7 @@ static int macronix_quad_enable(struct spi_nor *nor)
 
 	nor->bouncebuf[0] |= SR_QUAD_EN_MX;
 
-	ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
-	if (ret)
-		return ret;
-
-	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
-	if (ret)
-		return ret;
-
-	if (!(nor->bouncebuf[0] & SR_QUAD_EN_MX)) {
-		dev_err(nor->dev, "Macronix Quad bit not set\n");
-		return -EIO;
-	}
-
-	return 0;
+	return spi_nor_write_sr1_and_check(nor, nor->bouncebuf[0]);
 }
 
 /**
@@ -2108,6 +2095,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 {
 	u8 *sr_cr = nor->bouncebuf;
 	int ret;
+	u8 sr_written;
 
 	/* Check current Quad Enable bit value. */
 	ret = spi_nor_read_cr(nor, &sr_cr[1]);
@@ -2128,13 +2116,15 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
+	sr_written = sr_cr[1];
+
 	/* Read back and check it. */
 	ret = spi_nor_read_cr(nor, &sr_cr[1]);
 	if (ret)
 		return ret;
 
-	if (!(sr_cr[1] & CR_QUAD_EN_SPAN)) {
-		dev_err(nor->dev, "Spansion Quad bit not set\n");
+	if (sr_cr[1] != sr_written) {
+		dev_err(nor->dev, "SR2: Read back test failed\n");
 		return -EIO;
 	}
 
@@ -2157,6 +2147,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 {
 	u8 *sr2 = nor->bouncebuf;
 	int ret;
+	u8 sr2_written;
 
 	/* Check current Quad Enable bit value. */
 	ret = spi_nor_read_sr2(nor, sr2);
@@ -2172,13 +2163,15 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
+	sr2_written = *sr2;
+
 	/* Read back and check it. */
 	ret = spi_nor_read_sr2(nor, sr2);
 	if (ret)
 		return ret;
 
-	if (!(*sr2 & SR2_QUAD_EN_BIT7)) {
-		dev_err(nor->dev, "SR2 Quad bit not set\n");
+	if (*sr2 != sr2_written) {
+		dev_err(nor->dev, "Read back test failed\n");
 		return -EIO;
 	}
 
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 27/32] mtd: spi-nor: Extend the QE Read Back test to both SR1 and SR2
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (25 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 26/32] mtd: spi-nor: Extend the QE Read Back test to the entire SR byte Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 28/32] mtd: spi-nor: Rename CR_QUAD_EN_SPAN to SR2_QUAD_EN_BIT1 Tudor.Ambarus
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

In case of 16-bit Write Status Register, check that both SR1 and
SR2 were written correctly.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 55a12a1d710e..eecbd161df25 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2067,6 +2067,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 {
 	u8 *sr_cr = nor->bouncebuf;
 	int ret;
+	u8 sr_written;
 
 	/* Keep the current value of the Status Register. */
 	ret = spi_nor_read_sr(nor, &sr_cr[0]);
@@ -2075,7 +2076,22 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 
 	sr_cr[1] = CR_QUAD_EN_SPAN;
 
-	return spi_nor_write_sr(nor, sr_cr, 2);
+	ret = spi_nor_write_sr(nor, sr_cr, 2);
+	if (ret)
+		return ret;
+
+	sr_written = sr_cr[0];
+
+	ret = spi_nor_read_sr(nor, &sr_cr[0]);
+	if (ret)
+		return ret;
+
+	if (sr_cr[0] != sr_written) {
+		dev_err(nor->dev, "SR1: Read back test failed\n");
+		return -EIO;
+	}
+
+	return 0;
 }
 
 /**
@@ -2116,6 +2132,17 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
+	sr_written = sr_cr[0];
+
+	ret = spi_nor_read_sr(nor, &sr_cr[0]);
+	if (ret)
+		return ret;
+
+	if (sr_written != sr_cr[0]) {
+		dev_err(nor->dev, "SR1: Read back test failed\n");
+		return -EIO;
+	}
+
 	sr_written = sr_cr[1];
 
 	/* Read back and check it. */
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 28/32] mtd: spi-nor: Rename CR_QUAD_EN_SPAN to SR2_QUAD_EN_BIT1
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (26 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 27/32] mtd: spi-nor: Extend the QE Read Back test to both SR1 and SR2 Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 29/32] mtd: spi-nor: Merge spansion Quad Enable methods Tudor.Ambarus
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

JEDEC Basic Flash Parameter Table, 15th DWORD, bits 22:20,
refers to this bit as "bit 1 of the status register 2".
Rename the macro accordingly.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 10 +++++-----
 include/linux/mtd/spi-nor.h   |  4 +---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index eecbd161df25..1f7ccd80b8ed 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1026,7 +1026,7 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)
 		 * Write Status (01h) command is available just for the cases
 		 * in which the QE bit is described in SR2 at BIT(1).
 		 */
-		sr_cr[1] = CR_QUAD_EN_SPAN;
+		sr_cr[1] = SR2_QUAD_EN_BIT1;
 	} else {
 		sr_cr[1] = 0;
 	}
@@ -2074,7 +2074,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	sr_cr[1] = CR_QUAD_EN_SPAN;
+	sr_cr[1] = SR2_QUAD_EN_BIT1;
 
 	ret = spi_nor_write_sr(nor, sr_cr, 2);
 	if (ret)
@@ -2118,10 +2118,10 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	if (sr_cr[1] & CR_QUAD_EN_SPAN)
+	if (sr_cr[1] & SR2_QUAD_EN_BIT1)
 		return 0;
 
-	sr_cr[1] |= CR_QUAD_EN_SPAN;
+	sr_cr[1] |= SR2_QUAD_EN_BIT1;
 
 	/* Keep the current value of the Status Register. */
 	ret = spi_nor_read_sr(nor, &sr_cr[0]);
@@ -2256,7 +2256,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 	 * When the configuration register Quad Enable bit is one, only the
 	 * Write Status (01h) command with two data bytes may be used.
 	 */
-	if (sr_cr[1] & CR_QUAD_EN_SPAN) {
+	if (sr_cr[1] & SR2_QUAD_EN_BIT1) {
 		ret = spi_nor_read_sr(nor, &sr_cr[0]);
 		if (ret)
 			return ret;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index d6ec55cc6d97..f626e0e52909 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -144,10 +144,8 @@
 #define FSR_P_ERR		BIT(4)	/* Program operation status */
 #define FSR_PT_ERR		BIT(1)	/* Protection error bit */
 
-/* Configuration Register bits. */
-#define CR_QUAD_EN_SPAN		BIT(1)	/* Spansion Quad I/O */
-
 /* Status Register 2 bits. */
+#define SR2_QUAD_EN_BIT1	BIT(1)
 #define SR2_QUAD_EN_BIT7	BIT(7)
 
 /* Supported SPI protocols */
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 29/32] mtd: spi-nor: Merge spansion Quad Enable methods
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (27 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 28/32] mtd: spi-nor: Rename CR_QUAD_EN_SPAN to SR2_QUAD_EN_BIT1 Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 30/32] mtd: spi-nor: Rename macronix_quad_enable to spi_nor_sr1_bit6_quad_enable Tudor.Ambarus
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Merge
    spansion_no_read_cr_quad_enable()
    spansion_read_cr_quad_enable()
into
    spi_nor_sr2_bit1_quad_enable().

Reduce code duplication by introducing spi_nor_write_16bit_cr_and_check().
The Configuration Register contains bits that can be updated in future:
FREEZE, CMP. Provide a generic method that allows updating all bits
of the Configuration Register.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 165 +++++++++++++++++-------------------------
 1 file changed, 68 insertions(+), 97 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 1f7ccd80b8ed..ab028afc503f 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1055,6 +1055,59 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)
 }
 
 /**
+ * spi_nor_write_16bit_cr_and_check() - Write the Status Register 1 and the
+ * Configuration Register in one shot. Ensure that the byte written in the
+ * Configuration Register match the received value, and that the 16-bit Write
+ * did not affect what was already in the Status Register 1.
+ * @nor:	pointer to a 'struct spi_nor'.
+ * @cr:		byte value to be written to the Configuration Register.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_write_16bit_cr_and_check(struct spi_nor *nor, u8 cr)
+{
+	int ret;
+	u8 *sr_cr = nor->bouncebuf;
+	u8 sr_written;
+
+	/* Keep the current value of the Status Register 1. */
+	ret = spi_nor_read_sr(nor, &sr_cr[0]);
+	if (ret)
+		return ret;
+
+	sr_cr[1] = cr;
+
+	ret = spi_nor_write_sr(nor, sr_cr, 2);
+	if (ret)
+		return ret;
+
+	sr_written = sr_cr[0];
+
+	ret = spi_nor_read_sr(nor, &sr_cr[0]);
+	if (ret)
+		return ret;
+
+	if (sr_written != sr_cr[0]) {
+		dev_err(nor->dev, "SR1: Read back test failed\n");
+		return -EIO;
+	}
+
+	if (nor->flags & SNOR_F_NO_READ_CR)
+		return 0;
+
+	ret = spi_nor_read_cr(nor, &sr_cr[1]);
+	if (ret)
+		return ret;
+
+	if (cr != sr_cr[1]) {
+		dev_err(nor->dev, "CR: read back test failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
  * spi_nor_write_sr_and_check() - Write the Status Register 1 and ensure that
  * the byte written match the received value without affecting other bits in the
  * Status Register 1 and 2.
@@ -2051,111 +2104,29 @@ static int macronix_quad_enable(struct spi_nor *nor)
 }
 
 /**
- * spansion_no_read_cr_quad_enable() - set QE bit in Configuration Register.
- * @nor:	pointer to a 'struct spi_nor'
+ * spi_nor_sr2_bit1_quad_enable() - set the Quad Enable BIT(1) in the Status
+ * Register 2.
+ * @nor:       pointer to a 'struct spi_nor'.
  *
- * Set the Quad Enable (QE) bit in the Configuration Register.
- * This function should be used with QSPI memories not supporting the Read
- * Configuration Register (35h) instruction.
- *
- * bit 1 of the Configuration Register is the QE bit for Spansion like QSPI
- * memories.
+ * Bit 1 of the Status Register 2 is the QE bit for Spansion like QSPI memories.
  *
  * Return: 0 on success, -errno otherwise.
  */
-static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
+static int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
 {
-	u8 *sr_cr = nor->bouncebuf;
 	int ret;
-	u8 sr_written;
-
-	/* Keep the current value of the Status Register. */
-	ret = spi_nor_read_sr(nor, &sr_cr[0]);
-	if (ret)
-		return ret;
-
-	sr_cr[1] = SR2_QUAD_EN_BIT1;
-
-	ret = spi_nor_write_sr(nor, sr_cr, 2);
-	if (ret)
-		return ret;
 
-	sr_written = sr_cr[0];
-
-	ret = spi_nor_read_sr(nor, &sr_cr[0]);
-	if (ret)
-		return ret;
-
-	if (sr_cr[0] != sr_written) {
-		dev_err(nor->dev, "SR1: Read back test failed\n");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-/**
- * spansion_read_cr_quad_enable() - set QE bit in Configuration Register.
- * @nor:	pointer to a 'struct spi_nor'
- *
- * Set the Quad Enable (QE) bit in the Configuration Register.
- * This function should be used with QSPI memories supporting the Read
- * Configuration Register (35h) instruction.
- *
- * bit 1 of the Configuration Register is the QE bit for Spansion like QSPI
- * memories.
- *
- * Return: 0 on success, -errno otherwise.
- */
-static int spansion_read_cr_quad_enable(struct spi_nor *nor)
-{
-	u8 *sr_cr = nor->bouncebuf;
-	int ret;
-	u8 sr_written;
+	if (nor->flags & SNOR_F_NO_READ_CR)
+		return spi_nor_write_16bit_cr_and_check(nor, SR2_QUAD_EN_BIT1);
 
-	/* Check current Quad Enable bit value. */
-	ret = spi_nor_read_cr(nor, &sr_cr[1]);
+	ret = spi_nor_read_cr(nor, &nor->bouncebuf[0]);
 	if (ret)
 		return ret;
 
-	if (sr_cr[1] & SR2_QUAD_EN_BIT1)
+	if (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)
 		return 0;
 
-	sr_cr[1] |= SR2_QUAD_EN_BIT1;
-
-	/* Keep the current value of the Status Register. */
-	ret = spi_nor_read_sr(nor, &sr_cr[0]);
-	if (ret)
-		return ret;
-
-	ret = spi_nor_write_sr(nor, sr_cr, 2);
-	if (ret)
-		return ret;
-
-	sr_written = sr_cr[0];
-
-	ret = spi_nor_read_sr(nor, &sr_cr[0]);
-	if (ret)
-		return ret;
-
-	if (sr_written != sr_cr[0]) {
-		dev_err(nor->dev, "SR1: Read back test failed\n");
-		return -EIO;
-	}
-
-	sr_written = sr_cr[1];
-
-	/* Read back and check it. */
-	ret = spi_nor_read_cr(nor, &sr_cr[1]);
-	if (ret)
-		return ret;
-
-	if (sr_cr[1] != sr_written) {
-		dev_err(nor->dev, "SR2: Read back test failed\n");
-		return -EIO;
-	}
-
-	return 0;
+	return spi_nor_write_16bit_cr_and_check(nor, nor->bouncebuf[0]);
 }
 
 /**
@@ -2235,7 +2206,7 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
  *
  * Read-modify-write function that clears the Block Protection bits from the
  * Status Register without affecting other bits. The function is tightly
- * coupled with the spansion_read_cr_quad_enable() function. Both assume that
+ * coupled with the spi_nor_sr2_bit1_quad_enable() function. Both assume that
  * the Write Register with 16 bits, together with the Read Configuration
  * Register (35h) instructions are supported.
  *
@@ -3753,7 +3724,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		 * supported.
 		 */
 		nor->flags |= SNOR_F_HAS_16BIT_SR | SNOR_F_NO_READ_CR;
-		params->quad_enable = spansion_no_read_cr_quad_enable;
+		params->quad_enable = spi_nor_sr2_bit1_quad_enable;
 		break;
 
 	case BFPT_DWORD15_QER_SR1_BIT6:
@@ -3775,7 +3746,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		 */
 		nor->flags |= SNOR_F_HAS_16BIT_SR;
 
-		params->quad_enable = spansion_read_cr_quad_enable;
+		params->quad_enable = spi_nor_sr2_bit1_quad_enable;
 		break;
 
 	default:
@@ -4738,7 +4709,7 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	u8 i, erase_mask;
 
 	/* Initialize legacy flash parameters and settings. */
-	params->quad_enable = spansion_read_cr_quad_enable;
+	params->quad_enable = spi_nor_sr2_bit1_quad_enable;
 	params->set_4byte = spansion_set_4byte;
 	params->setup = spi_nor_default_setup;
 	/* Default to 16-bit Write Status (01h) Command */
@@ -4955,7 +4926,7 @@ static int spi_nor_init(struct spi_nor *nor)
 	int err;
 
 	if (nor->clear_sr_bp) {
-		if (nor->params.quad_enable == spansion_read_cr_quad_enable)
+		if (nor->params.quad_enable == spi_nor_sr2_bit1_quad_enable)
 			nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
 
 		err = nor->clear_sr_bp(nor);
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 30/32] mtd: spi-nor: Rename macronix_quad_enable to spi_nor_sr1_bit6_quad_enable
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (28 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 29/32] mtd: spi-nor: Merge spansion Quad Enable methods Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 31/32] mtd: spi-nor: Prepend "spi_nor_" to "sr2_bit7_quad_enable" Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 32/32] mtd: spi-nor: Rework the disabling of block write protection Tudor.Ambarus
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Rename method to a generic name: spi_nor_sr1_bit6_quad_enable().

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 19 +++++++++----------
 include/linux/mtd/spi-nor.h   |  2 +-
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index ab028afc503f..47d159959461 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2078,16 +2078,15 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 }
 
 /**
- * macronix_quad_enable() - set QE bit in Status Register.
+ * spi_nor_sr1_bit6_quad_enable() - Set the Quad Enable BIT(6) in the Status
+ * Register 1.
  * @nor:	pointer to a 'struct spi_nor'
  *
- * Set the Quad Enable (QE) bit in the Status Register.
- *
- * bit 6 of the Status Register is the QE bit for Macronix like QSPI memories.
+ * Bit 6 of the Status Register 1 is the QE bit for Macronix like QSPI memories.
  *
  * Return: 0 on success, -errno otherwise.
  */
-static int macronix_quad_enable(struct spi_nor *nor)
+static int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor)
 {
 	int ret;
 
@@ -2095,10 +2094,10 @@ static int macronix_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
+	if (nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)
 		return 0;
 
-	nor->bouncebuf[0] |= SR_QUAD_EN_MX;
+	nor->bouncebuf[0] |= SR1_QUAD_EN_BIT6;
 
 	return spi_nor_write_sr1_and_check(nor, nor->bouncebuf[0]);
 }
@@ -2349,7 +2348,7 @@ static void gd25q256_default_init(struct spi_nor *nor)
 	 * indicate the quad_enable method for this case, we need
 	 * to set it in the default_init fixup hook.
 	 */
-	nor->params.quad_enable = macronix_quad_enable;
+	nor->params.quad_enable = spi_nor_sr1_bit6_quad_enable;
 }
 
 static struct spi_nor_fixups gd25q256_fixups = {
@@ -3729,7 +3728,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 
 	case BFPT_DWORD15_QER_SR1_BIT6:
 		nor->flags &= ~SNOR_F_HAS_16BIT_SR;
-		params->quad_enable = macronix_quad_enable;
+		params->quad_enable = spi_nor_sr1_bit6_quad_enable;
 		break;
 
 	case BFPT_DWORD15_QER_SR2_BIT7:
@@ -4627,7 +4626,7 @@ static int spi_nor_setup(struct spi_nor *nor,
 
 static void macronix_set_default_init(struct spi_nor *nor)
 {
-	nor->params.quad_enable = macronix_quad_enable;
+	nor->params.quad_enable = spi_nor_sr1_bit6_quad_enable;
 	nor->params.set_4byte = macronix_set_4byte;
 }
 
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f626e0e52909..6d703df97f13 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -133,7 +133,7 @@
 #define SR_E_ERR		BIT(5)
 #define SR_P_ERR		BIT(6)
 
-#define SR_QUAD_EN_MX		BIT(6)	/* Macronix Quad I/O */
+#define SR1_QUAD_EN_BIT6	BIT(6)
 
 /* Enhanced Volatile Configuration Register bits */
 #define EVCR_QUAD_EN_MICRON	BIT(7)	/* Micron Quad I/O */
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 31/32] mtd: spi-nor: Prepend "spi_nor_" to "sr2_bit7_quad_enable"
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (29 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 30/32] mtd: spi-nor: Rename macronix_quad_enable to spi_nor_sr1_bit6_quad_enable Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  2019-10-29 11:17 ` [PATCH v3 32/32] mtd: spi-nor: Rework the disabling of block write protection Tudor.Ambarus
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

All SPI NOR generic methods should be prepended by "spi_nor_".

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 47d159959461..87660b101c98 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2129,7 +2129,7 @@ static int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
 }
 
 /**
- * sr2_bit7_quad_enable() - set QE bit in Status Register 2.
+ * spi_nor_sr2_bit7_quad_enable() - set QE bit in Status Register 2.
  * @nor:	pointer to a 'struct spi_nor'
  *
  * Set the Quad Enable (QE) bit in the Status Register 2.
@@ -2140,7 +2140,7 @@ static int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
  *
  * Return: 0 on success, -errno otherwise.
  */
-static int sr2_bit7_quad_enable(struct spi_nor *nor)
+static int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
 {
 	u8 *sr2 = nor->bouncebuf;
 	int ret;
@@ -3733,7 +3733,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 
 	case BFPT_DWORD15_QER_SR2_BIT7:
 		nor->flags &= ~SNOR_F_HAS_16BIT_SR;
-		params->quad_enable = sr2_bit7_quad_enable;
+		params->quad_enable = spi_nor_sr2_bit7_quad_enable;
 		break;
 
 	case BFPT_DWORD15_QER_SR2_BIT1:
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 32/32] mtd: spi-nor: Rework the disabling of block write protection
  2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
                   ` (30 preceding siblings ...)
  2019-10-29 11:17 ` [PATCH v3 31/32] mtd: spi-nor: Prepend "spi_nor_" to "sr2_bit7_quad_enable" Tudor.Ambarus
@ 2019-10-29 11:17 ` Tudor.Ambarus
  31 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-29 11:17 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon
  Cc: linux-mtd, linux-kernel, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

spi_nor_unlock() unlocks blocks of memory or the entire flash memory
array, if requested. clear_sr_bp() unlocks the entire flash memory
array at boot time. This calls for some unification, clear_sr_bp() is
just an optimization for the case when the unlock request covers the
entire flash size.

Get rid of clear_sr_bp() and introduce spi_nor_unlock_all(), which is
just a call to spi_nor_unlock() for the entire flash memory array.
This fixes a bug that was present in spi_nor_spansion_clear_sr_bp().
When the QE bit was zero, we used the Write Status (01h) command with
one data byte, which might cleared the Status Register 2. We now always
use the Write Status (01h) command with two data bytes when
SNOR_F_HAS_16BIT_SR is set, to avoid clearing the Status Register 2.

The SNOR_F_NO_READ_CR case is treated as well. When the flash doesn't
support the CR Read command, we make an assumption about the value of
the QE bit. In spi_nor_init(), call spi_nor_quad_enable() first, then
spi_nor_unlock_all(), so that at the spi_nor_unlock_all() time we can
be sure the QE bit has value one, because of the previous call to
spi_nor_quad_enable().

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

Note that this changes a bit the logic for the SNOR_MFR_ATMEL,
SNOR_MFR_INTEL and SNOR_MFR_SST cases. Before this patch, the Atmel,
Intel and SST chips did not set the locking ops, but unlocked the entire
flash at boot time, while now they are setting the locking ops to
stm_locking_ops. This should work, since the the disable of the block
protection at the boot time used the same Status Register bits to unlock
the flash, as in the stm_locking_ops case.

Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 140 +++++++++++++++---------------------------
 include/linux/mtd/spi-nor.h   |   3 -
 2 files changed, 50 insertions(+), 93 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 87660b101c98..0c354456a0b1 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2175,74 +2175,6 @@ static int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
-/**
- * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
- * @nor:        pointer to a 'struct spi_nor'
- *
- * Read-modify-write function that clears the Block Protection bits from the
- * Status Register without affecting other bits.
- *
- * Return: 0 on success, -errno otherwise.
- */
-static int spi_nor_clear_sr_bp(struct spi_nor *nor)
-{
-	int ret;
-	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
-
-	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
-	if (ret)
-		return ret;
-
-	nor->bouncebuf[0] &= ~mask;
-
-	return spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
-}
-
-/**
- * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
- * bits on spansion flashes.
- * @nor:        pointer to a 'struct spi_nor'
- *
- * Read-modify-write function that clears the Block Protection bits from the
- * Status Register without affecting other bits. The function is tightly
- * coupled with the spi_nor_sr2_bit1_quad_enable() function. Both assume that
- * the Write Register with 16 bits, together with the Read Configuration
- * Register (35h) instructions are supported.
- *
- * Return: 0 on success, -errno otherwise.
- */
-static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
-{
-	int ret;
-	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
-	u8 *sr_cr =  nor->bouncebuf;
-
-	/* Check current Quad Enable bit value. */
-	ret = spi_nor_read_cr(nor, &sr_cr[1]);
-	if (ret)
-		return ret;
-
-	/*
-	 * When the configuration register Quad Enable bit is one, only the
-	 * Write Status (01h) command with two data bytes may be used.
-	 */
-	if (sr_cr[1] & SR2_QUAD_EN_BIT1) {
-		ret = spi_nor_read_sr(nor, &sr_cr[0]);
-		if (ret)
-			return ret;
-
-		sr_cr[0] &= ~mask;
-
-		return spi_nor_write_sr(nor, sr_cr, 2);
-	}
-
-	/*
-	 * If the Quad Enable bit is zero, use the Write Status (01h) command
-	 * with one data byte.
-	 */
-	return spi_nor_clear_sr_bp(nor);
-}
-
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
 		.id = {							\
@@ -4624,12 +4556,27 @@ static int spi_nor_setup(struct spi_nor *nor,
 	return nor->params.setup(nor, hwcaps);
 }
 
+static void atmel_set_default_init(struct spi_nor *nor)
+{
+	nor->flags |= SNOR_F_HAS_LOCK;
+}
+
+static void intel_set_default_init(struct spi_nor *nor)
+{
+	nor->flags |= SNOR_F_HAS_LOCK;
+}
+
 static void macronix_set_default_init(struct spi_nor *nor)
 {
 	nor->params.quad_enable = spi_nor_sr1_bit6_quad_enable;
 	nor->params.set_4byte = macronix_set_4byte;
 }
 
+static void sst_set_default_init(struct spi_nor *nor)
+{
+	nor->flags |= SNOR_F_HAS_LOCK;
+}
+
 static void st_micron_set_default_init(struct spi_nor *nor)
 {
 	nor->flags |= SNOR_F_HAS_LOCK;
@@ -4651,6 +4598,14 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
 {
 	/* Init flash parameters based on MFR */
 	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;
@@ -4660,6 +4615,10 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
 		st_micron_set_default_init(nor);
 		break;
 
+	case SNOR_MFR_SST:
+		sst_set_default_init(nor);
+		break;
+
 	case SNOR_MFR_WINBOND:
 		winbond_set_default_init(nor);
 		break;
@@ -4920,21 +4879,26 @@ static int spi_nor_quad_enable(struct spi_nor *nor)
 	return nor->params.quad_enable(nor);
 }
 
-static int spi_nor_init(struct spi_nor *nor)
+/**
+ * spi_nor_unlock_all() - Unlocks the entire flash memory array.
+ * @nor:	pointer to a 'struct spi_nor'.
+ *
+ * Some SPI NOR flashes are write protected by default after a power-on reset
+ * cycle, in order to avoid inadvertent writes during power-up. Backward
+ * compatibility imposes to unlock the entire flash memory array at power-up
+ * by default.
+ */
+static int spi_nor_unlock_all(struct spi_nor *nor)
 {
-	int err;
+	if (nor->flags & SNOR_F_HAS_LOCK)
+		return spi_nor_unlock(&nor->mtd, 0, nor->params.size);
 
-	if (nor->clear_sr_bp) {
-		if (nor->params.quad_enable == spi_nor_sr2_bit1_quad_enable)
-			nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
+	return 0;
+}
 
-		err = nor->clear_sr_bp(nor);
-		if (err) {
-			dev_err(nor->dev,
-				"fail to clear block protection bits\n");
-			return err;
-		}
-	}
+static int spi_nor_init(struct spi_nor *nor)
+{
+	int err;
 
 	err = spi_nor_quad_enable(nor);
 	if (err) {
@@ -4942,6 +4906,12 @@ static int spi_nor_init(struct spi_nor *nor)
 		return err;
 	}
 
+	err = spi_nor_unlock_all(nor);
+	if (err) {
+		dev_err(nor->dev, "Failed to unlock the entire flash memory array\n");
+		return err;
+	}
+
 	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) {
 		/*
 		 * If the RESET# pin isn't hooked up properly, or the system
@@ -5124,16 +5094,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (info->flags & SPI_NOR_HAS_LOCK)
 		nor->flags |= SNOR_F_HAS_LOCK;
 
-	/*
-	 * 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;
-
 	/* Init flash parameters based on flash_info struct and SFDP */
 	spi_nor_init_params(nor);
 
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 6d703df97f13..9eae35c60bce 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -579,8 +579,6 @@ struct flash_info;
  * @write_proto:	the SPI protocol for write operations
  * @reg_proto		the SPI protocol for read_reg/write_reg/erase operations
  * @controller_ops:	SPI NOR controller driver specific operations.
- * @clear_sr_bp:	[FLASH-SPECIFIC] clears the Block Protection Bits from
- *			the SPI NOR Status Register.
  * @params:		[FLASH-SPECIFIC] SPI-NOR flash parameters and settings.
  *                      The structure includes legacy flash parameters and
  *                      settings that can be overwritten by the spi_nor_fixups
@@ -609,7 +607,6 @@ struct spi_nor {
 
 	const struct spi_nor_controller_ops *controller_ops;
 
-	int (*clear_sr_bp)(struct spi_nor *nor);
 	struct spi_nor_flash_parameter params;
 
 	void *priv;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 15/32] mtd: spi-nor: Check for errors after each Register Operation
  2019-10-29 11:17 ` [PATCH v3 15/32] mtd: spi-nor: Check for errors after each Register Operation Tudor.Ambarus
@ 2019-10-31  6:57   ` Tudor.Ambarus
  0 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-31  6:57 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:17 PM, Tudor Ambarus - M18064 wrote:
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -595,11 +595,15 @@ static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
>  {
>  	int ret;
>  
> -	spi_nor_write_enable(nor);
> +	ret == spi_nor_write_enable(nor);

there's a typo here, it should have been initialization. Will respin if other
comments will arise.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods
  2019-10-29 11:16 ` [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods Tudor.Ambarus
@ 2019-10-31 10:34   ` Boris Brezillon
  2019-11-02 10:34   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:34 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:16:49 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> All the core functions should begin with "spi_nor_".
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 110 +++++++++++++++++++++---------------------
>  1 file changed, 56 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index a6f9f833c862..aca8245fb6c4 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -393,7 +393,7 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
>   * Return the status register value.
>   * Returns negative if error occurred.
>   */
> -static int read_sr(struct spi_nor *nor)
> +static int spi_nor_read_sr(struct spi_nor *nor)
>  {
>  	int ret;
>  
> @@ -423,7 +423,7 @@ static int read_sr(struct spi_nor *nor)
>   * Return the status register value.
>   * Returns negative if error occurred.
>   */
> -static int read_fsr(struct spi_nor *nor)
> +static int spi_nor_read_fsr(struct spi_nor *nor)
>  {
>  	int ret;
>  
> @@ -453,7 +453,7 @@ static int read_fsr(struct spi_nor *nor)
>   * location. Return the configuration register value.
>   * Returns negative if error occurred.
>   */
> -static int read_cr(struct spi_nor *nor)
> +static int spi_nor_read_cr(struct spi_nor *nor)
>  {
>  	int ret;
>  
> @@ -482,7 +482,7 @@ static int read_cr(struct spi_nor *nor)
>   * Write status register 1 byte
>   * Returns negative if error occurred.
>   */
> -static int write_sr(struct spi_nor *nor, u8 val)
> +static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
>  {
>  	nor->bouncebuf[0] = val;
>  	if (nor->spimem) {
> @@ -503,7 +503,7 @@ static int write_sr(struct spi_nor *nor, u8 val)
>   * Set write enable latch with Write Enable command.
>   * Returns negative if error occurred.
>   */
> -static int write_enable(struct spi_nor *nor)
> +static int spi_nor_write_enable(struct spi_nor *nor)
>  {
>  	if (nor->spimem) {
>  		struct spi_mem_op op =
> @@ -521,7 +521,7 @@ static int write_enable(struct spi_nor *nor)
>  /*
>   * Send write disable instruction to the chip.
>   */
> -static int write_disable(struct spi_nor *nor)
> +static int spi_nor_write_disable(struct spi_nor *nor)
>  {
>  	if (nor->spimem) {
>  		struct spi_mem_op op =
> @@ -644,9 +644,9 @@ static int st_micron_set_4byte(struct spi_nor *nor, bool enable)
>  {
>  	int ret;
>  
> -	write_enable(nor);
> +	spi_nor_write_enable(nor);
>  	ret = macronix_set_4byte(nor, enable);
> -	write_disable(nor);
> +	spi_nor_write_disable(nor);
>  
>  	return ret;
>  }
> @@ -700,9 +700,9 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable)
>  	 * Register to be set to 1, so all 3-byte-address reads come from the
>  	 * second 16M. We must clear the register to enable normal behavior.
>  	 */
> -	write_enable(nor);
> +	spi_nor_write_enable(nor);
>  	ret = spi_nor_write_ear(nor, 0);
> -	write_disable(nor);
> +	spi_nor_write_disable(nor);
>  
>  	return ret;
>  }
> @@ -752,7 +752,7 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
>  
>  static int spi_nor_sr_ready(struct spi_nor *nor)
>  {
> -	int sr = read_sr(nor);
> +	int sr = spi_nor_read_sr(nor);
>  	if (sr < 0)
>  		return sr;
>  
> @@ -786,7 +786,7 @@ static int spi_nor_clear_fsr(struct spi_nor *nor)
>  
>  static int spi_nor_fsr_ready(struct spi_nor *nor)
>  {
> -	int fsr = read_fsr(nor);
> +	int fsr = spi_nor_read_fsr(nor);
>  	if (fsr < 0)
>  		return fsr;
>  
> @@ -864,7 +864,7 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
>   *
>   * Returns 0 if successful, non-zero otherwise.
>   */
> -static int erase_chip(struct spi_nor *nor)
> +static int spi_nor_erase_chip(struct spi_nor *nor)
>  {
>  	dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10));
>  
> @@ -1215,7 +1215,7 @@ static int spi_nor_erase_multi_sectors(struct spi_nor *nor, u64 addr, u32 len)
>  	list_for_each_entry_safe(cmd, next, &erase_list, list) {
>  		nor->erase_opcode = cmd->opcode;
>  		while (cmd->count) {
> -			write_enable(nor);
> +			spi_nor_write_enable(nor);
>  
>  			ret = spi_nor_erase_sector(nor, addr);
>  			if (ret)
> @@ -1270,9 +1270,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>  	if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
>  		unsigned long timeout;
>  
> -		write_enable(nor);
> +		spi_nor_write_enable(nor);
>  
> -		if (erase_chip(nor)) {
> +		if (spi_nor_erase_chip(nor)) {
>  			ret = -EIO;
>  			goto erase_err;
>  		}
> @@ -1298,7 +1298,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>  	/* "sector"-at-a-time erase */
>  	} else if (spi_nor_has_uniform_erase(nor)) {
>  		while (len) {
> -			write_enable(nor);
> +			spi_nor_write_enable(nor);
>  
>  			ret = spi_nor_erase_sector(nor, addr);
>  			if (ret)
> @@ -1319,7 +1319,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>  			goto erase_err;
>  	}
>  
> -	write_disable(nor);
> +	spi_nor_write_disable(nor);
>  
>  erase_err:
>  	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
> @@ -1328,12 +1328,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>  }
>  
>  /* Write status register and ensure bits in mask match written values */
> -static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
> +static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
> +				      u8 mask)
>  {
>  	int ret;
>  
> -	write_enable(nor);
> -	ret = write_sr(nor, status_new);
> +	spi_nor_write_enable(nor);
> +	ret = spi_nor_write_sr(nor, status_new);
>  	if (ret)
>  		return ret;
>  
> @@ -1341,7 +1342,7 @@ static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
>  	if (ret)
>  		return ret;
>  
> -	ret = read_sr(nor);
> +	ret = spi_nor_read_sr(nor);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -1447,7 +1448,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
>  	bool use_top;
>  
> -	status_old = read_sr(nor);
> +	status_old = spi_nor_read_sr(nor);
>  	if (status_old < 0)
>  		return status_old;
>  
> @@ -1509,7 +1510,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  	if ((status_new & mask) < (status_old & mask))
>  		return -EINVAL;
>  
> -	return write_sr_and_check(nor, status_new, mask);
> +	return spi_nor_write_sr_and_check(nor, status_new, mask);
>  }
>  
>  /*
> @@ -1527,7 +1528,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
>  	bool use_top;
>  
> -	status_old = read_sr(nor);
> +	status_old = spi_nor_read_sr(nor);
>  	if (status_old < 0)
>  		return status_old;
>  
> @@ -1592,7 +1593,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  	if ((status_new & mask) > (status_old & mask))
>  		return -EINVAL;
>  
> -	return write_sr_and_check(nor, status_new, mask);
> +	return spi_nor_write_sr_and_check(nor, status_new, mask);
>  }
>  
>  /*
> @@ -1606,7 +1607,7 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  {
>  	int status;
>  
> -	status = read_sr(nor);
> +	status = spi_nor_read_sr(nor);
>  	if (status < 0)
>  		return status;
>  
> @@ -1670,11 +1671,11 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>   * 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)
> +static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
>  {
>  	int ret;
>  
> -	write_enable(nor);
> +	spi_nor_write_enable(nor);
>  
>  	if (nor->spimem) {
>  		struct spi_mem_op op =
> @@ -1719,21 +1720,21 @@ static int macronix_quad_enable(struct spi_nor *nor)
>  {
>  	int ret, val;
>  
> -	val = read_sr(nor);
> +	val = spi_nor_read_sr(nor);
>  	if (val < 0)
>  		return val;
>  	if (val & SR_QUAD_EN_MX)
>  		return 0;
>  
> -	write_enable(nor);
> +	spi_nor_write_enable(nor);
>  
> -	write_sr(nor, val | SR_QUAD_EN_MX);
> +	spi_nor_write_sr(nor, val | SR_QUAD_EN_MX);
>  
>  	ret = spi_nor_wait_till_ready(nor);
>  	if (ret)
>  		return ret;
>  
> -	ret = read_sr(nor);
> +	ret = spi_nor_read_sr(nor);
>  	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
>  		dev_err(nor->dev, "Macronix Quad bit not set\n");
>  		return -EINVAL;
> @@ -1758,7 +1759,8 @@ static int macronix_quad_enable(struct spi_nor *nor)
>   * some very old and few memories don't support this instruction. If a pull-up
>   * resistor is present on the MISO/IO1 line, we might still be able to pass the
>   * "read back" test because the QSPI memory doesn't recognize the command,
> - * so leaves the MISO/IO1 line state unchanged, hence read_cr() returns 0xFF.
> + * so leaves the MISO/IO1 line state unchanged, hence spi_nor_read_cr() returns
> + * 0xFF.
>   *
>   * bit 1 of the Configuration Register is the QE bit for Spansion like QSPI
>   * memories.
> @@ -1772,12 +1774,12 @@ 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_cr(nor, sr_cr);
>  	if (ret)
>  		return ret;
>  
>  	/* read back and check it */
> -	ret = read_cr(nor);
> +	ret = spi_nor_read_cr(nor);
>  	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
>  		dev_err(nor->dev, "Spansion Quad bit not set\n");
>  		return -EINVAL;
> @@ -1805,7 +1807,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
>  	int ret;
>  
>  	/* Keep the current value of the Status Register. */
> -	ret = read_sr(nor);
> +	ret = spi_nor_read_sr(nor);
>  	if (ret < 0) {
>  		dev_err(nor->dev, "error while reading status register\n");
>  		return -EINVAL;
> @@ -1813,7 +1815,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
>  	sr_cr[0] = ret;
>  	sr_cr[1] = CR_QUAD_EN_SPAN;
>  
> -	return write_sr_cr(nor, sr_cr);
> +	return spi_nor_write_sr_cr(nor, sr_cr);
>  }
>  
>  /**
> @@ -1836,7 +1838,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>  	int ret;
>  
>  	/* Check current Quad Enable bit value. */
> -	ret = read_cr(nor);
> +	ret = spi_nor_read_cr(nor);
>  	if (ret < 0) {
>  		dev_err(dev, "error while reading configuration register\n");
>  		return -EINVAL;
> @@ -1848,19 +1850,19 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>  	sr_cr[1] = ret | CR_QUAD_EN_SPAN;
>  
>  	/* Keep the current value of the Status Register. */
> -	ret = read_sr(nor);
> +	ret = spi_nor_read_sr(nor);
>  	if (ret < 0) {
>  		dev_err(dev, "error while reading status register\n");
>  		return -EINVAL;
>  	}
>  	sr_cr[0] = ret;
>  
> -	ret = write_sr_cr(nor, sr_cr);
> +	ret = spi_nor_write_sr_cr(nor, sr_cr);
>  	if (ret)
>  		return ret;
>  
>  	/* Read back and check it. */
> -	ret = read_cr(nor);
> +	ret = spi_nor_read_cr(nor);
>  	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
>  		dev_err(nor->dev, "Spansion Quad bit not set\n");
>  		return -EINVAL;
> @@ -1926,7 +1928,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
>  	/* Update the Quad Enable bit. */
>  	*sr2 |= SR2_QUAD_EN_BIT7;
>  
> -	write_enable(nor);
> +	spi_nor_write_enable(nor);
>  
>  	ret = spi_nor_write_sr2(nor, sr2);
>  	if (ret < 0) {
> @@ -1964,15 +1966,15 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
>  	int ret;
>  	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>  
> -	ret = read_sr(nor);
> +	ret = spi_nor_read_sr(nor);
>  	if (ret < 0) {
>  		dev_err(nor->dev, "error while reading status register\n");
>  		return ret;
>  	}
>  
> -	write_enable(nor);
> +	spi_nor_write_enable(nor);
>  
> -	ret = write_sr(nor, ret & ~mask);
> +	ret = spi_nor_write_sr(nor, ret & ~mask);
>  	if (ret) {
>  		dev_err(nor->dev, "write to status register failed\n");
>  		return ret;
> @@ -2004,7 +2006,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
>  	u8 *sr_cr =  nor->bouncebuf;
>  
>  	/* Check current Quad Enable bit value. */
> -	ret = read_cr(nor);
> +	ret = spi_nor_read_cr(nor);
>  	if (ret < 0) {
>  		dev_err(nor->dev,
>  			"error while reading configuration register\n");
> @@ -2018,7 +2020,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
>  	if (ret & CR_QUAD_EN_SPAN) {
>  		sr_cr[1] = ret;
>  
> -		ret = read_sr(nor);
> +		ret = spi_nor_read_sr(nor);
>  		if (ret < 0) {
>  			dev_err(nor->dev,
>  				"error while reading status register\n");
> @@ -2026,7 +2028,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
>  		}
>  		sr_cr[0] = ret & ~mask;
>  
> -		ret = write_sr_cr(nor, sr_cr);
> +		ret = spi_nor_write_sr_cr(nor, sr_cr);
>  		if (ret)
>  			dev_err(nor->dev, "16-bit write register failed\n");
>  		return ret;
> @@ -2602,7 +2604,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  	if (ret)
>  		return ret;
>  
> -	write_enable(nor);
> +	spi_nor_write_enable(nor);
>  
>  	nor->sst_write_second = false;
>  
> @@ -2641,14 +2643,14 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  	}
>  	nor->sst_write_second = false;
>  
> -	write_disable(nor);
> +	spi_nor_write_disable(nor);
>  	ret = spi_nor_wait_till_ready(nor);
>  	if (ret)
>  		goto sst_write_err;
>  
>  	/* Write out trailing byte if it exists. */
>  	if (actual != len) {
> -		write_enable(nor);
> +		spi_nor_write_enable(nor);
>  
>  		nor->program_opcode = SPINOR_OP_BP;
>  		ret = spi_nor_write_data(nor, to, 1, buf + actual);
> @@ -2659,7 +2661,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  		ret = spi_nor_wait_till_ready(nor);
>  		if (ret)
>  			goto sst_write_err;
> -		write_disable(nor);
> +		spi_nor_write_disable(nor);
>  		actual += 1;
>  	}
>  sst_write_err:
> @@ -2711,7 +2713,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
>  
>  		addr = spi_nor_convert_addr(nor, addr);
>  
> -		write_enable(nor);
> +		spi_nor_write_enable(nor);
>  		ret = spi_nor_write_data(nor, addr, page_remain, buf + i);
>  		if (ret < 0)
>  			goto write_err;


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line
  2019-10-29 11:16 ` [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line Tudor.Ambarus
@ 2019-10-31 10:34   ` Boris Brezillon
  2019-11-02 10:34   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:34 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:16:50 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Two new lines, one after another, drop one.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index aca8245fb6c4..6e82df577eed 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -541,7 +541,6 @@ static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
>  	return mtd->priv;
>  }
>  
> -
>  static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
>  {
>  	size_t i;


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations
  2019-10-29 11:16 ` [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations Tudor.Ambarus
@ 2019-10-31 10:35   ` Boris Brezillon
  2019-11-02 10:35   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:35 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:16:52 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Group all register methods up in the file, to avoid forward
> declarations.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 426 +++++++++++++++++++++---------------------
>  1 file changed, 213 insertions(+), 213 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 6e82df577eed..24378d65fa2e 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -389,6 +389,43 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
>  }
>  
>  /*
> + * Set write enable latch with Write Enable command.
> + * Returns negative if error occurred.
> + */
> +static int spi_nor_write_enable(struct spi_nor *nor)
> +{
> +	if (nor->spimem) {
> +		struct spi_mem_op op =
> +			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 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_WREN, NULL, 0);
> +}
> +
> +/*
> + * Send write disable instruction to the chip.
> + */
> +static int spi_nor_write_disable(struct spi_nor *nor)
> +{
> +	if (nor->spimem) {
> +		struct spi_mem_op op =
> +			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 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_WRDI, NULL, 0);
> +}
> +
> +/*
>   * Read the status register, returning its value in the location
>   * Return the status register value.
>   * Returns negative if error occurred.
> @@ -499,126 +536,6 @@ static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
>  					      nor->bouncebuf, 1);
>  }
>  
> -/*
> - * Set write enable latch with Write Enable command.
> - * Returns negative if error occurred.
> - */
> -static int spi_nor_write_enable(struct spi_nor *nor)
> -{
> -	if (nor->spimem) {
> -		struct spi_mem_op op =
> -			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 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_WREN, NULL, 0);
> -}
> -
> -/*
> - * Send write disable instruction to the chip.
> - */
> -static int spi_nor_write_disable(struct spi_nor *nor)
> -{
> -	if (nor->spimem) {
> -		struct spi_mem_op op =
> -			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 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_WRDI, NULL, 0);
> -}
> -
> -static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
> -{
> -	return mtd->priv;
> -}
> -
> -static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
> -{
> -	size_t i;
> -
> -	for (i = 0; i < size; i++)
> -		if (table[i][0] == opcode)
> -			return table[i][1];
> -
> -	/* No conversion found, keep input op code. */
> -	return opcode;
> -}
> -
> -static u8 spi_nor_convert_3to4_read(u8 opcode)
> -{
> -	static const u8 spi_nor_3to4_read[][2] = {
> -		{ SPINOR_OP_READ,	SPINOR_OP_READ_4B },
> -		{ SPINOR_OP_READ_FAST,	SPINOR_OP_READ_FAST_4B },
> -		{ SPINOR_OP_READ_1_1_2,	SPINOR_OP_READ_1_1_2_4B },
> -		{ SPINOR_OP_READ_1_2_2,	SPINOR_OP_READ_1_2_2_4B },
> -		{ SPINOR_OP_READ_1_1_4,	SPINOR_OP_READ_1_1_4_4B },
> -		{ SPINOR_OP_READ_1_4_4,	SPINOR_OP_READ_1_4_4_4B },
> -		{ SPINOR_OP_READ_1_1_8,	SPINOR_OP_READ_1_1_8_4B },
> -		{ SPINOR_OP_READ_1_8_8,	SPINOR_OP_READ_1_8_8_4B },
> -
> -		{ SPINOR_OP_READ_1_1_1_DTR,	SPINOR_OP_READ_1_1_1_DTR_4B },
> -		{ SPINOR_OP_READ_1_2_2_DTR,	SPINOR_OP_READ_1_2_2_DTR_4B },
> -		{ SPINOR_OP_READ_1_4_4_DTR,	SPINOR_OP_READ_1_4_4_DTR_4B },
> -	};
> -
> -	return spi_nor_convert_opcode(opcode, spi_nor_3to4_read,
> -				      ARRAY_SIZE(spi_nor_3to4_read));
> -}
> -
> -static u8 spi_nor_convert_3to4_program(u8 opcode)
> -{
> -	static const u8 spi_nor_3to4_program[][2] = {
> -		{ SPINOR_OP_PP,		SPINOR_OP_PP_4B },
> -		{ SPINOR_OP_PP_1_1_4,	SPINOR_OP_PP_1_1_4_4B },
> -		{ SPINOR_OP_PP_1_4_4,	SPINOR_OP_PP_1_4_4_4B },
> -		{ SPINOR_OP_PP_1_1_8,	SPINOR_OP_PP_1_1_8_4B },
> -		{ SPINOR_OP_PP_1_8_8,	SPINOR_OP_PP_1_8_8_4B },
> -	};
> -
> -	return spi_nor_convert_opcode(opcode, spi_nor_3to4_program,
> -				      ARRAY_SIZE(spi_nor_3to4_program));
> -}
> -
> -static u8 spi_nor_convert_3to4_erase(u8 opcode)
> -{
> -	static const u8 spi_nor_3to4_erase[][2] = {
> -		{ SPINOR_OP_BE_4K,	SPINOR_OP_BE_4K_4B },
> -		{ SPINOR_OP_BE_32K,	SPINOR_OP_BE_32K_4B },
> -		{ SPINOR_OP_SE,		SPINOR_OP_SE_4B },
> -	};
> -
> -	return spi_nor_convert_opcode(opcode, spi_nor_3to4_erase,
> -				      ARRAY_SIZE(spi_nor_3to4_erase));
> -}
> -
> -static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
> -{
> -	nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
> -	nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode);
> -	nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
> -
> -	if (!spi_nor_has_uniform_erase(nor)) {
> -		struct spi_nor_erase_map *map = &nor->params.erase_map;
> -		struct spi_nor_erase_type *erase;
> -		int i;
> -
> -		for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
> -			erase = &map->erase_type[i];
> -			erase->opcode =
> -				spi_nor_convert_3to4_erase(erase->opcode);
> -		}
> -	}
> -}
> -
>  static int macronix_set_4byte(struct spi_nor *nor, bool enable)
>  {
>  	if (nor->spimem) {
> @@ -859,6 +776,99 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
>  }
>  
>  /*
> + * 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 spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
> +{
> +	int ret;
> +
> +	spi_nor_write_enable(nor);
> +
> +	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;
> +}
> +
> +/* Write status register and ensure bits in mask match written values */
> +static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
> +				      u8 mask)
> +{
> +	int ret;
> +
> +	spi_nor_write_enable(nor);
> +	ret = spi_nor_write_sr(nor, status_new);
> +	if (ret)
> +		return ret;
> +
> +	ret = spi_nor_wait_till_ready(nor);
> +	if (ret)
> +		return ret;
> +
> +	ret = spi_nor_read_sr(nor);
> +	if (ret < 0)
> +		return ret;
> +
> +	return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
> +}
> +
> +static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
> +{
> +	if (nor->spimem) {
> +		struct spi_mem_op op =
> +			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR2, 1),
> +				   SPI_MEM_OP_NO_ADDR,
> +				   SPI_MEM_OP_NO_DUMMY,
> +				   SPI_MEM_OP_DATA_OUT(1, sr2, 1));
> +
> +		return spi_mem_exec_op(nor->spimem, &op);
> +	}
> +
> +	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
> +}
> +
> +static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
> +{
> +	if (nor->spimem) {
> +		struct spi_mem_op op =
> +			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2, 1),
> +				   SPI_MEM_OP_NO_ADDR,
> +				   SPI_MEM_OP_NO_DUMMY,
> +				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
> +
> +		return spi_mem_exec_op(nor->spimem, &op);
> +	}
> +
> +	return nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
> +}
> +
> +/*
>   * Erase the whole flash memory
>   *
>   * Returns 0 if successful, non-zero otherwise.
> @@ -881,6 +891,89 @@ static int spi_nor_erase_chip(struct spi_nor *nor)
>  					      NULL, 0);
>  }
>  
> +static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
> +{
> +	return mtd->priv;
> +}
> +
> +static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
> +{
> +	size_t i;
> +
> +	for (i = 0; i < size; i++)
> +		if (table[i][0] == opcode)
> +			return table[i][1];
> +
> +	/* No conversion found, keep input op code. */
> +	return opcode;
> +}
> +
> +static u8 spi_nor_convert_3to4_read(u8 opcode)
> +{
> +	static const u8 spi_nor_3to4_read[][2] = {
> +		{ SPINOR_OP_READ,	SPINOR_OP_READ_4B },
> +		{ SPINOR_OP_READ_FAST,	SPINOR_OP_READ_FAST_4B },
> +		{ SPINOR_OP_READ_1_1_2,	SPINOR_OP_READ_1_1_2_4B },
> +		{ SPINOR_OP_READ_1_2_2,	SPINOR_OP_READ_1_2_2_4B },
> +		{ SPINOR_OP_READ_1_1_4,	SPINOR_OP_READ_1_1_4_4B },
> +		{ SPINOR_OP_READ_1_4_4,	SPINOR_OP_READ_1_4_4_4B },
> +		{ SPINOR_OP_READ_1_1_8,	SPINOR_OP_READ_1_1_8_4B },
> +		{ SPINOR_OP_READ_1_8_8,	SPINOR_OP_READ_1_8_8_4B },
> +
> +		{ SPINOR_OP_READ_1_1_1_DTR,	SPINOR_OP_READ_1_1_1_DTR_4B },
> +		{ SPINOR_OP_READ_1_2_2_DTR,	SPINOR_OP_READ_1_2_2_DTR_4B },
> +		{ SPINOR_OP_READ_1_4_4_DTR,	SPINOR_OP_READ_1_4_4_DTR_4B },
> +	};
> +
> +	return spi_nor_convert_opcode(opcode, spi_nor_3to4_read,
> +				      ARRAY_SIZE(spi_nor_3to4_read));
> +}
> +
> +static u8 spi_nor_convert_3to4_program(u8 opcode)
> +{
> +	static const u8 spi_nor_3to4_program[][2] = {
> +		{ SPINOR_OP_PP,		SPINOR_OP_PP_4B },
> +		{ SPINOR_OP_PP_1_1_4,	SPINOR_OP_PP_1_1_4_4B },
> +		{ SPINOR_OP_PP_1_4_4,	SPINOR_OP_PP_1_4_4_4B },
> +		{ SPINOR_OP_PP_1_1_8,	SPINOR_OP_PP_1_1_8_4B },
> +		{ SPINOR_OP_PP_1_8_8,	SPINOR_OP_PP_1_8_8_4B },
> +	};
> +
> +	return spi_nor_convert_opcode(opcode, spi_nor_3to4_program,
> +				      ARRAY_SIZE(spi_nor_3to4_program));
> +}
> +
> +static u8 spi_nor_convert_3to4_erase(u8 opcode)
> +{
> +	static const u8 spi_nor_3to4_erase[][2] = {
> +		{ SPINOR_OP_BE_4K,	SPINOR_OP_BE_4K_4B },
> +		{ SPINOR_OP_BE_32K,	SPINOR_OP_BE_32K_4B },
> +		{ SPINOR_OP_SE,		SPINOR_OP_SE_4B },
> +	};
> +
> +	return spi_nor_convert_opcode(opcode, spi_nor_3to4_erase,
> +				      ARRAY_SIZE(spi_nor_3to4_erase));
> +}
> +
> +static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
> +{
> +	nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
> +	nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode);
> +	nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
> +
> +	if (!spi_nor_has_uniform_erase(nor)) {
> +		struct spi_nor_erase_map *map = &nor->params.erase_map;
> +		struct spi_nor_erase_type *erase;
> +		int i;
> +
> +		for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
> +			erase = &map->erase_type[i];
> +			erase->opcode =
> +				spi_nor_convert_3to4_erase(erase->opcode);
> +		}
> +	}
> +}
> +
>  static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops)
>  {
>  	int ret = 0;
> @@ -1326,28 +1419,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>  	return ret;
>  }
>  
> -/* Write status register and ensure bits in mask match written values */
> -static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
> -				      u8 mask)
> -{
> -	int ret;
> -
> -	spi_nor_write_enable(nor);
> -	ret = spi_nor_write_sr(nor, status_new);
> -	if (ret)
> -		return ret;
> -
> -	ret = spi_nor_wait_till_ready(nor);
> -	if (ret)
> -		return ret;
> -
> -	ret = spi_nor_read_sr(nor);
> -	if (ret < 0)
> -		return ret;
> -
> -	return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
> -}
> -
>  static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs,
>  				 uint64_t *len)
>  {
> @@ -1664,47 +1735,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 spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
> -{
> -	int ret;
> -
> -	spi_nor_write_enable(nor);
> -
> -	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'
> @@ -1870,36 +1900,6 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>  	return 0;
>  }
>  
> -static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
> -{
> -	if (nor->spimem) {
> -		struct spi_mem_op op =
> -			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR2, 1),
> -				   SPI_MEM_OP_NO_ADDR,
> -				   SPI_MEM_OP_NO_DUMMY,
> -				   SPI_MEM_OP_DATA_OUT(1, sr2, 1));
> -
> -		return spi_mem_exec_op(nor->spimem, &op);
> -	}
> -
> -	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
> -}
> -
> -static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
> -{
> -	if (nor->spimem) {
> -		struct spi_mem_op op =
> -			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2, 1),
> -				   SPI_MEM_OP_NO_ADDR,
> -				   SPI_MEM_OP_NO_DUMMY,
> -				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
> -
> -		return spi_mem_exec_op(nor->spimem, &op);
> -	}
> -
> -	return nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
> -}
> -
>  /**
>   * sr2_bit7_quad_enable() - set QE bit in Status Register 2.
>   * @nor:	pointer to a 'struct spi_nor'


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods
  2019-10-29 11:16 ` [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods Tudor.Ambarus
@ 2019-10-31 10:36   ` Boris Brezillon
  2019-11-02 10:36   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:36 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:16:54 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> spi_mem_exec_op()
> nor->controller_ops->write_reg()
> nor->controller_ops->read_reg()
> spi_nor_wait_till_ready()
> Return 0 on success, -errno otherwise.
> 
> Stop compare with negative and compare with zero in all the register
> operations methods.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value
  2019-10-29 11:16 ` [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value Tudor.Ambarus
@ 2019-10-31 10:36   ` Boris Brezillon
  2019-11-02 10:37   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:36 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:16:55 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> ret is already of type int.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err()
  2019-10-29 11:16 ` [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err() Tudor.Ambarus
@ 2019-10-31 10:43   ` Boris Brezillon
  2019-11-02 10:38   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:43 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:16:57 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Print identifying information about struct device.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index e801f390728c..c794eff69fe9 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -448,7 +448,7 @@ static int spi_nor_read_sr(struct spi_nor *nor)
>  	}
>  
>  	if (ret) {
> -		pr_err("error %d reading SR\n", ret);
> +		dev_err(nor->dev, "error %d reading SR\n", ret);

nor->dev is not exactly what we should use since it points to the SPI
NOR controller device in the !SPI_MEM case, and those controllers can
be attached several SPI NOR devs. Ideally we should use mtd->dev, but
that requires splitting the MTD initialization and registration steps
so mtd->dev can have a valid name before registration time.

Anyway, I guess this change is good enough for now, just mentioned the
problem in case anyone is interested working on it.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

>  		return ret;
>  	}
>  
> @@ -478,7 +478,7 @@ static int spi_nor_read_fsr(struct spi_nor *nor)
>  	}
>  
>  	if (ret) {
> -		pr_err("error %d reading FSR\n", ret);
> +		dev_err(nor->dev, "error %d reading FSR\n", ret);
>  		return ret;
>  	}
>  


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops
  2019-10-29 11:16 ` [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops Tudor.Ambarus
@ 2019-10-31 10:48   ` Boris Brezillon
  2019-11-02 10:39   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:48 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:16:59 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Do not overwrite the error numbers received the Register Operations
> methods.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c794eff69fe9..1a00438fd061 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1364,10 +1364,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>  
>  		spi_nor_write_enable(nor);
>  
> -		if (spi_nor_erase_chip(nor)) {
> -			ret = -EIO;
> +		ret = spi_nor_erase_chip(nor);
> +		if (ret)
>  			goto erase_err;
> -		}
>  
>  		/*
>  		 * Scale the timeout linearly with the size of the flash, with
> @@ -1839,7 +1838,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
>  	ret = spi_nor_read_sr(nor);
>  	if (ret < 0) {
>  		dev_err(nor->dev, "error while reading status register\n");
> -		return -EINVAL;
> +		return ret;
>  	}
>  	sr_cr[0] = ret;
>  	sr_cr[1] = CR_QUAD_EN_SPAN;
> @@ -1870,7 +1869,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>  	ret = spi_nor_read_cr(nor);
>  	if (ret < 0) {
>  		dev_err(dev, "error while reading configuration register\n");
> -		return -EINVAL;
> +		return ret;
>  	}
>  
>  	if (ret & CR_QUAD_EN_SPAN)
> @@ -1882,7 +1881,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>  	ret = spi_nor_read_sr(nor);
>  	if (ret < 0) {
>  		dev_err(dev, "error while reading status register\n");
> -		return -EINVAL;
> +		return ret;
>  	}
>  	sr_cr[0] = ret;
>  
> @@ -1932,7 +1931,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
>  	ret = spi_nor_write_sr2(nor, sr2);
>  	if (ret) {
>  		dev_err(nor->dev, "error while writing status register 2\n");
> -		return -EINVAL;
> +		return ret;
>  	}
>  
>  	ret = spi_nor_wait_till_ready(nor);


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr()
  2019-10-29 11:17 ` [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr() Tudor.Ambarus
@ 2019-10-31 10:51   ` Boris Brezillon
  2019-11-02 10:42   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:51 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:00 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Let the callers pass the pointer to the DMA-able buffer where
> the value of the Status Register will be written. This way we
> avoid the casts between int and u8, which can be confusing.
> 
> Callers stop compare the return value of spi_nor_read_sr() with negative,
> spi_nor_read_sr() returns 0 on success and -errno otherwise.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 117 +++++++++++++++++++++++-------------------
>  1 file changed, 64 insertions(+), 53 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 1a00438fd061..dc44d1206f77 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -425,12 +425,15 @@ static int spi_nor_write_disable(struct spi_nor *nor)
>  	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRDI, NULL, 0);
>  }
>  
> -/*
> - * Read the status register, returning its value in the location
> - * Return the status register value.
> - * Returns negative if error occurred.
> +/**
> + * spi_nor_read_sr() - Read the Status Register.
> + * @nor:	pointer to 'struct spi_nor'.
> + * @sr:		pointer to a DMA-able buffer where the value of the
> + *              Status Register will be written.
> + *
> + * Return: 0 on success, -errno otherwise.
>   */
> -static int spi_nor_read_sr(struct spi_nor *nor)
> +static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
>  {
>  	int ret;
>  
> @@ -439,20 +442,18 @@ static int spi_nor_read_sr(struct spi_nor *nor)
>  			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 1),
>  				   SPI_MEM_OP_NO_ADDR,
>  				   SPI_MEM_OP_NO_DUMMY,
> -				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
> +				   SPI_MEM_OP_DATA_IN(1, sr, 1));
>  
>  		ret = spi_mem_exec_op(nor->spimem, &op);
>  	} else {
>  		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR,
> -						    nor->bouncebuf, 1);
> +						    sr, 1);
>  	}
>  
> -	if (ret) {
> +	if (ret)
>  		dev_err(nor->dev, "error %d reading SR\n", ret);
> -		return ret;
> -	}
>  
> -	return nor->bouncebuf[0];
> +	return ret;
>  }
>  
>  /*
> @@ -668,12 +669,14 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
>  
>  static int spi_nor_sr_ready(struct spi_nor *nor)
>  {
> -	int sr = spi_nor_read_sr(nor);
> -	if (sr < 0)
> -		return sr;
> +	int ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
>  
> -	if (nor->flags & SNOR_F_USE_CLSR && sr & (SR_E_ERR | SR_P_ERR)) {
> -		if (sr & SR_E_ERR)
> +	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");
> @@ -682,7 +685,7 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
>  		return -EIO;
>  	}
>  
> -	return !(sr & SR_WIP);
> +	return !(nor->bouncebuf[0] & SR_WIP);
>  }
>  
>  static int spi_nor_clear_fsr(struct spi_nor *nor)
> @@ -831,11 +834,11 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
>  	if (ret)
>  		return ret;
>  
> -	ret = spi_nor_read_sr(nor);
> -	if (ret < 0)
> +	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
> +	if (ret)
>  		return ret;
>  
> -	return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
> +	return ((nor->bouncebuf[0] & mask) != (status_new & mask)) ? -EIO : 0;
>  }
>  
>  static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
> @@ -1510,16 +1513,18 @@ static int stm_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
>  static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  {
>  	struct mtd_info *mtd = &nor->mtd;
> -	int status_old, status_new;
> +	int ret, status_old, status_new;
>  	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>  	u8 shift = ffs(mask) - 1, pow, val;
>  	loff_t lock_len;
>  	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
>  	bool use_top;
>  
> -	status_old = spi_nor_read_sr(nor);
> -	if (status_old < 0)
> -		return status_old;
> +	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
> +	if (ret)
> +		return ret;
> +
> +	status_old = nor->bouncebuf[0];
>  
>  	/* If nothing in our range is unlocked, we don't need to do anything */
>  	if (stm_is_locked_sr(nor, ofs, len, status_old))
> @@ -1590,16 +1595,18 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  {
>  	struct mtd_info *mtd = &nor->mtd;
> -	int status_old, status_new;
> +	int ret, status_old, status_new;
>  	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>  	u8 shift = ffs(mask) - 1, pow, val;
>  	loff_t lock_len;
>  	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
>  	bool use_top;
>  
> -	status_old = spi_nor_read_sr(nor);
> -	if (status_old < 0)
> -		return status_old;
> +	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
> +	if (ret)
> +		return ret;
> +
> +	status_old = nor->bouncebuf[0];
>  
>  	/* If nothing in our range is locked, we don't need to do anything */
>  	if (stm_is_unlocked_sr(nor, ofs, len, status_old))
> @@ -1674,13 +1681,13 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>   */
>  static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  {
> -	int status;
> +	int ret;
>  
> -	status = spi_nor_read_sr(nor);
> -	if (status < 0)
> -		return status;
> +	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
> +	if (ret)
> +		return ret;
>  
> -	return stm_is_locked_sr(nor, ofs, len, status);
> +	return stm_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]);
>  }
>  
>  static const struct spi_nor_locking_ops stm_locking_ops = {
> @@ -1746,24 +1753,28 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>   */
>  static int macronix_quad_enable(struct spi_nor *nor)
>  {
> -	int ret, val;
> +	int ret;
> +
> +	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
> +	if (ret)
> +		return ret;
>  
> -	val = spi_nor_read_sr(nor);
> -	if (val < 0)
> -		return val;
> -	if (val & SR_QUAD_EN_MX)
> +	if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
>  		return 0;
>  
>  	spi_nor_write_enable(nor);
>  
> -	spi_nor_write_sr(nor, val | SR_QUAD_EN_MX);
> +	spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
>  
>  	ret = spi_nor_wait_till_ready(nor);
>  	if (ret)
>  		return ret;
>  
> -	ret = spi_nor_read_sr(nor);
> -	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
> +	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
> +	if (ret)
> +		return ret;
> +
> +	if (!(nor->bouncebuf[0] & SR_QUAD_EN_MX)) {
>  		dev_err(nor->dev, "Macronix Quad bit not set\n");
>  		return -EINVAL;
>  	}
> @@ -1835,12 +1846,12 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
>  	int ret;
>  
>  	/* Keep the current value of the Status Register. */
> -	ret = spi_nor_read_sr(nor);
> -	if (ret < 0) {
> +	ret = spi_nor_read_sr(nor, &sr_cr[0]);
> +	if (ret) {
>  		dev_err(nor->dev, "error while reading status register\n");
>  		return ret;
>  	}
> -	sr_cr[0] = ret;
> +
>  	sr_cr[1] = CR_QUAD_EN_SPAN;
>  
>  	return spi_nor_write_sr_cr(nor, sr_cr);
> @@ -1878,12 +1889,11 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>  	sr_cr[1] = ret | CR_QUAD_EN_SPAN;
>  
>  	/* Keep the current value of the Status Register. */
> -	ret = spi_nor_read_sr(nor);
> -	if (ret < 0) {
> +	ret = spi_nor_read_sr(nor, &sr_cr[0]);
> +	if (ret) {
>  		dev_err(dev, "error while reading status register\n");
>  		return ret;
>  	}
> -	sr_cr[0] = ret;
>  
>  	ret = spi_nor_write_sr_cr(nor, sr_cr);
>  	if (ret)
> @@ -1967,15 +1977,15 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
>  	int ret;
>  	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>  
> -	ret = spi_nor_read_sr(nor);
> -	if (ret < 0) {
> +	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
> +	if (ret) {
>  		dev_err(nor->dev, "error while reading status register\n");
>  		return ret;
>  	}
>  
>  	spi_nor_write_enable(nor);
>  
> -	ret = spi_nor_write_sr(nor, ret & ~mask);
> +	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
>  	if (ret) {
>  		dev_err(nor->dev, "write to status register failed\n");
>  		return ret;
> @@ -2021,13 +2031,14 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
>  	if (ret & CR_QUAD_EN_SPAN) {
>  		sr_cr[1] = ret;
>  
> -		ret = spi_nor_read_sr(nor);
> -		if (ret < 0) {
> +		ret = spi_nor_read_sr(nor, &sr_cr[0]);
> +		if (ret) {
>  			dev_err(nor->dev,
>  				"error while reading status register\n");
>  			return ret;
>  		}
> -		sr_cr[0] = ret & ~mask;
> +
> +		sr_cr[0] &= ~mask;
>  
>  		ret = spi_nor_write_sr_cr(nor, sr_cr);
>  		if (ret)


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr()
  2019-10-29 11:17 ` [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr() Tudor.Ambarus
@ 2019-10-31 10:53   ` Boris Brezillon
  2019-11-02 10:44   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:53 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:02 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Let the callers pass the pointer to the DMA-able buffer where
> the value of the Flag Status Register will be written. This way we
> avoid the casts between int and u8, which can be confusing.
> 
> Caller stops compare the return value of spi_nor_read_fsr() with negative,
> spi_nor_read_fsr() returns 0 on success and -errno otherwise.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 38 ++++++++++++++++++++------------------
>  1 file changed, 20 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index dc44d1206f77..0d38aede4de7 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -456,12 +456,15 @@ static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
>  	return ret;
>  }
>  
> -/*
> - * Read the flag status register, returning its value in the location
> - * Return the status register value.
> - * Returns negative if error occurred.
> +/**
> + * spi_nor_read_fsr() - Read the Flag Status Register.
> + * @nor:	pointer to 'struct spi_nor'
> + * @fsr:	pointer to a DMA-able buffer where the value of the
> + *              Flag Status Register will be written.
> + *
> + * Return: 0 on success, -errno otherwise.
>   */
> -static int spi_nor_read_fsr(struct spi_nor *nor)
> +static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
>  {
>  	int ret;
>  
> @@ -470,20 +473,18 @@ static int spi_nor_read_fsr(struct spi_nor *nor)
>  			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 1),
>  				   SPI_MEM_OP_NO_ADDR,
>  				   SPI_MEM_OP_NO_DUMMY,
> -				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
> +				   SPI_MEM_OP_DATA_IN(1, fsr, 1));
>  
>  		ret = spi_mem_exec_op(nor->spimem, &op);
>  	} else {
>  		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDFSR,
> -						    nor->bouncebuf, 1);
> +						    fsr, 1);
>  	}
>  
> -	if (ret) {
> +	if (ret)
>  		dev_err(nor->dev, "error %d reading FSR\n", ret);
> -		return ret;
> -	}
>  
> -	return nor->bouncebuf[0];
> +	return ret;
>  }
>  
>  /*
> @@ -705,17 +706,18 @@ static int spi_nor_clear_fsr(struct spi_nor *nor)
>  
>  static int spi_nor_fsr_ready(struct spi_nor *nor)
>  {
> -	int fsr = spi_nor_read_fsr(nor);
> -	if (fsr < 0)
> -		return fsr;
> +	int ret = spi_nor_read_fsr(nor, &nor->bouncebuf[0]);

Didn't comment on the previous patch, but why not simply pass
nor->bouncebuf here?

Anyway, that's just a detail.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> +
> +	if (ret)
> +		return ret;
>  
> -	if (fsr & (FSR_E_ERR | FSR_P_ERR)) {
> -		if (fsr & FSR_E_ERR)
> +	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 (fsr & FSR_PT_ERR)
> +		if (nor->bouncebuf[0] & FSR_PT_ERR)
>  			dev_err(nor->dev,
>  			"Attempted to modify a protected sector.\n");
>  
> @@ -723,7 +725,7 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
>  		return -EIO;
>  	}
>  
> -	return fsr & FSR_READY;
> +	return nor->bouncebuf[0] & FSR_READY;
>  }
>  
>  static int spi_nor_ready(struct spi_nor *nor)


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr()
  2019-10-29 11:17 ` [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr() Tudor.Ambarus
@ 2019-10-31 10:58   ` Boris Brezillon
  2019-10-31 14:26     ` Tudor.Ambarus
  2019-11-02 10:45   ` Tudor.Ambarus
  1 sibling, 1 reply; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:58 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:04 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Let the callers pass the pointer to the DMA-able buffer where
> the value of the Configuration Register will be written. This way we
> avoid the casts between int and u8, which can be confusing.
> 
> Callers stop compare the return value of spi_nor_read_cr() with negative,
> spi_nor_read_cr() returns 0 on success and -errno otherwise.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

There's just this &nor->bouncebuf[0] that I'd prefer to be turned into
nor->bouncebuf if you're okay.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers
  2019-10-29 11:17 ` [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers Tudor.Ambarus
@ 2019-10-31 10:59   ` Boris Brezillon
  2019-11-02 10:46   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 10:59 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:05 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Drop the error messages from the callers, since the callees
> already print an error message in case of failure.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 12/32] mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr()
  2019-10-29 11:17 ` [PATCH v3 12/32] mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr() Tudor.Ambarus
@ 2019-10-31 11:02   ` Boris Brezillon
  0 siblings, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 11:02 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:07 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> spi_nor_clear_sr() and spi_nor_clear_fsr() are called just in case
> of errors. The callers didn't check their return value, make them
> of type void.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 4a1ecf452a39..e5ed9012cd50 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -654,7 +654,7 @@ static int s3an_sr_ready(struct spi_nor *nor)
>  	return !!(nor->bouncebuf[0] & XSR_RDY);
>  }
>  
> -static int spi_nor_clear_sr(struct spi_nor *nor)
> +static void spi_nor_clear_sr(struct spi_nor *nor)
>  {
>  	if (nor->spimem) {
>  		struct spi_mem_op op =
> @@ -690,7 +690,7 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
>  	return !(nor->bouncebuf[0] & SR_WIP);
>  }
>  
> -static int spi_nor_clear_fsr(struct spi_nor *nor)
> +static void spi_nor_clear_fsr(struct spi_nor *nor)
>  {
>  	if (nor->spimem) {
>  		struct spi_mem_op op =


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 13/32] mtd: spi-nor: Print error messages inside Reg Ops methods
  2019-10-29 11:17 ` [PATCH v3 13/32] mtd: spi-nor: Print error messages inside Reg Ops methods Tudor.Ambarus
@ 2019-10-31 11:05   ` Boris Brezillon
  2019-10-31 14:18     ` Tudor.Ambarus
  0 siblings, 1 reply; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 11:05 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:09 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Spare the callers of printing error messages by themselves.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 165 +++++++++++++++++++++++++++++++-----------
>  1 file changed, 123 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index e5ed9012cd50..bc46b946ac77 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -394,6 +394,8 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
>   */
>  static int spi_nor_write_enable(struct spi_nor *nor)
>  {
> +	int ret;
> +
>  	if (nor->spimem) {
>  		struct spi_mem_op op =
>  			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 1),
> @@ -401,10 +403,16 @@ static int spi_nor_write_enable(struct spi_nor *nor)
>  				   SPI_MEM_OP_NO_DUMMY,
>  				   SPI_MEM_OP_NO_DATA);
>  
> -		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_WREN,
> +						     NULL, 0);
>  	}
>  
> -	return nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> +	if (ret)
> +		dev_err(nor->dev, "error %d on Write Enable\n", ret);

I thought we agreed on using dev_err_once() here (applies to other
dev_err() calls). If it fails once it's unlikely to succeed on
subsequent calls, and I don't think spamming the kernel logs is very
useful.

> +
> +	return ret;
>  }

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write()
  2019-10-29 11:17 ` [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write() Tudor.Ambarus
@ 2019-10-31 11:12   ` Boris Brezillon
  2019-11-02 10:47   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 11:12 UTC (permalink / raw)
  To: Tudor.Ambarus, linux-kernel; +Cc: miquel.raynal, richard, vigneshr, linux-mtd

On Tue, 29 Oct 2019 11:17:10 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> In case the write of the first byte failed, retlen was incorrectly
> incremented to *retlen += actual; on the exit path. retlen should be
> incremented when actual data was written to the flash.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index bc46b946ac77..889fd77dbe96 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -2667,7 +2667,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  		size_t *retlen, const u_char *buf)
>  {
>  	struct spi_nor *nor = mtd_to_spi_nor(mtd);
> -	size_t actual;
> +	size_t actual = 0;
>  	int ret;
>  
>  	dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
> @@ -2680,9 +2680,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  
>  	nor->sst_write_second = false;
>  
> -	actual = to % 2;
>  	/* Start write from odd address. */
> -	if (actual) {
> +	if (to % 2) {
>  		nor->program_opcode = SPINOR_OP_BP;
>  
>  		/* write one byte. */
> @@ -2693,8 +2692,10 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  		ret = spi_nor_wait_till_ready(nor);
>  		if (ret)
>  			goto sst_write_err;
> +
> +		to++;
> +		actual++;
>  	}
> -	to += actual;
>  
>  	/* Write out most of the data here. */
>  	for (; actual < len - 1; actual += 2) {


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 16/32] mtd: spi-nor: Rename label as it is no longer generic
  2019-10-29 11:17 ` [PATCH v3 16/32] mtd: spi-nor: Rename label as it is no longer generic Tudor.Ambarus
@ 2019-10-31 11:14   ` Boris Brezillon
  0 siblings, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 11:14 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:13 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Rename 'sst_write_err' label to 'out' as it is no longer generic for
> all the errors in the sst_write() method, and may introduce confusion.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 22 +++++++++++-----------
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 21f01fdcfa16..ed7c233a7208 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -2705,7 +2705,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  
>  	ret = spi_nor_write_enable(nor);
>  	if (ret)
> -		goto sst_write_err;
> +		goto out;
>  
>  	nor->sst_write_second = false;
>  
> @@ -2716,11 +2716,11 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  		/* write one byte. */
>  		ret = spi_nor_write_data(nor, to, 1, buf);
>  		if (ret < 0)
> -			goto sst_write_err;
> +			goto out;
>  		WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
>  		ret = spi_nor_wait_till_ready(nor);
>  		if (ret)
> -			goto sst_write_err;
> +			goto out;
>  
>  		to++;
>  		actual++;
> @@ -2733,11 +2733,11 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  		/* write two bytes. */
>  		ret = spi_nor_write_data(nor, to, 2, buf + actual);
>  		if (ret < 0)
> -			goto sst_write_err;
> +			goto out;
>  		WARN(ret != 2, "While writing 2 bytes written %i bytes\n", ret);
>  		ret = spi_nor_wait_till_ready(nor);
>  		if (ret)
> -			goto sst_write_err;
> +			goto out;
>  		to += 2;
>  		nor->sst_write_second = true;
>  	}
> @@ -2745,32 +2745,32 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  
>  	ret = spi_nor_write_disable(nor);
>  	if (ret)
> -		goto sst_write_err;
> +		goto out;
>  
>  	ret = spi_nor_wait_till_ready(nor);
>  	if (ret)
> -		goto sst_write_err;
> +		goto out;
>  
>  	/* Write out trailing byte if it exists. */
>  	if (actual != len) {
>  		ret = spi_nor_write_enable(nor);
>  		if (ret)
> -			goto sst_write_err;
> +			goto out;
>  
>  		nor->program_opcode = SPINOR_OP_BP;
>  		ret = spi_nor_write_data(nor, to, 1, buf + actual);
>  		if (ret < 0)
> -			goto sst_write_err;
> +			goto out;
>  		WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
>  		ret = spi_nor_wait_till_ready(nor);
>  		if (ret)
> -			goto sst_write_err;
> +			goto out;
>  
>  		actual += 1;
>  
>  		ret = spi_nor_write_disable(nor);
>  	}
> -sst_write_err:
> +out:
>  	*retlen += actual;
>  	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
>  	return ret;


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 17/32] mtd: spi-nor: Move the WE and wait calls inside Write SR methods
  2019-10-29 11:17 ` [PATCH v3 17/32] mtd: spi-nor: Move the WE and wait calls inside Write SR methods Tudor.Ambarus
@ 2019-10-31 11:15   ` Boris Brezillon
  0 siblings, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 11:15 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:15 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Avoid duplicating code by moving the calls to spi_nor_write_enable() and
> spi_nor_wait_till_ready() inside the Write Status Register methods.
> 
> Move spi_nor_write_sr() to avoid forward declaration of
> spi_nor_wait_till_ready().
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 108 +++++++++++++++++-------------------------
>  1 file changed, 44 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index ed7c233a7208..5fb4d953b5c7 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -534,35 +534,6 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
>  	return ret;
>  }
>  
> -/*
> - * Write status register 1 byte
> - * Returns negative if error occurred.
> - */
> -static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
> -{
> -	int ret;
> -
> -	nor->bouncebuf[0] = val;
> -	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(1, nor->bouncebuf, 1));
> -
> -		ret = spi_mem_exec_op(nor->spimem, &op);
> -	} else {
> -		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
> -						     nor->bouncebuf, 1);
> -	}
> -
> -	if (ret)
> -		dev_err(nor->dev, "error %d writing SR\n", ret);
> -
> -	return ret;
> -
> -}
> -
>  static int macronix_set_4byte(struct spi_nor *nor, bool enable)
>  {
>  	int ret;
> @@ -854,6 +825,41 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
>  }
>  
>  /*
> + * Write status register 1 byte
> + * Returns negative if error occurred.
> + */
> +static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
> +{
> +	int ret;
> +
> +	nor->bouncebuf[0] = val;
> +
> +	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(1, nor->bouncebuf, 1));
> +
> +		ret = spi_mem_exec_op(nor->spimem, &op);
> +	} else {
> +		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
> +						     nor->bouncebuf, 1);
> +	}
> +
> +	if (ret) {
> +		dev_err(nor->dev, "error %d writing SR\n", ret);
> +		return ret;
> +	}
> +
> +	return spi_nor_wait_till_ready(nor);
> +}
> +
> +/*
>   * 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.
> @@ -895,18 +901,10 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
>  {
>  	int ret;
>  
> -	ret = spi_nor_write_enable(nor);
> -	if (ret)
> -		return ret;
> -
>  	ret = spi_nor_write_sr(nor, status_new);
>  	if (ret)
>  		return ret;
>  
> -	ret = spi_nor_wait_till_ready(nor);
> -	if (ret)
> -		return ret;
> -
>  	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
>  	if (ret)
>  		return ret;
> @@ -918,6 +916,10 @@ static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
>  {
>  	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_WRSR2, 1),
> @@ -931,10 +933,12 @@ static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
>  						     sr2, 1);
>  	}
>  
> -	if (ret)
> +	if (ret) {
>  		dev_err(nor->dev, "error %d writing SR2\n", ret);
> +		return ret;
> +	}
>  
> -	return ret;
> +	return spi_nor_wait_till_ready(nor);
>  }
>  
>  static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
> @@ -1864,18 +1868,10 @@ 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;
> -
>  	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
>  	if (ret)
>  		return ret;
>  
> -	ret = spi_nor_wait_till_ready(nor);
> -	if (ret)
> -		return ret;
> -
>  	ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
>  	if (ret)
>  		return ret;
> @@ -2041,18 +2037,10 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
>  	/* Update the Quad Enable bit. */
>  	*sr2 |= SR2_QUAD_EN_BIT7;
>  
> -	ret = spi_nor_write_enable(nor);
> -	if (ret)
> -		return ret;
> -
>  	ret = spi_nor_write_sr2(nor, sr2);
>  	if (ret)
>  		return ret;
>  
> -	ret = spi_nor_wait_till_ready(nor);
> -	if (ret)
> -		return ret;
> -
>  	/* Read back and check it. */
>  	ret = spi_nor_read_sr2(nor, sr2);
>  	if (ret)
> @@ -2084,15 +2072,7 @@ 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;
> -
> -	ret = spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
> -	if (ret)
> -		return ret;
> -
> -	return spi_nor_wait_till_ready(nor);
> +	return spi_nor_write_sr(nor, nor->bouncebuf[0] & ~mask);
>  }
>  
>  /**


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register
  2019-10-29 11:17 ` [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register Tudor.Ambarus
@ 2019-10-31 11:16   ` Boris Brezillon
  2019-11-02 10:48   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 11:16 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:17 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Constify the data to write to the Status Register.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 5fb4d953b5c7..274786e1988f 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -865,7 +865,7 @@ static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
>   * second byte will be written to the configuration register.
>   * Return negative if error occurred.
>   */
> -static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
> +static int spi_nor_write_sr_cr(struct spi_nor *nor, const u8 *sr_cr)
>  {
>  	int ret;
>  
> @@ -912,7 +912,7 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
>  	return ((nor->bouncebuf[0] & mask) != (status_new & mask)) ? -EIO : 0;
>  }
>  
> -static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
> +static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)
>  {
>  	int ret;
>  


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 19/32] mtd: spi-nor: Merge spi_nor_write_sr() and spi_nor_write_sr_cr()
  2019-10-29 11:17 ` [PATCH v3 19/32] mtd: spi-nor: Merge spi_nor_write_sr() and spi_nor_write_sr_cr() Tudor.Ambarus
@ 2019-10-31 11:17   ` Boris Brezillon
  0 siblings, 0 replies; 67+ messages in thread
From: Boris Brezillon @ 2019-10-31 11:17 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel

On Tue, 29 Oct 2019 11:17:18 +0000
<Tudor.Ambarus@microchip.com> wrote:

> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Merge
> static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
> static int spi_nor_write_sr_cr(struct spi_nor *nor, const u8 *sr_cr)
> into
> static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
> 
> The Status Register can be written with one or two bytes. Merge
> the two functions to avoid code duplication.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 13/32] mtd: spi-nor: Print error messages inside Reg Ops methods
  2019-10-31 11:05   ` Boris Brezillon
@ 2019-10-31 14:18     ` Tudor.Ambarus
  0 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-31 14:18 UTC (permalink / raw)
  To: boris.brezillon; +Cc: richard, linux-mtd, vigneshr, linux-kernel, miquel.raynal



On 10/31/2019 01:05 PM, Boris Brezillon wrote:
> External E-Mail
> 
> 
> On Tue, 29 Oct 2019 11:17:09 +0000
> <Tudor.Ambarus@microchip.com> wrote:
> 
>> From: Tudor Ambarus <tudor.ambarus@microchip.com>
>>
>> Spare the callers of printing error messages by themselves.
>>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
>> ---
>>  drivers/mtd/spi-nor/spi-nor.c | 165 +++++++++++++++++++++++++++++++-----------
>>  1 file changed, 123 insertions(+), 42 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index e5ed9012cd50..bc46b946ac77 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -394,6 +394,8 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
>>   */
>>  static int spi_nor_write_enable(struct spi_nor *nor)
>>  {
>> +	int ret;
>> +
>>  	if (nor->spimem) {
>>  		struct spi_mem_op op =
>>  			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 1),
>> @@ -401,10 +403,16 @@ static int spi_nor_write_enable(struct spi_nor *nor)
>>  				   SPI_MEM_OP_NO_DUMMY,
>>  				   SPI_MEM_OP_NO_DATA);
>>  
>> -		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_WREN,
>> +						     NULL, 0);
>>  	}
>>  
>> -	return nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
>> +	if (ret)
>> +		dev_err(nor->dev, "error %d on Write Enable\n", ret);
> 
> I thought we agreed on using dev_err_once() here (applies to other
> dev_err() calls). If it fails once it's unlikely to succeed on
> subsequent calls, and I don't think spamming the kernel logs is very
> useful.
> 

I used dev_err() and not dev_err_once() because if spi_nor_write_enable() fails,
we stop the execution and just return the spi_nor_write_enable()'s error. The
kernel logs will not be spammed because it will be just an error reported.

dev_err_once() would make sense if we change the method's return type from int
to void, but why to ignore possible errors from write enable/disable?


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr()
  2019-10-31 10:58   ` Boris Brezillon
@ 2019-10-31 14:26     ` Tudor.Ambarus
  0 siblings, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-10-31 14:26 UTC (permalink / raw)
  To: boris.brezillon; +Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel



On 10/31/2019 12:58 PM, Boris Brezillon wrote:
> External E-Mail
> 
> 
> On Tue, 29 Oct 2019 11:17:04 +0000
> <Tudor.Ambarus@microchip.com> wrote:
> 
>> From: Tudor Ambarus <tudor.ambarus@microchip.com>
>>
>> Let the callers pass the pointer to the DMA-able buffer where
>> the value of the Configuration Register will be written. This way we
>> avoid the casts between int and u8, which can be confusing.
>>
>> Callers stop compare the return value of spi_nor_read_cr() with negative,
>> spi_nor_read_cr() returns 0 on success and -errno otherwise.
>>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
> 
> There's just this &nor->bouncebuf[0] that I'd prefer to be turned into
> nor->bouncebuf if you're okay.
> 

I used &nor->bouncebuf[0] and not nor->bouncebuf for consistency reasons, but
sure I can update this. When writing the Status Register with two bytes, it
happens that in the code I pass pointer to the second byte, so &nor->bouncebuf[1].

I'm ok with both ways, and since you signaled it, I'll change according to your
suggestion.

Thanks for reviewing the series!

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods
  2019-10-29 11:16 ` [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods Tudor.Ambarus
  2019-10-31 10:34   ` Boris Brezillon
@ 2019-11-02 10:34   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:34 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:16 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> All the core functions should begin with "spi_nor_".
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 110 +++++++++++++++++++++---------------------
>  1 file changed, 56 insertions(+), 54 deletions(-)

Applied to spi-nor/next. Thanks.


^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line
  2019-10-29 11:16 ` [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line Tudor.Ambarus
  2019-10-31 10:34   ` Boris Brezillon
@ 2019-11-02 10:34   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:34 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:16 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Two new lines, one after another, drop one.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 1 -
>  1 file changed, 1 deletion(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations
  2019-10-29 11:16 ` [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations Tudor.Ambarus
  2019-10-31 10:35   ` Boris Brezillon
@ 2019-11-02 10:35   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:35 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:16 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Group all register methods up in the file, to avoid forward
> declarations.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 426 +++++++++++++++++++++---------------------
>  1 file changed, 213 insertions(+), 213 deletions(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods
  2019-10-29 11:16 ` [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods Tudor.Ambarus
  2019-10-31 10:36   ` Boris Brezillon
@ 2019-11-02 10:36   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:36 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:16 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> spi_mem_exec_op()
> nor->controller_ops->write_reg()
> nor->controller_ops->read_reg()
> spi_nor_wait_till_ready()
> Return 0 on success, -errno otherwise.
> 
> Stop compare with negative and compare with zero in all the register
> operations methods.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 23 +++++++++++++----------
>  1 file changed, 13 insertions(+), 10 deletions(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value
  2019-10-29 11:16 ` [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value Tudor.Ambarus
  2019-10-31 10:36   ` Boris Brezillon
@ 2019-11-02 10:37   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:37 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:16 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> ret is already of type int.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 15 ++++++---------
>  1 file changed, 6 insertions(+), 9 deletions(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err()
  2019-10-29 11:16 ` [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err() Tudor.Ambarus
  2019-10-31 10:43   ` Boris Brezillon
@ 2019-11-02 10:38   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:38 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:16 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Print identifying information about struct device.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Changed subject to "mtd: spi-nor: Print device info in case of error" and
applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops
  2019-10-29 11:16 ` [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops Tudor.Ambarus
  2019-10-31 10:48   ` Boris Brezillon
@ 2019-11-02 10:39   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:39 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:16 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Do not overwrite the error numbers received the Register Operations
> methods.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr()
  2019-10-29 11:17 ` [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr() Tudor.Ambarus
  2019-10-31 10:51   ` Boris Brezillon
@ 2019-11-02 10:42   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:42 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:17 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Let the callers pass the pointer to the DMA-able buffer where
> the value of the Status Register will be written. This way we
> avoid the casts between int and u8, which can be confusing.
> 
> Callers stop compare the return value of spi_nor_read_sr() with negative,
> spi_nor_read_sr() returns 0 on success and -errno otherwise.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 117 +++++++++++++++++++++++-------------------
>  1 file changed, 64 insertions(+), 53 deletions(-)

Replaced &nor->bouncebuf[0] with nor->bouncebuf and &sr_cr[0] with sr_cr and
applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr()
  2019-10-29 11:17 ` [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr() Tudor.Ambarus
  2019-10-31 10:53   ` Boris Brezillon
@ 2019-11-02 10:44   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:44 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:17 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Let the callers pass the pointer to the DMA-able buffer where
> the value of the Flag Status Register will be written. This way we
> avoid the casts between int and u8, which can be confusing.
> 
> Caller stops compare the return value of spi_nor_read_fsr() with negative,
> spi_nor_read_fsr() returns 0 on success and -errno otherwise.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 38 ++++++++++++++++++++------------------
>  1 file changed, 20 insertions(+), 18 deletions(-)

Replaced &nor->bouncebuf[0] with nor->bouncebuf and applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr()
  2019-10-29 11:17 ` [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr() Tudor.Ambarus
  2019-10-31 10:58   ` Boris Brezillon
@ 2019-11-02 10:45   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:45 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:17 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Let the callers pass the pointer to the DMA-able buffer where
> the value of the Configuration Register will be written. This way we
> avoid the casts between int and u8, which can be confusing.
> 
> Callers stop compare the return value of spi_nor_read_cr() with negative,
> spi_nor_read_cr() returns 0 on success and -errno otherwise.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 55 +++++++++++++++++++++++--------------------
>  1 file changed, 30 insertions(+), 25 deletions(-)

Replaced &nor->bouncebuf[0] with nor->bouncebuf and applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers
  2019-10-29 11:17 ` [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers Tudor.Ambarus
  2019-10-31 10:59   ` Boris Brezillon
@ 2019-11-02 10:46   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:46 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:17 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Drop the error messages from the callers, since the callees
> already print an error message in case of failure.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 50 +++++++++----------------------------------
>  1 file changed, 10 insertions(+), 40 deletions(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write()
  2019-10-29 11:17 ` [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write() Tudor.Ambarus
  2019-10-31 11:12   ` Boris Brezillon
@ 2019-11-02 10:47   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:47 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:17 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> In case the write of the first byte failed, retlen was incorrectly
> incremented to *retlen += actual; on the exit path. retlen should be
> incremented when actual data was written to the flash.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register
  2019-10-29 11:17 ` [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register Tudor.Ambarus
  2019-10-31 11:16   ` Boris Brezillon
@ 2019-11-02 10:48   ` Tudor.Ambarus
  1 sibling, 0 replies; 67+ messages in thread
From: Tudor.Ambarus @ 2019-11-02 10:48 UTC (permalink / raw)
  To: miquel.raynal, richard, vigneshr, boris.brezillon; +Cc: linux-mtd, linux-kernel



On 10/29/2019 01:17 PM, Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Constify the data to write to the Status Register.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Applied to spi-nor/next. Thanks.

^ permalink raw reply	[flat|nested] 67+ messages in thread

end of thread, other threads:[~2019-11-02 10:48 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-29 11:16 [PATCH v3 00/32] mtd: spi-nor: Quad Enable and (un)lock methods Tudor.Ambarus
2019-10-29 11:16 ` [PATCH v3 01/32] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods Tudor.Ambarus
2019-10-31 10:34   ` Boris Brezillon
2019-11-02 10:34   ` Tudor.Ambarus
2019-10-29 11:16 ` [PATCH v3 02/32] mtd: spi-nor: Drop duplicated new line Tudor.Ambarus
2019-10-31 10:34   ` Boris Brezillon
2019-11-02 10:34   ` Tudor.Ambarus
2019-10-29 11:16 ` [PATCH v3 03/32] mtd: spi-nor: Group all Reg Ops to avoid forward declarations Tudor.Ambarus
2019-10-31 10:35   ` Boris Brezillon
2019-11-02 10:35   ` Tudor.Ambarus
2019-10-29 11:16 ` [PATCH v3 04/32] mtd: spi-nor: Stop compare with negative in Reg Ops methods Tudor.Ambarus
2019-10-31 10:36   ` Boris Brezillon
2019-11-02 10:36   ` Tudor.Ambarus
2019-10-29 11:16 ` [PATCH v3 05/32] mtd: spi-nor: Drop explicit cast to int to already int value Tudor.Ambarus
2019-10-31 10:36   ` Boris Brezillon
2019-11-02 10:37   ` Tudor.Ambarus
2019-10-29 11:16 ` [PATCH v3 06/32] mtd: spi-nor: Use dev_err() instead of pr_err() Tudor.Ambarus
2019-10-31 10:43   ` Boris Brezillon
2019-11-02 10:38   ` Tudor.Ambarus
2019-10-29 11:16 ` [PATCH v3 07/32] mtd: spi-nor: Don't overwrite errno from Reg Ops Tudor.Ambarus
2019-10-31 10:48   ` Boris Brezillon
2019-11-02 10:39   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 08/32] mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr() Tudor.Ambarus
2019-10-31 10:51   ` Boris Brezillon
2019-11-02 10:42   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 09/32] mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr() Tudor.Ambarus
2019-10-31 10:53   ` Boris Brezillon
2019-11-02 10:44   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 10/32] mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr() Tudor.Ambarus
2019-10-31 10:58   ` Boris Brezillon
2019-10-31 14:26     ` Tudor.Ambarus
2019-11-02 10:45   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 11/32] mtd: spi-nor: Drop redundant error reports in Reg Ops callers Tudor.Ambarus
2019-10-31 10:59   ` Boris Brezillon
2019-11-02 10:46   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 12/32] mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr() Tudor.Ambarus
2019-10-31 11:02   ` Boris Brezillon
2019-10-29 11:17 ` [PATCH v3 13/32] mtd: spi-nor: Print error messages inside Reg Ops methods Tudor.Ambarus
2019-10-31 11:05   ` Boris Brezillon
2019-10-31 14:18     ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 14/32] mtd: spi-nor: Fix retlen handling in sst_write() Tudor.Ambarus
2019-10-31 11:12   ` Boris Brezillon
2019-11-02 10:47   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 15/32] mtd: spi-nor: Check for errors after each Register Operation Tudor.Ambarus
2019-10-31  6:57   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 16/32] mtd: spi-nor: Rename label as it is no longer generic Tudor.Ambarus
2019-10-31 11:14   ` Boris Brezillon
2019-10-29 11:17 ` [PATCH v3 17/32] mtd: spi-nor: Move the WE and wait calls inside Write SR methods Tudor.Ambarus
2019-10-31 11:15   ` Boris Brezillon
2019-10-29 11:17 ` [PATCH v3 18/32] mtd: spi-nor: Constify data to write to the Status Register Tudor.Ambarus
2019-10-31 11:16   ` Boris Brezillon
2019-11-02 10:48   ` Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 19/32] mtd: spi-nor: Merge spi_nor_write_sr() and spi_nor_write_sr_cr() Tudor.Ambarus
2019-10-31 11:17   ` Boris Brezillon
2019-10-29 11:17 ` [PATCH v3 20/32] mtd: spi-nor: Describe all the Reg Ops Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 21/32] mtd: spi-nor: Drop spansion_quad_enable() Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 22/32] mtd: spi-nor: Fix errno on Quad Enable methods Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 23/32] mtd: spi-nor: Check all the bits written, not just the BP ones Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 24/32] mtd: spi-nor: Print error message when the read back test fails Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 25/32] mtd: spi-nor: Fix clearing of QE bit on lock()/unlock() Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 26/32] mtd: spi-nor: Extend the QE Read Back test to the entire SR byte Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 27/32] mtd: spi-nor: Extend the QE Read Back test to both SR1 and SR2 Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 28/32] mtd: spi-nor: Rename CR_QUAD_EN_SPAN to SR2_QUAD_EN_BIT1 Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 29/32] mtd: spi-nor: Merge spansion Quad Enable methods Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 30/32] mtd: spi-nor: Rename macronix_quad_enable to spi_nor_sr1_bit6_quad_enable Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 31/32] mtd: spi-nor: Prepend "spi_nor_" to "sr2_bit7_quad_enable" Tudor.Ambarus
2019-10-29 11:17 ` [PATCH v3 32/32] mtd: spi-nor: Rework the disabling of block write protection Tudor.Ambarus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).