* [PATCH 01/15] mtd: spi-nor: Only switch to ODTR if the chip has a callback for it
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 02/15] mtd: spi-nor: Fix spacing between arguments Miquel Raynal
` (13 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
Every manufacturer has its own way of entering ODTR mode. This is
typically implemented by the nor->params->set_octal_dtr()
callback. Without this callback the core cannot switch to ODTR. If it
actually does, the chip will stay in SDR mode and none of the subsequent
operations will succeed.
As of today, any chip not listed in any manufacturer/fixups table will
get parsed through SFDP and operated based on the best compromise the
core can find. A chip advertizing ODTR support in its SFDP content, will
therefore be operated in ODTR mode, leading to a 100% failure rate in
operating the chip out of the box.
Make sure ODTR page reads and page programs are not enabled for chips
without a ->set_octal_dtr() callback. If they support it, they will
anyway work in octal mode, but with an SDR bus interface.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
I faced this problem while operating a Winbond W35T01NW SPI NOR chip
which supports ODTR and properly advertizes it in its SFDP data. However
it was not expected that it would not be usable at all without a vendor
fixup. This commit allows to use all the features available through SFDP
without the IDs being listed. Basic SPI NOR tests then passed and speed
was obviously better than when constraining the I/O lines in DT:
Before:
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
After:
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
+ flash_speed /dev/mtd0 -dc10
not NAND flash, assume page size is 512 bytes.
scanning for bad eraseblocks
scanned 10 eraseblocks, 0 are bad
testing eraseblock write speed
eraseblock write speed is 802 KiB/s
testing eraseblock read speed
eraseblock read speed is 20000 KiB/s
testing page write speed
page write speed is 796 KiB/s
testing page read speed
page read speed is 9696 KiB/s
testing 2 page write speed
2 page write speed is 799 KiB/s
testing 2 page read speed
2 page read speed is 13333 KiB/s
Testing erase speed
erase speed is 445 KiB/s
---
drivers/mtd/spi-nor/core.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index e2b6efafdd8d..9c61ff4b93c3 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2991,15 +2991,21 @@ static int spi_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
{
int ret;
- if (!nor->params->set_octal_dtr)
- return 0;
-
if (!(nor->read_proto == SNOR_PROTO_8_8_8_DTR &&
nor->write_proto == SNOR_PROTO_8_8_8_DTR))
return 0;
- if (!(nor->params->flags & SNOR_F_IO_MODE_EN_VOLATILE))
- return 0;
+ if (enable &&
+ (!nor->params->set_octal_dtr ||
+ !(nor->params->flags & SNOR_F_IO_MODE_EN_VOLATILE))) {
+ struct spi_nor_hwcaps hwcaps = { .mask = SNOR_HWCAPS_ALL };
+
+ dev_err(nor->dev, "Cannot enter octal DTR mode\n");
+ hwcaps.mask &= ~(SNOR_HWCAPS_READ_8_8_8_DTR |
+ SNOR_HWCAPS_PP_8_8_8_DTR);
+
+ return spi_nor_setup(nor, &hwcaps);
+ }
ret = nor->params->set_octal_dtr(nor, enable);
if (ret)
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 02/15] mtd: spi-nor: Fix spacing between arguments
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
2026-10-02 12:21 ` [PATCH 01/15] mtd: spi-nor: Only switch to ODTR if the chip has a callback for it Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 03/15] mtd: spi-nor: Fix comment indentation to clarify the intent Miquel Raynal
` (12 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
A spurious tab got inserted there.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/spi-nor/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 9c61ff4b93c3..4b9e0410f2f5 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -773,7 +773,7 @@ int spi_nor_read_sr_ll(struct spi_nor *nor, u8 opcode, u8 *sr,
*
* Return: 0 on success, -errno otherwise.
*/
-static int spi_nor_write_sr_ll(struct spi_nor *nor, u8 opcode, const u8 *sr,
+static int spi_nor_write_sr_ll(struct spi_nor *nor, u8 opcode, const u8 *sr,
unsigned int len)
{
int ret, i;
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 03/15] mtd: spi-nor: Fix comment indentation to clarify the intent
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
2026-10-02 12:21 ` [PATCH 01/15] mtd: spi-nor: Only switch to ODTR if the chip has a callback for it Miquel Raynal
2026-10-02 12:21 ` [PATCH 02/15] mtd: spi-nor: Fix spacing between arguments Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 04/15] mtd: spi-nor: sfdp: Enhance a comment Miquel Raynal
` (11 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
The comment is misaligned with the content it describes and this kind of
bothered me when I first read that code. Move it to the correct
indentation level for the sake of clarity.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/spi-nor/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 4b9e0410f2f5..2bbec3feda39 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2459,7 +2459,8 @@ spi_nor_select_uniform_erase(struct spi_nor_erase_map *map)
*/
if (!erase && tested_erase->size)
erase = tested_erase;
- /* keep iterating to find the wanted_size */
+
+ /* keep iterating to find the wanted_size */
}
if (!erase)
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 04/15] mtd: spi-nor: sfdp: Enhance a comment
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (2 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 03/15] mtd: spi-nor: Fix comment indentation to clarify the intent Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 05/15] mtd: spi-nor: Drop stale values Miquel Raynal
` (10 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
While working in spi_nor_parse_sccr_mc(), the actual meaning of the
comment was not obvious to me. Not sure my proposal greatly improves it,
but at a first glane it feels clearer to me.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/spi-nor/sfdp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index c21a6953db96..9d5c0bbb53ae 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -1417,8 +1417,8 @@ static int spi_nor_parse_sccr_mc(struct spi_nor *nor,
le32_to_cpu_array(dwords, sccr_mc_header->length);
/*
- * Pair of DOWRDs (volatile and non-volatile register offsets) per
- * additional die. Hence, length = 2 * (number of additional dice).
+ * There is a pair of DWORDs (volatile and non-volatile register offsets)
+ * per additional die. Hence, length = 2 * (number of additional dice).
*/
n_dice = 1 + sccr_mc_header->length / 2;
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 05/15] mtd: spi-nor: Drop stale values
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (3 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 04/15] mtd: spi-nor: sfdp: Enhance a comment Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 06/15] mtd: spi-nor: Fix WRSR with ODTR chips Miquel Raynal
` (9 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
These apparently Micron-specific flash opcodes are used nowhere. They
are not exposed by a UAPI header either, so just drop them, they are
stale definitions.
I discovered them while working on Winbond VCR registers. For a
moment I thought VCR registers were wide spread (but, no).
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
include/linux/mtd/spi-nor.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index b3e3c6b10186..1a2f15d8426a 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -89,10 +89,6 @@
/* Used for Spansion flashes only. */
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
-/* Used for Micron flashes only. */
-#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
-#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
-
/* Used for GigaDevices and Winbond flashes. */
#define SPINOR_OP_ESECR 0x44 /* Erase Security registers */
#define SPINOR_OP_PSECR 0x42 /* Program Security registers */
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 06/15] mtd: spi-nor: Fix WRSR with ODTR chips
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (4 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 05/15] mtd: spi-nor: Drop stale values Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:34 ` sashiko-bot
2026-10-02 12:21 ` [PATCH 07/15] mtd: spi-nor: Allow configuring the actual number of dummy cycles Miquel Raynal
` (8 subsequent siblings)
14 siblings, 1 reply; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
The ODTR interface requires an even number of bytes in each section of
the operation. spi_nor_spimem_setup_op() takes care of the opcode phase,
but we have to adapt the rest of the operation ourself.
Inspiration comes from the spi_nor_read_sr_ll() helper which faces a
similar case.
Fixes: 63489002d397 ("mtd: spi-nor: Refactor Read Status/Write Status support")
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/spi-nor/core.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 2bbec3feda39..6e22342361c3 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -791,6 +791,17 @@ static int spi_nor_write_sr_ll(struct spi_nor *nor, u8 opcode, const u8 *sr,
if (nor->spimem) {
struct spi_mem_op op = SPI_NOR_WRSR_OP(opcode,
nor->bouncebuf, len);
+ if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
+ if (len != 1)
+ return -EOPNOTSUPP;
+
+ /*
+ * We don't want to write only one byte in DTR mode. So,
+ * duplicate the buffer and write 2.
+ */
+ op.data.nbytes = 2;
+ nor->bouncebuf[1] = nor->bouncebuf[0];
+ }
spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 06/15] mtd: spi-nor: Fix WRSR with ODTR chips
2026-10-02 12:21 ` [PATCH 06/15] mtd: spi-nor: Fix WRSR with ODTR chips Miquel Raynal
@ 2026-10-02 12:34 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-10-02 12:34 UTC (permalink / raw)
To: Richard Weinberger, Takahiro Kuwano, Miquel Raynal,
Pratyush Yadav, Vignesh Raghavendra, Michael Walle
Cc: linux-mtd, Steam Lin, Thomas Petazzoni, linux-kernel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] mtd: spi-nor: state leak in spi_nor_write_sr_ll() due to missing WEL cleanup
- [High] mtd: spi-nor: 16-bit status register writes erroneously rejected in 8-8-8 DTR mode
--
commit 4a237a858739ae2cb0d065925cac15d3e9009a72
Author: Miquel Raynal <miquel.raynal@bootlin.com>
mtd: spi-nor: Fix WRSR with ODTR chips
The ODTR interface requires an even number of bytes in each section of
the operation. spi_nor_spimem_setup_op() takes care of the opcode phase,
but we have to adapt the rest of the operation ourself.
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index cf23094021daa..381bbc13f82ff 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -791,6 +791,17 @@ static int spi_nor_write_sr_ll(struct spi_nor *nor, u8 opcode, const u8 *sr,
> if (nor->spimem) {
> struct spi_mem_op op = SPI_NOR_WRSR_OP(opcode,
> nor->bouncebuf, len);
> + if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
> + if (len != 1)
> + return -EOPNOTSUPP;
[Severity: High]
Does this early return leak the Write Enable Latch state?
In spi_nor_write_sr_ll(), spi_nor_write_enable() is called before this code
is reached, which transmits the WREN opcode to the flash chip and sets its
internal Write Enable Latch.
If len is not 1, this early return bypasses the execution of the intended WRSR
command and does not call spi_nor_write_disable() to manually clear the latch
bit.
Could this leave the flash globally write-enabled and vulnerable to accidental
data corruption?
[Severity: High]
Does this condition unintentionally reject 16-bit status register writes
in 8-8-8 DTR mode?
Callers like spi_nor_write_sr1_and_sr2() natively invoke spi_nor_write_sr_ll()
with len = 2 to write 16-bit status registers:
drivers/mtd/spi-nor/core.c:spi_nor_write_sr1_and_sr2() {
...
if (params->opcodes.write_sr1_and_sr2)
return spi_nor_write_sr_ll(nor,
params->opcodes.write_sr1_and_sr2,
sr, 2);
...
}
Returning -EOPNOTSUPP here blocks these valid operations without a fallback.
> +
> + /*
> + * We don't want to write only one byte in DTR mode. So,
> + * duplicate the buffer and write 2.
> + */
> + op.data.nbytes = 2;
> + nor->bouncebuf[1] = nor->bouncebuf[0];
> + }
>
> spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261002-winbond-master-spi-nor-w35t-v1-0-a22a2f95c26e@bootlin.com?part=6
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 07/15] mtd: spi-nor: Allow configuring the actual number of dummy cycles
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (5 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 06/15] mtd: spi-nor: Fix WRSR with ODTR chips Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:34 ` sashiko-bot
2026-10-02 12:21 ` [PATCH 08/15] mtd: spi-nor: Fix SWP for octal DTR chips Miquel Raynal
` (7 subsequent siblings)
14 siblings, 1 reply; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
The SPI NOR core selects the fastest read variant advertised by the SFDP
tables. This may or may not be a wise choice but at least it is simpler
as any bus frequency will just work. There is however a downside: the
number of dummy cycles is maximized (in case the bus frequency is really
fast, this is how the chip enforces a sufficient delay). Maximizing the
number of dummy cycles means that, if the amount of cycles is
configurable in the chip, we might not take its default value. When this
happens, we need to make sure that the chip is configured accordingly.
Crete a callback to configure the chip for expecting a specific number
of dummy cycles.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/spi-nor/core.c | 12 +++++++++++-
drivers/mtd/spi-nor/core.h | 2 ++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 6e22342361c3..152add3834fc 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2627,7 +2627,17 @@ static int spi_nor_setup(struct spi_nor *nor,
return err;
}
- return spi_nor_set_addr_nbytes(nor);
+ err = spi_nor_set_addr_nbytes(nor);
+ if (err)
+ return err;
+
+ if (nor->params->set_dummy) {
+ err = nor->params->set_dummy(nor, nor->read_dummy);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
bool spi_nor_fixup_match(const struct spi_nor *nor,
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 670182b3c2ad..b64f26b69c05 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -377,6 +377,7 @@ struct spi_nor_opcodes {
* Table.
* @otp: SPI NOR OTP info.
* @set_octal_dtr: enables or disables SPI NOR octal DTR mode.
+ * @set_dummy: configure the number of read dummy cycles.
* @quad_enable: enables SPI NOR quad mode.
* @qe_mask: two bytes mask used to set/clear the QE bit
* @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
@@ -410,6 +411,7 @@ struct spi_nor_flash_parameter {
struct spi_nor_otp otp;
int (*set_octal_dtr)(struct spi_nor *nor, bool enable);
+ int (*set_dummy)(struct spi_nor *nor, u8 dummy_cycles);
int (*quad_enable)(struct spi_nor *nor);
u8 qe_mask[2];
int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable);
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 07/15] mtd: spi-nor: Allow configuring the actual number of dummy cycles
2026-10-02 12:21 ` [PATCH 07/15] mtd: spi-nor: Allow configuring the actual number of dummy cycles Miquel Raynal
@ 2026-10-02 12:34 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-10-02 12:34 UTC (permalink / raw)
To: Pratyush Yadav, Richard Weinberger, Vignesh Raghavendra,
Takahiro Kuwano, Miquel Raynal, Michael Walle
Cc: Thomas Petazzoni, linux-mtd, Steam Lin, linux-kernel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] mtd: spi-nor: volatile dummy cycle hardware config lost on resume
--
commit 55807f7f87f4c66c05c4d5c678570e0e6e21c0c9
Author: Miquel Raynal <miquel.raynal@bootlin.com>
mtd: spi-nor: Allow configuring the actual number of dummy cycles
This commit introduces a callback to configure the actual number of dummy
cycles expected by the SPI NOR chip. It ensures that the chip is configured
properly when the number of dummy cycles is maximized for the fastest read
variant advertised by the SFDP tables.
> Crete a callback to configure the chip for expecting a specific number
> of dummy cycles.
[Severity: Low]
This isn't a bug, but there's a typo (Crete) in the commit message.
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 381bbc13f82ff..f45c2c07d0245 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -2636,7 +2636,17 @@ static int spi_nor_setup(struct spi_nor *nor,
> return err;
> }
>
> - return spi_nor_set_addr_nbytes(nor);
> + err = spi_nor_set_addr_nbytes(nor);
> + if (err)
> + return err;
> +
> + if (nor->params->set_dummy) {
> + err = nor->params->set_dummy(nor, nor->read_dummy);
> + if (err)
> + return err;
> + }
[Severity: High]
Is the dummy cycle hardware configuration lost during a suspend and resume
cycle?
When a SPI NOR chip loses power during system suspend, its volatile dummy
cycle configuration register is reset to its power-on default.
Upon system resume, spi_nor_resume() calls spi_nor_init() to re-initialize
the volatile state of the chip:
drivers/mtd/spi-nor/core.c:spi_nor_resume() {
...
/* re-initialize the nor chip */
ret = spi_nor_init(nor);
...
}
However, spi_nor_init() does not restore the dummy cycle configuration using
nor->params->set_dummy().
Since the software state (nor->read_dummy) retains the custom dummy cycle
count while the hardware reverts to the default count, will subsequent reads
be misaligned and lead to data corruption?
> +
> + return 0;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261002-winbond-master-spi-nor-w35t-v1-0-a22a2f95c26e@bootlin.com?part=7
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 08/15] mtd: spi-nor: Fix SWP for octal DTR chips
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (6 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 07/15] mtd: spi-nor: Allow configuring the actual number of dummy cycles Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:29 ` sashiko-bot
2026-10-02 12:21 ` [PATCH 09/15] mtd: spi-nor: winbond: Prepare the introduction of W35TxxNW parts Miquel Raynal
` (6 subsequent siblings)
14 siblings, 1 reply; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
During the recent rework of status registers handling, we mostly focused
on quad capable devices, partially skipping ODTR devices in our mental
model. It seems that many (if not all?) ODTR devices have no SR2 read
opcode and have other control mechanisms. Because of that, the current
support in swp.c is broken, because reading back the written value may
or may not lead to the expected result.
Let's extend the _careful() suffix to the helper reading back the values
and comparing them. Maybe this "carfulness" will have to be moved back
to the core, it is a bit early to state it. For now, let's just make
sure that we read back 0s without errors when virtually accessing SR2 on
those chips.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/spi-nor/core.c | 2 +-
drivers/mtd/spi-nor/core.h | 1 +
drivers/mtd/spi-nor/swp.c | 23 +++++++++++++++++++++--
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 152add3834fc..4926a3193891 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -927,7 +927,7 @@ int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)
*
* Return 0 or errno.
*/
-static int spi_nor_write_sr1_and_sr2(struct spi_nor *nor, const u8 *sr)
+int spi_nor_write_sr1_and_sr2(struct spi_nor *nor, const u8 *sr)
{
struct spi_nor_flash_parameter *params = nor->params;
int ret;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index b64f26b69c05..cee33ca18b04 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -664,6 +664,7 @@ int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2);
int spi_nor_read_sr1_and_sr2(struct spi_nor *nor, u8 *sr);
int spi_nor_write_sr1(struct spi_nor *nor, const u8 *sr1);
int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2);
+int spi_nor_write_sr1_and_sr2(struct spi_nor *nor, const u8 *sr);
int spi_nor_write_sr1_and_sr2_and_check(struct spi_nor *nor, const u8 *sr);
ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,
diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
index 7e667e4ca84d..e9cf2ca23234 100644
--- a/drivers/mtd/spi-nor/swp.c
+++ b/drivers/mtd/spi-nor/swp.c
@@ -240,6 +240,25 @@ static int spi_nor_read_sr1_and_sr2_careful(struct spi_nor *nor, u8 *sr)
return spi_nor_read_sr2_careful(nor, &sr[1]);
}
+static int spi_nor_write_sr1_and_sr2_and_check_careful(struct spi_nor *nor, const u8 *sr)
+{
+ u8 tmp[2];
+ int ret;
+
+ ret = spi_nor_write_sr1_and_sr2(nor, sr);
+ if (ret)
+ return ret;
+
+ ret = spi_nor_read_sr1_and_sr2_careful(nor, tmp);
+ if (ret)
+ return ret;
+
+ if (sr[0] != tmp[0] || sr[1] != tmp[1])
+ return -EIO;
+
+ return 0;
+}
+
/*
* Keep a local cache containing all lock-related bits for debugfs use only.
* This way, debugfs never needs to access the flash directly.
@@ -407,7 +426,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)
(ofs_old < ofs_new || (ofs_new + len_new) < (ofs_old + len_old)))
return -EINVAL;
- ret = spi_nor_write_sr1_and_sr2_and_check(nor, best_status_new);
+ ret = spi_nor_write_sr1_and_sr2_and_check_careful(nor, best_status_new);
if (ret)
return ret;
@@ -529,7 +548,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
(ofs_new < ofs_old || (ofs_old + len_old) < (ofs_new + len_new)))
return -EINVAL;
- ret = spi_nor_write_sr1_and_sr2_and_check(nor, best_status_new);
+ ret = spi_nor_write_sr1_and_sr2_and_check_careful(nor, best_status_new);
if (ret)
return ret;
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 08/15] mtd: spi-nor: Fix SWP for octal DTR chips
2026-10-02 12:21 ` [PATCH 08/15] mtd: spi-nor: Fix SWP for octal DTR chips Miquel Raynal
@ 2026-10-02 12:29 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-10-02 12:29 UTC (permalink / raw)
To: Takahiro Kuwano, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, Michael Walle, Pratyush Yadav
Cc: Steam Lin, linux-mtd, Thomas Petazzoni, linux-kernel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] mtd: spi-nor: uninitialized stack memory read causes spurious -EIO in SR2 check
--
commit 7f40280ba9ff306f160cda218a293f8e370be331
Author: Miquel Raynal <miquel.raynal@bootlin.com>
mtd: spi-nor: Fix SWP for octal DTR chips
During the recent rework of status registers handling, we mostly focused
on quad capable devices, partially skipping ODTR devices in our mental
model. It seems that many (if not all?) ODTR devices have no SR2 read
opcode and have other control mechanisms. Because of that, the current
support in swp.c is broken, because reading back the written value may
or may not lead to the expected result.
Let's extend the _careful() suffix to the helper reading back the values
and comparing them. Maybe this "carfulness" will have to be moved back
to the core, it is a bit early to state it. For now, let's just make
sure that we read back 0s without errors when virtually accessing SR2 on
those chips.
[ ... ]
> diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
> index 7e667e4ca84d5..e9cf2ca232341 100644
> --- a/drivers/mtd/spi-nor/swp.c
> +++ b/drivers/mtd/spi-nor/swp.c
> @@ -240,6 +240,25 @@ static int spi_nor_read_sr1_and_sr2_careful(struct spi_nor *nor, u8 *sr)
> return spi_nor_read_sr2_careful(nor, &sr[1]);
> }
>
> +static int spi_nor_write_sr1_and_sr2_and_check_careful(struct spi_nor *nor, const u8 *sr)
> +{
> + u8 tmp[2];
[Severity: High]
Does this allocate uninitialized memory on the stack?
> + int ret;
> +
> + ret = spi_nor_write_sr1_and_sr2(nor, sr);
> + if (ret)
> + return ret;
> +
> + ret = spi_nor_read_sr1_and_sr2_careful(nor, tmp);
> + if (ret)
> + return ret;
> +
> + if (sr[0] != tmp[0] || sr[1] != tmp[1])
[Severity: High]
Does this unconditionally compare tmp[1] against sr[1] even when it contains
uninitialized stack data?
In the call chain spi_nor_read_sr1_and_sr2_careful() ->
spi_nor_read_sr2_careful(), if the device lacks a read_sr2 opcode and is not
quad-enabled, the function falls back to returning 0 without populating the
sr2 value.
If tmp[1] remains uninitialized, this check might fail and return -EIO
sporadically for devices lacking a read_sr2 opcode, such as the ODTR devices
targeted by this patch. Could this lead to unpredictable failures during
lock and unlock operations?
Would zero-initializing tmp avoid this issue?
> + return -EIO;
> +
> + return 0;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261002-winbond-master-spi-nor-w35t-v1-0-a22a2f95c26e@bootlin.com?part=8
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 09/15] mtd: spi-nor: winbond: Prepare the introduction of W35TxxNW parts
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (7 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 08/15] mtd: spi-nor: Fix SWP for octal DTR chips Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:45 ` sashiko-bot
2026-10-02 12:21 ` [PATCH 10/15] mtd: spi-nor: winbond: Add support for W35T64NW-C Miquel Raynal
` (5 subsequent siblings)
14 siblings, 1 reply; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
This is a new octal DTR family, they require:
- a callback for enter octal DTR modes,
- a callback to configure the number of dummy cycles (since the spi-nor
core picks up a variant for which the number of duty cycles does not
match the hardware default).
These chips have a flag regiter, but no SR2.
They also feature automatic error correction (SECDEC).
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/spi-nor/winbond.c | 96 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index f2daab39ea57..d33e693ed711 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -11,6 +11,13 @@
#define WINBOND_NOR_OP_RDEAR 0xc8 /* Read Extended Address Register */
#define WINBOND_NOR_OP_WREAR 0xc5 /* Write Extended Address Register */
#define WINBOND_NOR_OP_SELDIE 0xc2 /* Select active die */
+#define WINBOND_NOR_OP_WR_VCR 0x81 /* Write VCR registers */
+#define WINBOND_NOR_VCR_IO_MODE_CFG_REG 0x00 /* IO mode configuration address (VCR) */
+#define WINBOND_NOR_VCR_IO_MODE_SSDR 0xFF
+#define WINBOND_NOR_VCR_IO_MODE_ODDR 0xE7
+#define WINBOND_NOR_VCR_DUMMY_CFG_REG 0x01 /* Dummy cycle configuration address (VCR) */
+#define WINBOND_NOR_OP_RD_FR 0x70 /* Read Flag registers */
+#define WINBOND_NOR_OP_CL_FR 0x50 /* Clear Flag registers */
#define WINBOND_NOR_WREAR_OP(buf) \
SPI_MEM_OP(SPI_MEM_OP_CMD(WINBOND_NOR_OP_WREAR, 0), \
@@ -24,6 +31,12 @@
SPI_MEM_OP_NO_DUMMY, \
SPI_MEM_OP_DATA_OUT(1, buf, 0))
+#define WINBOND_NOR_WR_VCR_OP(addr, buf) \
+ SPI_MEM_OP(SPI_MEM_OP_CMD(WINBOND_NOR_OP_WR_VCR, 0), \
+ SPI_MEM_OP_ADDR(3, addr, 0), \
+ SPI_MEM_OP_NO_DUMMY, \
+ SPI_MEM_OP_DATA_OUT(1, buf, 0))
+
static bool is_w25qxxrv(const struct spi_nor *nor)
{
struct sfdp_header *sfdp_h = spi_nor_sfdp_get_header(nor);
@@ -252,6 +265,87 @@ static const struct spi_nor_fixups winbond_nor_ecc_configuration_fixups = {
.post_sfdp = winbond_nor_ecc_configuration_post_sfdp_fixups,
};
+static int winbond_w35txxnw_nor_write_vcr(struct spi_nor *nor, u8 addr, u8 val)
+{
+ u8 *buf = nor->bouncebuf;
+ struct spi_mem_op op;
+ int ret;
+
+ if (!nor->spimem)
+ return -EOPNOTSUPP;
+
+ ret = spi_nor_write_enable(nor);
+ if (ret)
+ return ret;
+
+ buf[0] = val;
+ buf[1] = val;
+ op = (struct spi_mem_op)WINBOND_NOR_WR_VCR_OP(addr, buf);
+ spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+ if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
+ op.addr.nbytes = 4;
+ op.data.nbytes = 2;
+ }
+
+ return spi_mem_exec_op(nor->spimem, &op);
+}
+
+static int winbond_w35txxnw_nor_set_dummy(struct spi_nor *nor, u8 dummy_cycles)
+{
+ return winbond_w35txxnw_nor_write_vcr(nor, WINBOND_NOR_VCR_DUMMY_CFG_REG,
+ dummy_cycles);
+}
+
+static int winbond_w35txxnw_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
+{
+ enum spi_nor_protocol proto_aft;
+ u8 *buf = nor->bouncebuf;
+ u8 rdid_dummy_aft, val;
+ int ret;
+
+ if (enable) {
+ val = WINBOND_NOR_VCR_IO_MODE_ODDR;
+ proto_aft = SNOR_PROTO_8_8_8_DTR;
+ rdid_dummy_aft = 16;
+ } else {
+ val = WINBOND_NOR_VCR_IO_MODE_SSDR;
+ proto_aft = SNOR_PROTO_1_1_1;
+ rdid_dummy_aft = 0;
+ }
+
+ ret = winbond_w35txxnw_nor_write_vcr(nor, WINBOND_NOR_VCR_IO_MODE_CFG_REG, val);
+ if (ret)
+ return ret;
+
+ /* Read flash ID to make sure the switch was successful */
+ ret = spi_nor_read_id(nor, 0, rdid_dummy_aft, buf, proto_aft);
+ if (ret) {
+ dev_err(nor->dev, "Cannot read JEDEC ID after %s 8D-8D-8D mode (%d)\n",
+ enable ? "enabling" : "disabling", ret);
+ return ret;
+ }
+
+ if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int winbond_w35txxnw_nor_late_init(struct spi_nor *nor)
+{
+ nor->params->set_octal_dtr = winbond_w35txxnw_nor_set_octal_dtr;
+ nor->params->set_dummy = winbond_w35txxnw_nor_set_dummy;
+ nor->params->opcodes.read_sr2 = 0;
+ nor->params->opcodes.write_sr1_and_sr2 = 0;
+
+ return 0;
+}
+
+static const struct spi_nor_fixups winbond_w35txxnw_nor_fixups = {
+ .post_sfdp = winbond_nor_ecc_configuration_post_sfdp_fixups,
+ .late_init = winbond_w35txxnw_nor_late_init,
+};
+
static const struct flash_info winbond_nor_parts[] = {
{
.id = SNOR_ID(0xef, 0x30, 0x10),
@@ -673,6 +767,8 @@ static const struct spi_nor_fixup winbond_fixups[] = {
.fixups = &winbond_nor_multi_die_fixups },
{ .id = SNOR_ID(0xef, 0x40, 0x22), .match = winbond_jv_match,
.fixups = &winbond_nor_multi_die_fixups },
+ { .id = SNOR_ID(0xef, 0x5b), .fixup_flags = SPI_NOR_IO_MODE_EN_VOLATILE,
+ .fixups = &winbond_w35txxnw_nor_fixups },
{ .id = SNOR_ID(0xef, 0x60), .match = winbond_pw_with_ecc_match,
.fixups = &winbond_nor_ecc_configuration_fixups },
{ .id = SNOR_ID(0xef, 0x60), .match = winbond_pw_match,
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 09/15] mtd: spi-nor: winbond: Prepare the introduction of W35TxxNW parts
2026-10-02 12:21 ` [PATCH 09/15] mtd: spi-nor: winbond: Prepare the introduction of W35TxxNW parts Miquel Raynal
@ 2026-10-02 12:45 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-10-02 12:45 UTC (permalink / raw)
To: Takahiro Kuwano, Vignesh Raghavendra, Richard Weinberger,
Pratyush Yadav, Miquel Raynal, Michael Walle
Cc: linux-mtd, linux-kernel, Thomas Petazzoni, Steam Lin
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] mtd: spi-nor: winbond: volatile dummy cycle config lost on resume
--
commit 61a4c1418798804759dbb5ceb316bd56196b68ad
Author: Miquel Raynal <miquel.raynal@bootlin.com>
mtd: spi-nor: winbond: Prepare the introduction of W35TxxNW parts
This commit introduces support for the Winbond W35TxxNW octal DTR flash
family. It implements callbacks for entering octal DTR mode and configuring
the number of dummy cycles via volatile VCR registers.
> --- a/drivers/mtd/spi-nor/winbond.c
> +++ b/drivers/mtd/spi-nor/winbond.c
[ ... ]
> +static int winbond_w35txxnw_nor_set_dummy(struct spi_nor *nor, u8 dummy_cycles)
> +{
> + return winbond_w35txxnw_nor_write_vcr(nor, WINBOND_NOR_VCR_DUMMY_CFG_REG,
> + dummy_cycles);
> +}
> +
> +static int winbond_w35txxnw_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
> +{
> + enum spi_nor_protocol proto_aft;
> + u8 *buf = nor->bouncebuf;
> + u8 rdid_dummy_aft, val;
> + int ret;
> +
> + if (enable) {
> + val = WINBOND_NOR_VCR_IO_MODE_ODDR;
> + proto_aft = SNOR_PROTO_8_8_8_DTR;
> + rdid_dummy_aft = 16;
> + } else {
> + val = WINBOND_NOR_VCR_IO_MODE_SSDR;
> + proto_aft = SNOR_PROTO_1_1_1;
> + rdid_dummy_aft = 0;
> + }
> +
> + ret = winbond_w35txxnw_nor_write_vcr(nor, WINBOND_NOR_VCR_IO_MODE_CFG_REG, val);
> + if (ret)
> + return ret;
[Severity: High]
Will this lose the dummy cycle configuration upon system resume?
When the system resumes, the SPI NOR subsystem invokes spi_nor_resume(),
which calls spi_nor_init(). The spi_nor_init() function calls
spi_nor_set_octal_dtr() to re-enable octal DTR mode, which invokes
winbond_w35txxnw_nor_set_octal_dtr():
spi_nor_resume()
spi_nor_init()
spi_nor_set_octal_dtr()
winbond_w35txxnw_nor_set_octal_dtr()
Since winbond_w35txxnw_nor_set_dummy() writes to a volatile register
(WINBOND_NOR_VCR_DUMMY_CFG_REG), that configuration is lost during sleep.
Because the core does not call the nor->params->set_dummy() callback on
resume, and winbond_w35txxnw_nor_set_octal_dtr() does not explicitly
reconfigure the dummy cycles when Octal DTR is re-enabled, will the SPI
controller and the flash chip disagree on the number of dummy cycles used
for read operations?
Can this cause data corruption on read operations after a system
suspend/resume cycle?
> +
> + /* Read flash ID to make sure the switch was successful */
> + ret = spi_nor_read_id(nor, 0, rdid_dummy_aft, buf, proto_aft);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261002-winbond-master-spi-nor-w35t-v1-0-a22a2f95c26e@bootlin.com?part=9
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 10/15] mtd: spi-nor: winbond: Add support for W35T64NW-C
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (8 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 09/15] mtd: spi-nor: winbond: Prepare the introduction of W35TxxNW parts Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 11/15] mtd: spi-nor: winbond: Add support for W35T12NW-C Miquel Raynal
` (4 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
W35T devices are Winbond new octal DTR capable SPI-NORs.
16 bytes chunks are protected against single errors. In case a
non-aligned write happens, ECC is locally disabled until the next erase.
These chips may leverage lock CMP support, by using a Winbond specific
register instead of SR2 which is gone. This feature is therefore not
supported nor flagged.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b17
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0104ff00080117800000ff84010102e00000ff05010106e800
00ff8701011c000100ff0a000108700100ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff030000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31444e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000000000000000000000feffe300fe
ffe300058880060588a10070888400708885818501f0b1b501f0d8b8cefb
b02e2cd388a489aa00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000081850310
b1b503100000000000000601000000000000b1050000e700000000000000
00000000000000000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
30be7c3bf1f6a00ea4e56585dc9c929026555f2e2c16ab5f6fdfbc3819fc0d21 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 17 02 00 00
size 8.00 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (8.00 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-007fffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-007fffff | unlocked | 64
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
[ 24.901260] random: crng init done
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_read
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 8388608 (8M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x800000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_read
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-007fffff | unlocked | 64
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x800000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_read
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_read
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_read2
1f43b7c8eba44e56b616e12b515ff61c3d31307e3f9cedab13d3de08c15fb0b8 spi_test
731475d3e8b53d9a8c4e86ef609a765a590ac6a325ed450eeec725531ce6734a spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-007fffff | locked | 64
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=8388608
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=64
+ ss=131072
+ bps=2
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 8126464 4
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-007bffff | unlocked | 62
007c0000-007fffff | locked | 2
+ flash_lock -u /dev/mtd0 8126464 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-007dffff | unlocked | 63
007e0000-007fffff | locked | 1
+ flash_lock -u /dev/mtd0
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-007fffff | unlocked | 64
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 4
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0003ffff | locked | 2
00040000-007fffff | unlocked | 62
+ flash_lock -u /dev/mtd0 131072 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 1
00020000-007fffff | unlocked | 63
---
drivers/mtd/spi-nor/winbond.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index d33e693ed711..e1a93f27f24c 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -620,6 +620,10 @@ static const struct flash_info winbond_nor_parts[] = {
.id = SNOR_ID(0xef, 0xa0, 0x22),
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP,
+ }, {
+ /* W35T64NW-C */
+ .id = SNOR_ID(0xef, 0x5b, 0x17),
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6,
}, {
/*
* Catch all entry to make sure all chips solely relying
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 11/15] mtd: spi-nor: winbond: Add support for W35T12NW-C
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (9 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 10/15] mtd: spi-nor: winbond: Add support for W35T64NW-C Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 12/15] mtd: spi-nor: winbond: Add support for W35T25NW-C/E Miquel Raynal
` (3 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
W35T devices are Winbond new octal DTR capable SPI-NORs.
16 bytes chunks are protected against single errors. In case a
non-aligned write happens, ECC is locally disabled until the next erase.
These chips may leverage lock CMP support, by using a Winbond specific
register instead of SR2 which is gone. This feature is therefore not
supported nor flagged.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b18
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0104ff00080117800000ff84010102e00000ff05010106e800
00ff8701011c000100ff0a000108700100ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff070000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31447e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000000000000000000000feffe300fe
ffe300058880060588a10070888400708885818501f0b1b501f0d8b8cefb
b02e2cd388a489aa00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000081850310
b1b503100000000000000601000000000000b1050000e700000000000000
00000000000000000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
128f9dde70c802230cf6171d8f00f00c4088f72cfde19f7ebf8f85f56aa900a6 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 18 02 00 00
size 16.0 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (16.0 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-00ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00ffffff | unlocked | 64
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 16777216 (16M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x1000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00ffffff | unlocked | 64
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x1000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read2
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
f3623e31ffb383dba8eb6ca97cf24de7450c0872dc49b851c7ff9eed559369eb spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00ffffff | locked | 64
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=16777216
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=64
+ ss=262144
+ bps=4
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 16252928 8
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00f7ffff | unlocked | 62
00f80000-00ffffff | locked | 2
+ flash_lock -u /dev/mtd0 16252928 4
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00fbffff | unlocked | 63
00fc0000-00ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 -16777216 512
flash_lock: invalid option -- '1'
Utility to lock, unlock, or check the lock status of the flash.
Default action: lock
Usage: flash_lock [options] [--] <mtd device> [offset [block count]]
Options:
-h --help Display this help and exit
-V --version Display version information and exit
-i --islocked Check if flash region is locked
-l --lock Lock a region of flash
-u --unlock Unlock a region of flash
<mtd device> MTD device node or 'mtd:<name>'
If offset is not specified, it defaults to 0.
If block count is not specified, it defaults to all blocks.
A block count of -1 means all blocks.
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00ffffff | unlocked | 64
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 8
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0007ffff | locked | 2
00080000-00ffffff | unlocked | 62
+ flash_lock -u /dev/mtd0 262144 4
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0003ffff | locked | 1
00040000-00ffffff | unlocked | 63
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b18
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0104ff00080117800000ff84010102e00000ff05010106e800
00ff8701011c000100ff0a000108700100ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff070000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31447e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000000000000000000000feffe300fe
ffe300058880060588a10070888400708885818501f0b1b501f0d8b8cefb
b02e2cd388a489aa00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000081850310
b1b503100000000000000601000000000000b1050000e700000000000000
00000000000000000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
128f9dde70c802230cf6171d8f00f00c4088f72cfde19f7ebf8f85f56aa900a6 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 18 02 00 00
size 16.0 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (16.0 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-00ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00ffffff | unlocked | 64
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 16777216 (16M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x1000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00ffffff | unlocked | 64
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x1000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_read2
9b28460593b87e540ca650cc9d82034f94de1a91ca68690d23a23b3aae37d53d spi_test
f3623e31ffb383dba8eb6ca97cf24de7450c0872dc49b851c7ff9eed559369eb spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00ffffff | locked | 64
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=16777216
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=64
+ ss=262144
+ bps=4
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 16252928 8
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00f7ffff | unlocked | 62
00f80000-00ffffff | locked | 2
+ flash_lock -u /dev/mtd0 16252928 4
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-00fbffff | unlocked | 63
00fc0000-00ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 8
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0007ffff | locked | 2
00080000-00ffffff | unlocked | 62
+ flash_lock -u /dev/mtd0 262144 4
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0003ffff | locked | 1
00040000-00ffffff | unlocked | 63
---
drivers/mtd/spi-nor/winbond.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index e1a93f27f24c..0bb8e5a8c7c3 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -624,6 +624,10 @@ static const struct flash_info winbond_nor_parts[] = {
/* W35T64NW-C */
.id = SNOR_ID(0xef, 0x5b, 0x17),
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6,
+ }, {
+ /* W35T12NW-C */
+ .id = SNOR_ID(0xef, 0x5b, 0x18),
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6,
}, {
/*
* Catch all entry to make sure all chips solely relying
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 12/15] mtd: spi-nor: winbond: Add support for W35T25NW-C/E
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (10 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 11/15] mtd: spi-nor: winbond: Add support for W35T12NW-C Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 13/15] mtd: spi-nor: winbond: Add support for W35T51NW-C/E Miquel Raynal
` (2 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
W35T devices are Winbond new octal DTR capable SPI-NORs.
16 bytes chunks are protected against single errors. In case a
non-aligned write happens, ECC is locally disabled until the next erase.
These chips may leverage lock CMP support, by using a Winbond specific
register instead of SR2 which is gone. This feature is therefore not
supported nor flagged.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
Logs for W35T25NW-C:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b19
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0104ff00080117800000ff84010102e00000ff05010106e800
00ff8701011c000100ff0a000108700100ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff0f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e3144ce96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000000000000000000000feffe300fe
ffe300058880060588a10070888400708885818501f0b1b501f0d8b8cefb
b02e2cd388a489aa00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000081850310
b1b503100000000000000601000000000000b1050000e700000000000000
00000000000000000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
7dc00a62e47b0203b6adb38450098d68cecace4884e825796f884b0c4fcce121 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 19 02 00 00
size 32.0 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (32.0 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-01ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01ffffff | unlocked | 512
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_read
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 33554432 (32M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x2000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_read
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01ffffff | unlocked | 512
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x2000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_read
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_read
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_read2
8d3ebdc5576a51d5f2e6d9f132622ae9cc00919227e4fbce7c18fa2525392921 spi_test
f999d2e58cf596a1357e3337b36766bdb402cae729f224d8b952dbea6e46eee4 spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01ffffff | locked | 512
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=33554432
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=512
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 33423360 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01fdffff | unlocked | 510
01fe0000-01ffffff | locked | 2
+ flash_lock -u /dev/mtd0 33423360 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01feffff | unlocked | 511
01ff0000-01ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 25165824 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-017fffff | unlocked | 384
01800000-01ffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-01ffffff | unlocked | 510
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-01ffffff | unlocked | 511
Logs for W35T25NW-E:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b19
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0102ff00080117800000ff84010102e00000ff05010106e800
00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff0f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e3144ce96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b00003807e19c10000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
bcb73821a779a8a28f58a3c2e231894142037f04f90e22c7a0527081badeda43 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 19 02 00 00
size 32.0 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (32.0 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-01ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01ffffff | unlocked | 512
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
[ 15.836899] random: crng init done
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_read
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 33554432 (32M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x2000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_read
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01ffffff | unlocked | 512
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x2000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_read
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_read
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_read2
de381056136f8b252a3379e234ed001de3a44ab1bf4e1f7ac715197fbeea75d1 spi_test
4753383c1bb538600660c0d666594f8c9d821565994882212d463ffa46d08185 spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01ffffff | locked | 512
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=33554432
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=512
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 33423360 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01fdffff | unlocked | 510
01fe0000-01ffffff | locked | 2
+ flash_lock -u /dev/mtd0 33423360 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-01feffff | unlocked | 511
01ff0000-01ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 25165824 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-017fffff | unlocked | 384
01800000-01ffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-01ffffff | unlocked | 510
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-01ffffff | unlocked | 511
---
drivers/mtd/spi-nor/winbond.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index 0bb8e5a8c7c3..55b27bc7e467 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -628,6 +628,11 @@ static const struct flash_info winbond_nor_parts[] = {
/* W35T12NW-C */
.id = SNOR_ID(0xef, 0x5b, 0x18),
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6,
+ }, {
+ /* W35T25NW-C/E */
+ .id = SNOR_ID(0xef, 0x5b, 0x19),
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
+ SPI_NOR_4BIT_BP,
}, {
/*
* Catch all entry to make sure all chips solely relying
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 13/15] mtd: spi-nor: winbond: Add support for W35T51NW-C/E
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (11 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 12/15] mtd: spi-nor: winbond: Add support for W35T25NW-C/E Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:32 ` sashiko-bot
2026-10-02 12:21 ` [PATCH 14/15] mtd: spi-nor: winbond: Add support for W35T01NW-C/E Miquel Raynal
2026-10-02 12:21 ` [PATCH 15/15] mtd: spi-nor: winbond: Add support for W35T02NW-C/E Miquel Raynal
14 siblings, 1 reply; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
W35T devices are Winbond new octal DTR capable SPI-NORs.
16 bytes chunks are protected against single errors. In case a
non-aligned write happens, ECC is locally disabled until the next erase.
These chips may leverage lock CMP support, by using a Winbond specific
register instead of SR2 which is gone. This feature is therefore not
supported nor flagged.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
Logs for W35T51NW-C:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b1a
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0104ff00080117800000ff84010102e00000ff05010106e800
00ff8701011c000100ff0a000108700100ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff1f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31458e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000000000000000000000feffe300fe
ffe300058880060588a10070888400708885818501f0b1b501f0d8b8cefb
b02e2cd388a489aa00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000081850310
b1b503100000000000000601000000000000b1050000e700000000000000
00000000000000000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
a290fdc72785300e3b6efb4964a0a41524707263735ec4a23009b97324aad7ce /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 1a 02 00 00
size 64.0 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (64.0 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-03ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03ffffff | unlocked | 1024
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
[ 14.761055] random: crng init done
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_read
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 67108864 (64M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x4000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_read
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03ffffff | unlocked | 1024
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x4000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_read
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_read
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_read2
199319e974b9cb046bac51c1cb64a6843c4851127fbf072a4240063d47727177 spi_test
8ff4795e570cf12e4257adf7e9c761c516f0b1d5e1a2a2af68542add3025fc34 spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03ffffff | locked | 1024
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=67108864
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=1024
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 66977792 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03fdffff | unlocked | 1022
03fe0000-03ffffff | locked | 2
+ flash_lock -u /dev/mtd0 66977792 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03feffff | unlocked | 1023
03ff0000-03ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 58720256 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-037fffff | unlocked | 896
03800000-03ffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-03ffffff | unlocked | 1022
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-03ffffff | unlocked | 1023
Logs for W35T51NW-E:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b1a
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0102ff00080117800000ff84010102e00000ff05010106e800
00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff1f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31458e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
4e27c223863fa0982fa54d0b74b0bbfbf370c105f94bc0e49d0d02d8db79cbed /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/[ 54.436903] random: crng init done
debug/spi-nor/spi0.0/params
name (null)
id ef 5b 1a 02 00 00
size 64.0 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (64.0 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-03ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03ffffff | unlocked | 1024
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_read
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 67108864 (64M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x4000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_read
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03ffffff | unlocked | 1024
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x4000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_read
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_read
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_read2
a4a0c6780d8568c36179c019fcb621ac2b59e98127a16996b3264e6be64cf746 spi_test
496fde2866968c0c852f11ffcd7d1fc9e79f88256bf6f0ebf700d795483eecef spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03ffffff | locked | 1024
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=67108864
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=1024
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 66977792 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03fdffff | unlocked | 1022
03fe0000-03ffffff | locked | 2
+ flash_lock -u /dev/mtd0 66977792 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-03feffff | unlocked | 1023
03ff0000-03ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 58720256 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-037fffff | unlocked | 896
03800000-03ffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-03ffffff | unlocked | 1022
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-03ffffff | unlocked | 1023
---
drivers/mtd/spi-nor/winbond.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index 55b27bc7e467..a830cad64c1c 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -633,6 +633,11 @@ static const struct flash_info winbond_nor_parts[] = {
.id = SNOR_ID(0xef, 0x5b, 0x19),
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
SPI_NOR_4BIT_BP,
+ }, {
+ /* W35T51NW-C/E */
+ .id = SNOR_ID(0xef, 0x5b, 0x1a),
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
+ SPI_NOR_4BIT_BP,
}, {
/*
* Catch all entry to make sure all chips solely relying
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 13/15] mtd: spi-nor: winbond: Add support for W35T51NW-C/E
2026-10-02 12:21 ` [PATCH 13/15] mtd: spi-nor: winbond: Add support for W35T51NW-C/E Miquel Raynal
@ 2026-10-02 12:32 ` sashiko-bot
0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-10-02 12:32 UTC (permalink / raw)
To: Miquel Raynal, Michael Walle, Takahiro Kuwano, Pratyush Yadav,
Richard Weinberger, Vignesh Raghavendra
Cc: linux-mtd, Thomas Petazzoni, linux-kernel, Steam Lin
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] mtd: spi-nor: uninitialized memory read in write_sr1_and_sr2_and_check_careful()
--
commit db0463242c1b895f1a8729e983049e5010571c6d
Author: Miquel Raynal <miquel.raynal@bootlin.com>
mtd: spi-nor: winbond: Add support for W35T51NW-C/E
This commit adds support for the Winbond W35T51NW-C/E SPI-NOR flash
devices. It defines their JEDEC ID and configures features like block
protection and locking by setting SPI_NOR_HAS_LOCK and related flags.
> diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
> index 05a80af3a6b93..0e350dcfbb755 100644
> --- a/drivers/mtd/spi-nor/winbond.c
> +++ b/drivers/mtd/spi-nor/winbond.c
[ ... ]
> @@ -633,6 +633,11 @@ static const struct flash_info winbond_nor_parts[] = {
> .id = SNOR_ID(0xef, 0x5b, 0x19),
> .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
> SPI_NOR_4BIT_BP,
> + }, {
> + /* W35T51NW-C/E */
> + .id = SNOR_ID(0xef, 0x5b, 0x1a),
> + .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
> + SPI_NOR_4BIT_BP,
[Severity: High]
Does enabling SPI_NOR_HAS_LOCK on this chip lead to an uninitialized memory
read and random failures during lock/unlock operations?
Since W35T chips disable reading SR2 via winbond_w35txxnw_nor_late_init()
by setting nor->params->opcodes.read_sr2 = 0, lock operations eventually reach
spi_nor_write_sr1_and_sr2_and_check_careful() with an uninitialized buffer:
drivers/mtd/spi-nor/swp.c:spi_nor_write_sr1_and_sr2_and_check_careful() {
u8 tmp[2];
int ret;
...
ret = spi_nor_read_sr1_and_sr2_careful(nor, tmp);
if (ret)
return ret;
if (sr[0] != tmp[0] || sr[1] != tmp[1])
return -EIO;
}
Because read_sr2 is 0, spi_nor_read_sr2_careful() safely returns 0 but leaves
tmp[1] completely uninitialized.
When the code unconditionally evaluates if (sr[1] != tmp[1]), tmp[1] contains
stack garbage, which will randomly not match sr[1]. Can this cause spurious
-EIO failures for lock and unlock functionality on these chips?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261002-winbond-master-spi-nor-w35t-v1-0-a22a2f95c26e@bootlin.com?part=13
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 14/15] mtd: spi-nor: winbond: Add support for W35T01NW-C/E
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (12 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 13/15] mtd: spi-nor: winbond: Add support for W35T51NW-C/E Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
2026-10-02 12:21 ` [PATCH 15/15] mtd: spi-nor: winbond: Add support for W35T02NW-C/E Miquel Raynal
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
W35T devices are Winbond new octal DTR capable SPI-NORs.
16 bytes chunks are protected against single errors. In case a
non-aligned write happens, ECC is locally disabled until the next erase.
These chips may leverage lock CMP support, by using a Winbond specific
register instead of SR2 which is gone. This feature is therefore not
supported nor flagged.
Parts suffixed -C and -E are very similar: the -C variant comes with
additional JESD216F SFDP tables.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
Logs for W35T01NW-C:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b1b
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0104ff00080117800000ff84010102e00000ff05010106e800
00ff8701011c000100ff0a000108700100ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff3f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31458e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000000000000000000000feffe300fe
ffe300058880060588a10070888400708885818501f0b1b501f0d8b8cefb
b02e2cd388a489aa00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000081850310
b1b503100000000000000601000000000000b1050000e700000000000000
00000000000000000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
0f951707aa460006d0e534d524464a6a0d2adca6eeab522c59497868e6828542 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 1b 02 00 00
size 128 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (128 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-07ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | unlocked | 2048
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
[ 20.788989] random: crng init done
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_read
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 134217728 (128M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x8000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_read
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | unlocked | 2048
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x8000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_read
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_read
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_read2
c8b5315b436f2f21d320704b5cae5349aa5f8c4bf245cfc7a7b55b26d139442a spi_test
2cc891e91c0aefad43e9bee4348aeddb34a2040c83e3fa3e920aaca7b4790203 spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | locked | 2048
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=134217728
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=2048
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 134086656 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07fdffff | unlocked | 2046
07fe0000-07ffffff | locked | 2
+ flash_lock -u /dev/mtd0 134086656 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07feffff | unlocked | 2047
07ff0000-07ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 125829120 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-077fffff | unlocked | 1920
07800000-07ffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-07ffffff | unlocked | 2046
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-07ffffff | unlocked | 2047
Logs for W35T01NW-E:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b1b
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0102ff00080117800000ff84010102e00000ff05010106e800
00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff3f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31458e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
0fee35c2e84c7f280fe44e3249695f6075ab26716936deb21d4297dbafa39221 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/[ 41.869223] random: crng init done
debug/spi-nor/spi0.0/params
name (null)
id ef 5b 1b 02 00 00
size 128 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (128 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-07ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | unlocked | 2048
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_read
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 134217728 (128M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x8000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_read
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | unlocked | 2048
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x8000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_read
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_read
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_read2
7997c21fcdcafb94f39c027a6f5e6df4dd92307a6e4e099b26b6a7038bfe479c spi_test
a273339ca03dac990920b5ce3f664c784b7c427bfc9fff36904ba220f4d78a4e spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | locked | 2048
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=134217728
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=2048
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 134086656 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07fdffff | unlocked | 2046
07fe0000-07ffffff | locked | 2
+ flash_lock -u /dev/mtd0 134086656 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07feffff | unlocked | 2047
07ff0000-07ffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 125829120 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-077fffff | unlocked | 1920
07800000-07ffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-07ffffff | unlocked | 2046
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-07ffffff | unlocked | 2047
---
drivers/mtd/spi-nor/winbond.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index a830cad64c1c..b86b9ca1fbc6 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -638,6 +638,11 @@ static const struct flash_info winbond_nor_parts[] = {
.id = SNOR_ID(0xef, 0x5b, 0x1a),
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
SPI_NOR_4BIT_BP,
+ }, {
+ /* W35T01NW-C/E */
+ .id = SNOR_ID(0xef, 0x5b, 0x1b),
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
+ SPI_NOR_4BIT_BP,
}, {
/*
* Catch all entry to make sure all chips solely relying
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 15/15] mtd: spi-nor: winbond: Add support for W35T02NW-C/E
2026-10-02 12:21 [PATCH 00/15] mtd: spi-nor: winbond: Add support for the W35TxxNW family Miquel Raynal
` (13 preceding siblings ...)
2026-10-02 12:21 ` [PATCH 14/15] mtd: spi-nor: winbond: Add support for W35T01NW-C/E Miquel Raynal
@ 2026-10-02 12:21 ` Miquel Raynal
14 siblings, 0 replies; 21+ messages in thread
From: Miquel Raynal @ 2026-10-02 12:21 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Takahiro Kuwano,
Richard Weinberger, Vignesh Raghavendra
Cc: Thomas Petazzoni, Steam Lin, linux-mtd, linux-kernel, Miquel Raynal
W35T devices are Winbond new octal DTR capable SPI-NORs.
16 bytes chunks are protected against single errors. In case a
non-aligned write happens, ECC is locally disabled until the next erase.
These chips may leverage lock CMP support, by using a Winbond specific
register instead of SR2 which is gone. This feature is therefore not
supported nor flagged.
Parts suffixed -C and -E are very similar: the -C variant comes with
additional JESD216F SFDP tables.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
Logs for W35T02NW-C:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b1c
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0104ff00080117800000ff84010102e00000ff05010106e800
00ff8701011c000100ff0a000108700100ffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff7f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31458e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000000000000000000000feffe300fe
ffe300058880060588a10070888400708885818501f0b1b501f0d8b8cefb
b02e2cd388a489aa00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000081850310
b1b503100000000000000601000000000000b1050000e700000000000000
00000000000000000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
26f67ccb92a7569acbe700c8592f109a9391698fc3efea5336bdbf3fa9884c7c /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 1c 02 00 00
size 256 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (256 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-0fffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0fffffff | unlocked | 4096
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
[ 22.593225] random: crng init done
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_read
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 268435456 (256M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x10000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_read
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0fffffff | unlocked | 4096
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x10000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_read
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_read
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_read2
c35c5b4833cf3c08ce055b3c2ec7a687059ecbe3c97eeee79a918869e7fdf2ae spi_test
187b09308be122170581bb64e59b5e65d6eaa01c1ade0f55232f757a96c819d0 spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0fffffff | locked | 4096
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=268435456
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=4096
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 268304384 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0ffdffff | unlocked | 4094
0ffe0000-0fffffff | locked | 2
+ flash_lock -u /dev/mtd0 268304384 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0ffeffff | unlocked | 4095
0fff0000-0fffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 260046848 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0f7fffff | unlocked | 3968
0f800000-0fffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-0fffffff | unlocked | 4094
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-0fffffff | unlocked | 4095
Logs for W35T02NW-E:
********************
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef5b1c
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
534644500a0102ff00080117800000ff84010102e00000ff05010106e800
00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe5208affffffff7f0000000000000000eeffffffffff
0000ffff00000c200f5210d800003452b50082e31458e96376337a757a75
ffc3d55c008070ffe950f8a110cb088b0000ac0000000000ffffff860000
00000000000000000000ffffffff430ef0ff215cdcff000b0016b181b585
00d87b9d580b000030f6de9c10000000
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
afd9273978f29205307fae0a666613a304b67dfdddc2f6450a197623fd9b76b3 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-8S
opcode 0x7c
mode cycles 0
dummy cycles 8
1S-8S-8S
opcode 0xcc
mode cycles 0
dummy cycles 16
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 22
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
8D-8D-8D
opcode 0x12
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 5b 1c 02 00 00
size 256 MiB
write size 16
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_SR_TB_BIT6 | HAS_4BIT_BP | IO_MODE_EN_VOLATILE | SOFT_RESET | ECC | NO_WP
opcodes
read 0x0b
dummy cycles 22
erase 0xdc
program 0x12
SR1 read 0x05
SR1 write 0x01
8D extension repeat
protocols
read 8D-8D-8D
write 8D-8D-8D
register 8D-8D-8D
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (64.0 KiB) [3]
c7 (256 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-0fffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0fffffff | unlocked | 4096
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
[ 19.188920] random: crng init done
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_read
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 268435456 (256M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x10000000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_read
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0fffffff | unlocked | 4096
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x10000000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_read
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_read
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_read2
c989d1f44e0786ffa833ee3566bf5bed4fee67ade0b27b23568306e17876e393 spi_test
89425399a935397bb5560d889cc8f534a21e5fbfadd18053b8e0cc2edd164f3a spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0fffffff | locked | 4096
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=268435456
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=4096
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 268304384 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0ffdffff | unlocked | 4094
0ffe0000-0fffffff | locked | 2
+ flash_lock -u /dev/mtd0 268304384 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0ffeffff | unlocked | 4095
0fff0000-0fffffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 260046848 128
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0f7fffff | unlocked | 3968
0f800000-0fffffff | locked | 128
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-0fffffff | unlocked | 4094
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-0fffffff | unlocked | 4095
---
drivers/mtd/spi-nor/winbond.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index b86b9ca1fbc6..9f144f2795d0 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -643,6 +643,11 @@ static const struct flash_info winbond_nor_parts[] = {
.id = SNOR_ID(0xef, 0x5b, 0x1b),
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
SPI_NOR_4BIT_BP,
+ }, {
+ /* W35T02NW-C/E */
+ .id = SNOR_ID(0xef, 0x5b, 0x1c),
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 |
+ SPI_NOR_4BIT_BP,
}, {
/*
* Catch all entry to make sure all chips solely relying
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread