[PATCH] mtd: spi-nor: wait until lock/unlock operations are ready

Ezequiel Garcia ezequiel at vanguardiasur.com.ar
Sun Nov 22 20:09:57 EST 2015


On Micron and Numonyx devices, the status register write command
(WRSR), raises a work-in-progress bit (WIP) on the status register.
The datasheets for these devices specify that while the status
register write is in progress, the status register WIP bit can still
be read to check the end of the operation.

This commit adds a wait_till_ready call on lock/unlock operations,
only for these manufacturers. This is needed to prevent applications
from issuing erase or program operations before the unlock operation
is completed.

Reported-by: Stas Sergeev <stsp at list.ru>
Signed-off-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
---
 drivers/mtd/spi-nor/spi-nor.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index e9c26c0e2258..acc9b05e02be 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -485,6 +485,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	u8 status_old, status_new;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 	u8 shift = ffs(mask) - 1, pow, val;
+	int ret;
 
 	status_old = read_sr(nor);
 
@@ -521,7 +522,13 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 		return -EINVAL;
 
 	write_enable(nor);
-	return write_sr(nor, status_new);
+	ret = write_sr(nor, status_new);
+	if (ret)
+		return ret;
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+	return 0;
 }
 
 /*
@@ -535,6 +542,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	uint8_t status_old, status_new;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 	u8 shift = ffs(mask) - 1, pow, val;
+	int ret;
 
 	status_old = read_sr(nor);
 
@@ -569,7 +577,13 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 		return -EINVAL;
 
 	write_enable(nor);
-	return write_sr(nor, status_new);
+	ret = write_sr(nor, status_new);
+	if (ret)
+		return ret;
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+	return 0;
 }
 
 /*
-- 
2.6.2




More information about the linux-mtd mailing list