summaryrefslogtreecommitdiff
path: root/drivers/mtd/spi-nor
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-17 17:57:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-17 17:57:04 -0700
commit8541d8f725c673db3bd741947f27974358b2e163 (patch)
treea1e69d8655620db0043dbddef860b9da13d5f9e6 /drivers/mtd/spi-nor
parenta436a0b847c0fef9ead14f99bc03d8adbf66f15b (diff)
parentb2a4fe0960aee9a2c8045cfd26fbeacf30b26efe (diff)
downloadlwn-master.tar.gz
lwn-master.zip
Merge tag 'mtd/for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linuxHEADmaster
Pull MTD updates from Miquel Raynal: "MTD changes: - mtdconcat finally makes it in, after several years of being merged and reverted - Baikal SoC support is being removed, so MTD bits are being removed as well - misc cleanups NAND changes: - SunXi driver support for new versions of the Allwinner NAND controller. - DT-binding improvements and cleanups. - A few fixes (Realtek ECC and Winbond SPI NAND), aside with the usual load of misc changes. SPI NOR fixes: - Enable die erase on MT35XU02GCBA. We knew this flash needed this fixup since 7f77c561e227 ("mtd: spi-nor: micron-st: add TODO for fixing mt35xu02gcba") but did not add it due to lack of hardware to test on. - Fix locking on some Winbond w25q series flashes. - Fix Auto Address Increment (AAI) writes on SST that flashes that start on odd address. The write enable latch needs to be set again after the single byte program" * tag 'mtd/for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (44 commits) mtd: spinand: winbond: Declare the QE bit on W25NxxJW mtd: spi-nor: micron-st: Enable die erase support for MT35XU02GCBA mtd: spi-nor: winbond: Fix locking support for w25q256jw mtd: spi-nor: sst: Fix write enable before AAI sequence mtd: spi-nor: winbond: Fix locking support for w25q64jvm mtd: spi-nor: winbond: Fix locking support for w25q256jwm dt-bindings: mtd: mxc-nand: add missing compatible string and ref to nand-controller-legacy.yaml dt-bindings: mtd: gpmi-nand: ref to nand-controller-legacy.yaml dt-bindings: mtd: refactor NAND bindings and add nand-controller-legacy.yaml mtd: spinand: winbond: Clarify when to enable the HS bit mtd: rawnand: sunxi: introduce maximize variable user data length mtd: rawnand: sunxi: fix typos in comments mtd: rawnand: sunxi: change error prone variable name mtd: rawnand: sunxi: remove dead code mtd: rawnand: sunxi: make the code more self-explanatory mtd: rawnand: sunxi: replace hard coded value by a define - take2 mtd: rawnand: sunxi: do not count BBM bytes twice mtd: rawnand: sunxi: fix sunxi_nfc_hw_ecc_read_extra_oob mtd: rawnand: sunxi: sunxi_nand_ooblayout_free code clarification mtd: cmdlinepart: use a flexible array member ...
Diffstat (limited to 'drivers/mtd/spi-nor')
-rw-r--r--drivers/mtd/spi-nor/core.c2
-rw-r--r--drivers/mtd/spi-nor/core.h2
-rw-r--r--drivers/mtd/spi-nor/micron-st.c27
-rw-r--r--drivers/mtd/spi-nor/sst.c13
-rw-r--r--drivers/mtd/spi-nor/swp.c4
-rw-r--r--drivers/mtd/spi-nor/winbond.c4
6 files changed, 35 insertions, 17 deletions
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1eee519c01e5..5dd0b3cb5250 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2393,7 +2393,7 @@ static int spi_nor_spimem_check_readop(struct spi_nor *nor,
/* convert the dummy cycles to the number of bytes */
op.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) *
op.dummy.buswidth / 8;
- if (spi_nor_protocol_is_dtr(nor->read_proto))
+ if (spi_nor_protocol_is_dtr(read->proto))
op.dummy.nbytes *= 2;
return spi_nor_spimem_check_read_pp_op(nor, &op);
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 16b382d4f04f..e838c40a2589 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -413,7 +413,7 @@ struct spi_nor_flash_parameter {
* number of dummy cycles in read register ops.
* @smpt_map_id: called after map ID in SMPT table has been determined for the
* case the map ID is wrong and needs to be fixed.
- * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs
+ * @post_sfdp: called after SFDP has been parsed (is not called for SPI NORs
* that do not support RDSFDP). Typically used to tweak various
* parameters that could not be extracted by other means (i.e.
* when information provided by the SFDP/flash_info tables are
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index 88033384a71e..c75b0a1cd567 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -167,6 +167,16 @@ static int mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor)
0, 20, SPINOR_OP_MT_DTR_RD,
SNOR_PROTO_8_8_8_DTR);
+ /*
+ * Some batches of mt35xu512aba do not contain the OCT DTR command
+ * information, but do support OCT DTR mode. Add the settings for
+ * SNOR_CMD_PP_8_8_8_DTR here. This also makes sure the flash can switch
+ * to OCT DTR mode.
+ */
+ nor->params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
+ spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
+ SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
+
nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
nor->params->rdsr_dummy = 8;
nor->params->rdsr_addr_nbytes = 0;
@@ -185,7 +195,7 @@ static const struct spi_nor_fixups mt35xu512aba_fixups = {
.post_sfdp = mt35xu512aba_post_sfdp_fixup,
};
-static const struct spi_nor_fixups mt35xu01gbba_fixups = {
+static const struct spi_nor_fixups mt35_two_die_fixups = {
.post_sfdp = mt35xu512aba_post_sfdp_fixup,
.late_init = micron_st_nor_two_die_late_init,
};
@@ -202,25 +212,16 @@ static const struct flash_info micron_nor_parts[] = {
.id = SNOR_ID(0x2c, 0x5b, 0x1b),
.mfr_flags = USE_FSR,
.fixup_flags = SPI_NOR_IO_MODE_EN_VOLATILE,
- .fixups = &mt35xu01gbba_fixups,
+ .fixups = &mt35_two_die_fixups,
}, {
- /*
- * The MT35XU02GCBA flash device does not support chip erase,
- * according to its datasheet. It supports die erase, which
- * means the current driver implementation will likely need to
- * be converted to use die erase. Furthermore, similar to the
- * MT35XU01GBBA, the SPI_NOR_IO_MODE_EN_VOLATILE flag probably
- * needs to be enabled.
- *
- * TODO: Fix these and test on real hardware.
- */
.id = SNOR_ID(0x2c, 0x5b, 0x1c),
.name = "mt35xu02g",
.sector_size = SZ_128K,
.size = SZ_256M,
.no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ,
.mfr_flags = USE_FSR,
- .fixup_flags = SPI_NOR_4B_OPCODES,
+ .fixup_flags = SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE,
+ .fixups = &mt35_two_die_fixups,
},
};
diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index 175211fe6a5e..db02c14ba16f 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -203,6 +203,8 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
/* Start write from odd address. */
if (to % 2) {
+ bool needs_write_enable = (len > 1);
+
/* write one byte. */
ret = sst_nor_write_data(nor, to, 1, buf);
if (ret < 0)
@@ -210,6 +212,17 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
to++;
actual++;
+
+ /*
+ * Byte program clears the write enable latch. If more
+ * data needs to be written using the AAI sequence,
+ * re-enable writes.
+ */
+ if (needs_write_enable) {
+ ret = spi_nor_write_enable(nor);
+ if (ret)
+ goto out;
+ }
}
/* Write out most of the data here. */
diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
index 9b07f83aeac7..e67a81dbb6bf 100644
--- a/drivers/mtd/spi-nor/swp.c
+++ b/drivers/mtd/spi-nor/swp.c
@@ -28,8 +28,10 @@ static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor)
{
if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
return SR_TB_BIT6;
- else
+ else if (nor->flags & SNOR_F_HAS_SR_TB)
return SR_TB_BIT5;
+ else
+ return 0;
}
static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index fb855fe44733..eaa547d36aad 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -274,6 +274,7 @@ static const struct flash_info winbond_nor_parts[] = {
.id = SNOR_ID(0xef, 0x60, 0x19),
.name = "w25q256jw",
.size = SZ_32M,
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_NOR_4BIT_BP,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x60, 0x20),
@@ -295,6 +296,7 @@ static const struct flash_info winbond_nor_parts[] = {
.id = SNOR_ID(0xef, 0x70, 0x17),
.name = "w25q64jvm",
.size = SZ_8M,
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K,
}, {
.id = SNOR_ID(0xef, 0x70, 0x18),
@@ -337,7 +339,7 @@ static const struct flash_info winbond_nor_parts[] = {
.id = SNOR_ID(0xef, 0x80, 0x19),
.name = "w25q256jwm",
.size = SZ_32M,
- .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_NOR_4BIT_BP,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
.id = SNOR_ID(0xef, 0x80, 0x20),