Messages in this thread Patch in this message | | | From | Jonas Bonn <> | Subject | [PATCH 1/1] spi-nor: always respect write-protect input | Date | Fri, 25 Jan 2019 11:55:07 +0100 |
| |
The status register bit SRWD (status register write disable) is described in many words in the datasheets but effectively boils down to:
i) if set, respect WP# when trying to change protection bits; ii) if unset, ignore WP# when trying to change protection bits
In short, the bit determines whether the WP# signal is honored or not.
It's difficult to imagine the use-case where the WP# is connected and asserted but the user doesn't want to respect its setting. As such, this patch sets the SRWD bit unconditionally so that the WP# is _always_ respected; hardware that doesn't care about WP# normally won't even have it connected.
Tested on a Cypress s25fl512s. With this patch, the WP# is always respected, irregardless of whether any flash protection bits are set.
Signed-off-by: Jonas Bonn <jonas@norrbonn.se> CC: Marek Vasut <marek.vasut@gmail.com> CC: David Woodhouse <dwmw2@infradead.org> CC: Brian Norris <computersforpeace@gmail.com> CC: Boris Brezillon <bbrezillon@kernel.org> CC: Richard Weinberger <richard@nod.at> CC: linux-mtd@lists.infradead.org --- drivers/mtd/spi-nor/spi-nor.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index c6064479b614..c960c097e0bc 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1230,9 +1230,6 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) status_new = (status_old & ~mask & ~SR_TB) | val; - /* Disallow further writes if WP pin is asserted */ - status_new |= SR_SRWD; - if (!use_top) status_new |= SR_TB; @@ -1312,10 +1309,6 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) status_new = (status_old & ~mask & ~SR_TB) | val; - /* Don't protect status register if we're fully unlocked */ - if (lock_len == 0) - status_new &= ~SR_SRWD; - if (!use_top) status_new |= SR_TB; @@ -3918,6 +3911,7 @@ static int spi_nor_setup(struct spi_nor *nor, static int spi_nor_init(struct spi_nor *nor) { int err; + int sr; /* * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up @@ -3953,6 +3947,16 @@ static int spi_nor_init(struct spi_nor *nor) set_4byte(nor, true); } + /* Always respect the WP# (write-protect) input */ + sr = read_sr(nor); + if (sr < 0) { + dev_err(nor->dev, "error while reading status register\n"); + return -EINVAL; + } + sr |= SR_SRWD; + return write_sr_and_check(nor, sr, SR_SRWD); + + return 0; } -- 2.19.1
| |