[PATCH v4 06/25] mtd: spi-nor: Move the fixup flags into the fixup list
Miquel Raynal
miquel.raynal at bootlin.com
Wed Sep 2 09:59:20 PDT 2026
The idea of the fixup flags is to enable fixups without having to repeat
the same fixup function over and over again. It overall reduces the
boilerplate with a similar intent: fixing our knowledge of the flash.
Move the fixup_flags field as well as the associated flag definitions to
the spi_nor_fixup structure and enable them based on the IDs.
No functional change.
Suggested-by: Michael Walle <mwalle at kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
drivers/mtd/spi-nor/core.c | 27 +++++++++++++++++++--------
drivers/mtd/spi-nor/core.h | 30 ++++++++++++++----------------
drivers/mtd/spi-nor/gigadevice.c | 4 ++--
drivers/mtd/spi-nor/issi.c | 8 ++++----
drivers/mtd/spi-nor/macronix.c | 4 ++--
drivers/mtd/spi-nor/micron-st.c | 21 ++++++++++++---------
drivers/mtd/spi-nor/sfdp.c | 6 +++---
drivers/mtd/spi-nor/spansion.c | 6 +++---
8 files changed, 59 insertions(+), 47 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index a9360998d34b..77d28c99c33b 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2367,7 +2367,7 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
fixups = nor->manufacturer->fixups;
for (i = 0; i < nor->manufacturer->nfixups; i++) {
- if (fixups[i].fixups->post_bfpt &&
+ if (fixups[i].fixups && fixups[i].fixups->post_bfpt &&
spi_nor_fixup_match(nor, &fixups[i])) {
ret = fixups[i].fixups->post_bfpt(nor, bfpt_header, bfpt);
if (ret)
@@ -2667,7 +2667,7 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
fixups = nor->manufacturer->fixups;
for (i = 0; i < nor->manufacturer->nfixups; i++) {
- if (fixups[i].fixups->default_init &&
+ if (fixups[i].fixups && fixups[i].fixups->default_init &&
spi_nor_fixup_match(nor, &fixups[i]))
fixups[i].fixups->default_init(nor);
}
@@ -2799,13 +2799,24 @@ static void spi_nor_init_flags(struct spi_nor *nor)
*/
static void spi_nor_init_fixup_flags(struct spi_nor *nor)
{
- const u8 fixup_flags = nor->info->fixup_flags;
+ const struct spi_nor_fixup *fixups;
+ unsigned int i;
- if (fixup_flags & SPI_NOR_4B_OPCODES)
- nor->flags |= SNOR_F_4B_OPCODES;
+ if (!nor->manufacturer || !nor->manufacturer->fixups)
+ return;
- if (fixup_flags & SPI_NOR_IO_MODE_EN_VOLATILE)
- nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
+ fixups = nor->manufacturer->fixups;
+
+ for (i = 0; i < nor->manufacturer->nfixups; i++) {
+ if (!fixups[i].fixup_flags ||
+ !spi_nor_fixup_match(nor, &fixups[i]))
+ continue;
+
+ if (fixups[i].fixup_flags & SPI_NOR_4B_OPCODES)
+ nor->flags |= SNOR_F_4B_OPCODES;
+ if (fixups[i].fixup_flags & SPI_NOR_IO_MODE_EN_VOLATILE)
+ nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
+ }
}
/**
@@ -2830,7 +2841,7 @@ static int spi_nor_late_init_params(struct spi_nor *nor)
fixups = nor->manufacturer->fixups;
for (i = 0; i < nor->manufacturer->nfixups; i++) {
- if (fixups[i].fixups->late_init &&
+ if (fixups[i].fixups && fixups[i].fixups->late_init &&
spi_nor_fixup_match(nor, &fixups[i])) {
ret = fixups[i].fixups->late_init(nor);
if (ret)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 32a2d485d31d..1533f79b9039 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -450,11 +450,25 @@ struct spi_nor_fixups {
* @id: (optional) flash ID this fixup applies to, may only match the
* ID prefix, eg. just the first few bytes to match a whole family
* @match: (optional) custom match function (can be used together with @id)
+ * @fixup_flags: flags that indicate support that can be discovered via SFDP
+ * ideally, but can not be discovered for this particular flash
+ * because the SFDP table that indicates this support is not
+ * defined by the flash. In case the table for this support is
+ * defined but has wrong values, one should instead use a
+ * post_sfdp() hook to set the SNOR_F equivalent flag.
+ *
+ * SPI_NOR_4B_OPCODES: use dedicated 4byte address op codes to support
+ * memory size above 128Mib.
+ * SPI_NOR_IO_MODE_EN_VOLATILE: flash enables the best available I/O mode
+ * via a volatile bit.
* @fixups: the fixup hooks to apply when this entry matches
*/
struct spi_nor_fixup {
const struct spi_nor_id *id;
bool (*match)(const struct spi_nor *nor);
+ u8 fixup_flags;
+#define SPI_NOR_4B_OPCODES BIT(0)
+#define SPI_NOR_IO_MODE_EN_VOLATILE BIT(1)
const struct spi_nor_fixups *fixups;
};
@@ -519,22 +533,10 @@ struct spi_nor_id {
* SPI_NOR_OCTAL_DTR_READ: flash supports octal DTR Read.
* SPI_NOR_OCTAL_DTR_PP: flash supports Octal DTR Page Program.
*
- * @fixup_flags: flags that indicate support that can be discovered via SFDP
- * ideally, but can not be discovered for this particular flash
- * because the SFDP table that indicates this support is not
- * defined by the flash. In case the table for this support is
- * defined but has wrong values, one should instead use a
- * post_sfdp() hook to set the SNOR_F equivalent flag.
- *
- * SPI_NOR_4B_OPCODES: use dedicated 4byte address op codes to support
- * memory size above 128Mib.
- * SPI_NOR_IO_MODE_EN_VOLATILE: flash enables the best available I/O mode
- * via a volatile bit.
* @mfr_flags: manufacturer private flags. Used in the manufacturer fixup
* hooks to differentiate support between flashes of the same
* manufacturer.
* @otp_org: flash's OTP organization.
- * @fixups: part specific fixup hooks.
*/
struct flash_info {
char *name;
@@ -566,10 +568,6 @@ struct flash_info {
#define SPI_NOR_OCTAL_DTR_READ BIT(6)
#define SPI_NOR_OCTAL_DTR_PP BIT(7)
- u8 fixup_flags;
-#define SPI_NOR_4B_OPCODES BIT(0)
-#define SPI_NOR_IO_MODE_EN_VOLATILE BIT(1)
-
u8 mfr_flags;
const struct spi_nor_otp_organization *otp;
diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c
index f76fd0dedd0a..6a2e6ebda148 100644
--- a/drivers/mtd/spi-nor/gigadevice.c
+++ b/drivers/mtd/spi-nor/gigadevice.c
@@ -64,7 +64,6 @@ static const struct flash_info gigadevice_nor_parts[] = {
.id = SNOR_ID(0xc8, 0x40, 0x19),
.name = "gd25q256",
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6,
- .fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0xc8, 0x60, 0x16),
.name = "gd25lq32",
@@ -87,7 +86,8 @@ static const struct flash_info gigadevice_nor_parts[] = {
};
static const struct spi_nor_fixup gigadevice_fixups[] = {
- { .id = SNOR_ID(0xc8, 0x40, 0x19), .fixups = &gd25q256_fixups },
+ { .id = SNOR_ID(0xc8, 0x40, 0x19), .fixups = &gd25q256_fixups,
+ .fixup_flags = SPI_NOR_4B_OPCODES },
};
const struct spi_nor_manufacturer spi_nor_gigadevice = {
diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c
index 7af850eea9ff..2f057d731df2 100644
--- a/drivers/mtd/spi-nor/issi.c
+++ b/drivers/mtd/spi-nor/issi.c
@@ -101,7 +101,6 @@ static const struct flash_info issi_nor_parts[] = {
}, {
.id = SNOR_ID(0x9d, 0x60, 0x19),
.name = "is25lp256",
- .fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x9d, 0x70, 0x16),
.name = "is25wp032",
@@ -121,7 +120,6 @@ static const struct flash_info issi_nor_parts[] = {
.id = SNOR_ID(0x9d, 0x70, 0x19),
.name = "is25wp256",
.flags = SPI_NOR_QUAD_PP,
- .fixup_flags = SPI_NOR_4B_OPCODES,
}
};
@@ -146,8 +144,10 @@ static bool issi_pm25lv_match(const struct spi_nor *nor)
static const struct spi_nor_fixup issi_fixup_list[] = {
{ .fixups = &issi_fixups },
{ .match = issi_pm25lv_match, .fixups = &pm25lv_nor_fixups },
- { .id = SNOR_ID(0x9d, 0x60, 0x19), .fixups = &is25lp256_fixups },
- { .id = SNOR_ID(0x9d, 0x70, 0x19), .fixups = &is25lp256_fixups },
+ { .id = SNOR_ID(0x9d, 0x60, 0x19), .fixups = &is25lp256_fixups,
+ .fixup_flags = SPI_NOR_4B_OPCODES },
+ { .id = SNOR_ID(0x9d, 0x70, 0x19), .fixups = &is25lp256_fixups,
+ .fixup_flags = SPI_NOR_4B_OPCODES },
};
const struct spi_nor_manufacturer spi_nor_issi = {
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index 04b431bf5f13..94e553724fc9 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -140,7 +140,6 @@ static const struct flash_info macronix_nor_parts[] = {
}, {
/* MX66L51235F */
.id = SNOR_ID(0xc2, 0x20, 0x1a),
- .fixup_flags = SPI_NOR_4B_OPCODES,
}, {
/* MX66L1G45G */
.id = SNOR_ID(0xc2, 0x20, 0x1b),
@@ -328,7 +327,8 @@ static const struct spi_nor_fixups macronix_nor_fixups = {
static const struct spi_nor_fixup macronix_fixups[] = {
{ .fixups = ¯onix_nor_fixups },
{ .id = SNOR_ID(0xc2, 0x20, 0x19), .fixups = &mx25l25635_fixups },
- { .id = SNOR_ID(0xc2, 0x20, 0x1a), .fixups = ¯onix_qpp4b_fixups },
+ { .id = SNOR_ID(0xc2, 0x20, 0x1a), .fixups = ¯onix_qpp4b_fixups,
+ .fixup_flags = SPI_NOR_4B_OPCODES },
{ .id = SNOR_ID(0xc2, 0x20, 0x1b), .fixups = ¯onix_qpp4b_fixups },
{ .id = SNOR_ID(0xc2, 0x20, 0x1c), .fixups = ¯onix_qpp4b_fixups },
{ .id = SNOR_ID(0xc2, 0x25, 0x3a), .fixups = ¯onix_qpp4b_fixups },
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index 2aabd6d487ba..53ae9533f50f 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -205,12 +205,10 @@ static const struct flash_info micron_nor_parts[] = {
/* MT35XU512ABA */
.id = SNOR_ID(0x2c, 0x5b, 0x1a),
.mfr_flags = USE_FSR,
- .fixup_flags = SPI_NOR_IO_MODE_EN_VOLATILE,
}, {
/* MT35XU01GBBA */
.id = SNOR_ID(0x2c, 0x5b, 0x1b),
.mfr_flags = USE_FSR,
- .fixup_flags = SPI_NOR_IO_MODE_EN_VOLATILE,
}, {
.id = SNOR_ID(0x2c, 0x5b, 0x1c),
.name = "mt35xu02g",
@@ -218,7 +216,6 @@ static const struct flash_info micron_nor_parts[] = {
.size = SZ_256M,
.no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ,
.mfr_flags = USE_FSR,
- .fixup_flags = SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE,
},
};
@@ -403,7 +400,6 @@ static const struct flash_info st_nor_parts[] = {
.name = "mt25ql256a",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
- .fixup_flags = SPI_NOR_4B_OPCODES,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x19),
@@ -416,7 +412,6 @@ static const struct flash_info st_nor_parts[] = {
.name = "mt25ql512a",
.size = SZ_64M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
- .fixup_flags = SPI_NOR_4B_OPCODES,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xba, 0x20),
@@ -472,7 +467,6 @@ static const struct flash_info st_nor_parts[] = {
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
SPI_NOR_BP3_SR_BIT6,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
- .fixup_flags = SPI_NOR_4B_OPCODES,
.mfr_flags = USE_FSR,
}, {
.id = SNOR_ID(0x20, 0xbb, 0x19),
@@ -661,13 +655,22 @@ static const struct spi_nor_fixups micron_st_nor_fixups = {
static const struct spi_nor_fixup micron_fixups[] = {
{ .fixups = µn_st_nor_fixups },
- { .id = SNOR_ID(0x2c, 0x5b, 0x1a), .fixups = &mt35xu512aba_fixups },
- { .id = SNOR_ID(0x2c, 0x5b, 0x1b), .fixups = &mt35_two_die_fixups },
- { .id = SNOR_ID(0x2c, 0x5b, 0x1c), .fixups = &mt35_two_die_fixups },
+ { .id = SNOR_ID(0x2c, 0x5b, 0x1a), .fixups = &mt35xu512aba_fixups,
+ .fixup_flags = SPI_NOR_IO_MODE_EN_VOLATILE },
+ { .id = SNOR_ID(0x2c, 0x5b, 0x1b), .fixups = &mt35_two_die_fixups,
+ .fixup_flags = SPI_NOR_IO_MODE_EN_VOLATILE },
+ { .id = SNOR_ID(0x2c, 0x5b, 0x1c), .fixups = &mt35_two_die_fixups,
+ .fixup_flags = SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE },
};
static const struct spi_nor_fixup st_fixups[] = {
{ .fixups = µn_st_nor_fixups },
+ { .id = SNOR_ID(0x20, 0xba, 0x19, 0x10, 0x44, 0x00),
+ .fixup_flags = SPI_NOR_4B_OPCODES },
+ { .id = SNOR_ID(0x20, 0xba, 0x20, 0x10, 0x44, 0x00),
+ .fixup_flags = SPI_NOR_4B_OPCODES },
+ { .id = SNOR_ID(0x20, 0xbb, 0x19, 0x10, 0x44, 0x00),
+ .fixup_flags = SPI_NOR_4B_OPCODES },
{ .id = SNOR_ID(0x20, 0xba, 0x21), .fixups = &n25q00_fixups },
{ .id = SNOR_ID(0x20, 0xba, 0x22), .fixups = &mt25q02_fixups },
{ .id = SNOR_ID(0x20, 0xbb, 0x20, 0x10, 0x44, 0x00), .fixups = &mt25qu512a_fixups },
diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index 39cb8ac3a037..87b2d0a0e9f4 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -736,7 +736,7 @@ static void spi_nor_smpt_read_dummy_fixups(const struct spi_nor *nor,
fixups = nor->manufacturer->fixups;
for (i = 0; i < nor->manufacturer->nfixups; i++) {
- if (fixups[i].fixups->smpt_read_dummy &&
+ if (fixups[i].fixups && fixups[i].fixups->smpt_read_dummy &&
spi_nor_fixup_match(nor, &fixups[i]))
fixups[i].fixups->smpt_read_dummy(nor, read_dummy);
}
@@ -773,7 +773,7 @@ static void spi_nor_smpt_map_id_fixups(const struct spi_nor *nor, u8 *map_id)
fixups = nor->manufacturer->fixups;
for (i = 0; i < nor->manufacturer->nfixups; i++) {
- if (fixups[i].fixups->smpt_map_id &&
+ if (fixups[i].fixups && fixups[i].fixups->smpt_map_id &&
spi_nor_fixup_match(nor, &fixups[i]))
fixups[i].fixups->smpt_map_id(nor, map_id);
}
@@ -1430,7 +1430,7 @@ static int spi_nor_post_sfdp_fixups(struct spi_nor *nor)
fixups = nor->manufacturer->fixups;
for (i = 0; i < nor->manufacturer->nfixups; i++) {
- if (fixups[i].fixups->post_sfdp &&
+ if (fixups[i].fixups && fixups[i].fixups->post_sfdp &&
spi_nor_fixup_match(nor, &fixups[i])) {
ret = fixups[i].fixups->post_sfdp(nor);
if (ret)
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index f3862eb1a23a..5f4ce042ef2c 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -976,19 +976,16 @@ static const struct flash_info spansion_nor_parts[] = {
.name = "s25fl064l",
.size = SZ_8M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
- .fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x01, 0x60, 0x18),
.name = "s25fl128l",
.size = SZ_16M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
- .fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x01, 0x60, 0x19),
.name = "s25fl256l",
.size = SZ_32M,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
- .fixup_flags = SPI_NOR_4B_OPCODES,
}, {
.id = SNOR_ID(0x04, 0x2c, 0xc2, 0x7f, 0x7f, 0x7f),
.name = "cy15x104q",
@@ -1157,6 +1154,9 @@ static const struct spi_nor_fixup spansion_fixups[] = {
{ .fixups = &spansion_nor_fixups },
{ .id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x81), .fixups = &s25fs_s_nor_fixups },
{ .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x81), .fixups = &s25fs_s_nor_fixups },
+ { .id = SNOR_ID(0x01, 0x60, 0x17), .fixup_flags = SPI_NOR_4B_OPCODES },
+ { .id = SNOR_ID(0x01, 0x60, 0x18), .fixup_flags = SPI_NOR_4B_OPCODES },
+ { .id = SNOR_ID(0x01, 0x60, 0x19), .fixup_flags = SPI_NOR_4B_OPCODES },
{ .id = SNOR_ID(0x34, 0x2a, 0x1a, 0x0f, 0x03, 0x90), .fixups = &s25hx_t_fixups },
{ .id = SNOR_ID(0x34, 0x2a, 0x1b, 0x0f, 0x03, 0x90), .fixups = &s25hx_t_fixups },
{ .id = SNOR_ID(0x34, 0x2a, 0x1c, 0x0f, 0x00, 0x90), .fixups = &s25hx_t_fixups },
--
2.54.0
More information about the linux-arm-kernel
mailing list