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

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Tue Jan 12 15:59:29 PST 2016


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=32321e950d8a237d7e8f3a9b76220007dfa87544
Commit:     32321e950d8a237d7e8f3a9b76220007dfa87544
Parent:     6e75632ac34d2f63ab586880f7e9747bd9b708a6
Author:     Ezequiel García <ezequiel at vanguardiasur.com.ar>
AuthorDate: Mon Dec 28 17:54:51 2015 -0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Jan 6 17:18:34 2016 -0800

    mtd: spi-nor: wait until lock/unlock operations are ready
    
    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,
    which is required for Micron and Numonyx but should be harmless for
    others. 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>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index f8f36d4..ed0c19c 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -481,6 +481,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	int 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);
 	if (status_old < 0)
@@ -519,7 +520,10 @@ 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;
+	return spi_nor_wait_till_ready(nor);
 }
 
 /*
@@ -533,6 +537,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	int 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);
 	if (status_old < 0)
@@ -569,7 +574,10 @@ 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;
+	return spi_nor_wait_till_ready(nor);
 }
 
 /*



More information about the linux-mtd-cvs mailing list