mtd: spi-nor: Rework flash parameter initialization
Subsystems (2)
Michael Walle
maintainerv2 cover mtd: spi-nor: Rework flash parameter initialization
Try to simplify the flash initialization and get rid of the legacy handling. As default, all the flags of the in-kernel database are taken and amended with the SFDP data.
This might have the consequence that all the flashes now get a RDSFPD opcode which might be an unknown opcode. But that was already the case for any flashes which were unknown to the linux kernel. So far, there was not a single complaint. See patch 8 for more information.
Sashiko found that not everything is rolled back in case of a SFDP parsing failure. Thus there are now 5 additional patches which will move the discovered parameters into spi_nor_flash_parameter which is rolled back. The new rule is now:
SFDP parsing and the per-flash SFDP fixups must only change the spi_nor_flash_parameter data.
changes since v1:
- collected Tb and Rb tags
- Fixed the roll-back issue Sashiko found, we now keep two backups
for the parameters.
- Link to v1: https://lore.kernel.org/linux-mtd/[email protected]/
changes since the RFC:
- new patches to address the rollback issue, as pointed out by
Sashiko
- remove SKIP_SFDP from kerneldoc, as pointed out by Sashiko
- mention issuing the potential unsupported RDSFPD command in the
commit message, as pointed out by Tudor
- Link to the RFC: https://lore.kernel.org/linux-mtd/[email protected]/
Michael Walle (8):
mtd: spi-nor: spansion: s25fl256s0: remove SKIP_SFDP flag
mtd: spi-nor: don't clear the SNOR_F_4B_OPCODES flag on failure
mtd: spi-nor: move cmd_ext_type into spi_nor_flash_parameter
mtd: spi-nor: move flags into spi_nor_flash_parameter
mtd: spi-nor: move spi_nor_post_bfpt_fixups() into sfdp
mtd: spi-nor: spansion: s25fs256t: move ARCFN check into .late_init
mtd: spi-nor: push the rollback mechanism into the sfdp module
mtd: spi-nor: rework flash parameter initialization
drivers/mtd/spi-nor/core.c | 178 +++++++++++--------------------- drivers/mtd/spi-nor/core.h | 13 +-- drivers/mtd/spi-nor/debugfs.c | 6 +- drivers/mtd/spi-nor/macronix.c | 2 +- drivers/mtd/spi-nor/micron-st.c | 8 +- drivers/mtd/spi-nor/sfdp.c | 70 ++++++++++--- drivers/mtd/spi-nor/spansion.c | 36 ++++--- drivers/mtd/spi-nor/swp.c | 52 ++++++---- drivers/mtd/spi-nor/winbond.c | 4 +- include/linux/mtd/spi-nor.h | 4 - 10 files changed, 185 insertions(+), 188 deletions(-)
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 1/8 mtd: spi-nor: spansion: s25fl256s0: remove SKIP_SFDP flag
That flag was added in [1] to not "issue any non supported commands". But since we now have the generic SFDP driver, we'll issue the RDSFDP command on most flashes anyway and there was no single complaint. Remove the only user of this flag so we can rework the parameter initialization in the core.
[1] https://lore.kernel.org/linux-mtd/[email protected]/
--- drivers/mtd/spi-nor/spansion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi-nor/spansion.c +1 -1
@@ -868,7 +868,7 @@ static const struct flash_info spansion_nor_parts[] = { .name = "s25fl256s0", .size = SZ_32M, .sector_size = SZ_256K, - .no_sfdp_flags = SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, + .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, .mfr_flags = USE_CLSR, }, { .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x81),
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 2/8 mtd: spi-nor: don't clear the SNOR_F_4B_OPCODES flag on failure
In reply to Michael WalleThis was introduced in commit 548ed6847f530 ("mtd: spi-nor: Add the SNOR_F_4B_OPCODES flag"). It looks like it was the rollback mechanism if parsing the SFDP failed, but was setting that flag first. Nowadays, that flag can only be set if spi_nor_parse_4bait() was successful. IOW, the flags won't be left in an undefined state if parsing SFDP fails.
Remove the unneeded code to be able to rework spi_nor_init_params().
--- drivers/mtd/spi-nor/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/mtd/spi-nor/core.c +1 -3
@@ -3066,10 +3066,8 @@ static void spi_nor_sfdp_init_params_deprecated(struct spi_nor *nor)memcpy (&sfdp_params, nor->params,sizeof (sfdp_params)); -if (spi_nor_parse_sfdp (nor)) { +if (spi_nor_parse_sfdp (nor))memcpy (nor->params, &sfdp_params,sizeof (*nor->params)); - nor->flags &= ~SNOR_F_4B_OPCODES ; - } }/**
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 3/8 mtd: spi-nor: move cmd_ext_type into spi_nor_flash_parameter
In reply to Michael WalleRight now the SFDP parsing code is modifying both members of struct spi_nor_flash_parameter and struct spi_nor. This may lead to inconsistencies if the parsing fails because only the flash parameters are rolled back.
To fix this, move cmd_ext_type into the struct spi_nor_flash_parameter.
--- drivers/mtd/spi-nor/core.c | 2 +- drivers/mtd/spi-nor/core.h | 2 ++ drivers/mtd/spi-nor/debugfs.c | 2 +- drivers/mtd/spi-nor/micron-st.c | 2 +- drivers/mtd/spi-nor/sfdp.c | 4 ++-- include/linux/mtd/spi-nor.h | 2 -- 6 files changed, 7 insertions(+), 7 deletions(-)
drivers/mtd/spi-nor/core.c +1 -1
@@ -59,7 +59,7 @@static u8 spi_nor_get_cmd_ext (const struct spi_nor *nor,const struct spi_mem_op *op) { -switch (nor->cmd_ext_type) { +switch (nor->params->cmd_ext_type) {case SPI_NOR_EXT_INVERT :return ~op->cmd.opcode;
drivers/mtd/spi-nor/core.h +2 -0
@@ -370,6 +370,7 @@ struct spi_nor_otp {* in the array, the higher priority. * @page_programs: page program capabilities ordered by priority: the * higher index in the array, the higher priority. +* @cmd_ext_type: the command opcode extension type for DTR mode. * @erase_map: the erase map parsed from the SFDP Sector Map Parameter * Table. * @otp: SPI NOR OTP info.
@@ -399,6 +400,7 @@ struct spi_nor_flash_parameter {struct spi_nor_hwcaps hwcaps;struct spi_nor_read_command reads[SNOR_CMD_READ_MAX ];struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX ]; +enum spi_nor_cmd_ext cmd_ext_type;struct spi_nor_erase_map erase_map;struct spi_nor_otp otp;
drivers/mtd/spi-nor/debugfs.c +1 -1
@@ -109,7 +109,7 @@ static int spi_nor_params_show(struct seq_file *s, void *data)seq_printf (s," erase\t\t0x%02x\n" , nor->erase_opcode);seq_printf (s," program\t0x%02x\n" , nor->program_opcode); -switch (nor->cmd_ext_type) { +switch (params->cmd_ext_type) {case SPI_NOR_EXT_NONE : str ="none" ;break ;
drivers/mtd/spi-nor/micron-st.c +1 -1
@@ -177,7 +177,7 @@ static int mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor)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->cmd_ext_type =SPI_NOR_EXT_REPEAT ; nor->params->rdsr_dummy =8 ; nor->params->rdsr_addr_nbytes =0 ;
drivers/mtd/spi-nor/sfdp.c +2 -2
@@ -664,11 +664,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,/* 8D-8D-8D command extension. */ switch (bfpt.dwords[SFDP_DWORD (18 )] &BFPT_DWORD18_CMD_EXT_MASK ) {case BFPT_DWORD18_CMD_EXT_REP : - nor->cmd_ext_type =SPI_NOR_EXT_REPEAT ; + params->cmd_ext_type =SPI_NOR_EXT_REPEAT ;break ;case BFPT_DWORD18_CMD_EXT_INV : - nor->cmd_ext_type =SPI_NOR_EXT_INVERT ; + params->cmd_ext_type =SPI_NOR_EXT_INVERT ;break ;case BFPT_DWORD18_CMD_EXT_RES :
include/linux/mtd/spi-nor.h +0 -2
@@ -366,7 +366,6 @@ struct spi_nor_flash_parameter;* @program_opcode: the program opcode * @sst_write_second: used by the SST write operation * @flags: flag options for the current SPI NOR (SNOR_F_*) -* @cmd_ext_type: the command opcode extension type for DTR mode. * @read_proto: the SPI protocol for read operations * @write_proto: the SPI protocol for write operations * @reg_proto: the SPI protocol for read_reg/write_reg/erase operations
@@ -408,7 +407,6 @@ struct spi_nor {enum spi_nor_protocol reg_proto;bool sst_write_second;u32 flags; -enum spi_nor_cmd_ext cmd_ext_type;struct sfdp *sfdp;struct dentry *debugfs_root;u8 dfs_sr_cache[2 ];
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 4/8 mtd: spi-nor: move flags into spi_nor_flash_parameter
In reply to Michael WalleRight now the SFDP parsing code is modifying both members of struct spi_nor_flash_parameter and struct spi_nor. This may lead to inconsistencies if the parsing fails because only the flash parameters are rolled back.
To fix this, move the flags into the struct spi_nor_flash_parameter.
--- drivers/mtd/spi-nor/core.c | 83 ++++++++++++++++++--------------- drivers/mtd/spi-nor/core.h | 2 + drivers/mtd/spi-nor/debugfs.c | 4 +- drivers/mtd/spi-nor/macronix.c | 2 +- drivers/mtd/spi-nor/micron-st.c | 6 +-- drivers/mtd/spi-nor/sfdp.c | 16 +++---- drivers/mtd/spi-nor/spansion.c | 4 +- drivers/mtd/spi-nor/swp.c | 52 +++++++++++++-------- drivers/mtd/spi-nor/winbond.c | 4 +- include/linux/mtd/spi-nor.h | 2 - 10 files changed, 98 insertions(+), 77 deletions(-)
drivers/mtd/spi-nor/core.c +46 -37
@@ -83,6 +83,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor,struct spi_mem_op *op, const enum spi_nor_protocol proto) { + struct spi_nor_flash_parameter *params = nor->params;u8 ext; op->cmd.buswidth =spi_nor_get_protocol_inst_nbits (proto);
@@ -116,7 +117,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor, op->cmd.nbytes =2 ; } -if (proto ==SNOR_PROTO_8_8_8_DTR && nor->flags &SNOR_F_SWAP16 ) +if (proto ==SNOR_PROTO_8_8_8_DTR && params->flags &SNOR_F_SWAP16 ) op->data.swap16 = true; }
@@ -633,7 +634,7 @@ int spi_nor_sr_ready(struct spi_nor *nor)*/ static bool spi_nor_use_parallel_locking (struct spi_nor *nor) { -return nor->flags &SNOR_F_RWW ; +return nor->params->flags &SNOR_F_RWW ; }/* Locking helpers for status read operations */
@@ -860,12 +861,13 @@ static int spi_nor_write_sr1_and_check(struct spi_nor *nor, u8 sr1)*/ static int spi_nor_write_16bit_sr_and_check (struct spi_nor *nor,u8 sr1) { +struct spi_nor_flash_parameter *params = nor->params;int ret;u8 *sr_cr = nor->bouncebuf;u8 cr_written;/* Make sure we don't overwrite the contents of Status Register 2. */ -if (!(nor->flags &SNOR_F_NO_READ_CR )) { +if (!(params->flags &SNOR_F_NO_READ_CR )) { ret =spi_nor_read_cr (nor, &sr_cr[1 ]);if (ret)return ret;
@@ -906,7 +908,7 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1)return -EIO ; } -if (nor->flags &SNOR_F_NO_READ_CR ) +if (params->flags &SNOR_F_NO_READ_CR )return 0 ; cr_written = sr_cr[1 ];
@@ -961,7 +963,7 @@ int spi_nor_write_16bit_cr_and_check(struct spi_nor *nor, u8 cr)return -EIO ; } -if (nor->flags &SNOR_F_NO_READ_CR ) +if (nor->params->flags &SNOR_F_NO_READ_CR )return 0 ; ret =spi_nor_read_cr (nor, &sr_cr[1 ]);
@@ -1009,7 +1011,7 @@ static int spi_nor_write_16bit_sr_cr_and_check(struct spi_nor *nor, const u8 *rereturn -EIO ; } -if (nor->flags &SNOR_F_NO_READ_CR ) +if (nor->params->flags &SNOR_F_NO_READ_CR )return 0 ; ret =spi_nor_read_cr (nor, &nor->bouncebuf[1 ]);
@@ -1035,7 +1037,7 @@ static int spi_nor_write_16bit_sr_cr_and_check(struct spi_nor *nor, const u8 *re*/ int spi_nor_write_sr_and_check (struct spi_nor *nor,u8 sr1) { -if (nor->flags &SNOR_F_HAS_16BIT_SR ) +if (nor->params->flags &SNOR_F_HAS_16BIT_SR )return spi_nor_write_16bit_sr_and_check (nor, sr1);return spi_nor_write_sr1_and_check (nor, sr1);
@@ -1052,7 +1054,7 @@ int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1)*/ int spi_nor_write_sr_cr_and_check (struct spi_nor *nor,const u8 *regs) { -if (nor->flags &SNOR_F_HAS_16BIT_SR ) +if (nor->params->flags &SNOR_F_HAS_16BIT_SR )return spi_nor_write_16bit_sr_cr_and_check (nor, regs);return spi_nor_write_sr1_and_check (nor, regs[0 ]);
@@ -1821,6 +1823,7 @@ static int spi_nor_erase_dice(struct spi_nor *nor, loff_t addr,static int spi_nor_erase (struct mtd_info *mtd,struct erase_info *instr) {struct spi_nor *nor =mtd_to_spi_nor (mtd); +struct spi_nor_flash_parameter *params = nor->params;u8 n_dice = nor->params->n_dice;bool multi_die_erase = false;u32 addr, len, rem;
@@ -1852,7 +1855,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)return ret;/* chip (die) erase? */ -if ((len == mtd->size && !(nor->flags &SNOR_F_NO_OP_CHIP_ERASE )) || +if ((len == mtd->size && !(params->flags &SNOR_F_NO_OP_CHIP_ERASE )) || multi_die_erase) { ret =spi_nor_erase_dice (nor, addr, len, die_size);if (ret)
@@ -1942,7 +1945,7 @@ int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor) {int ret; -if (nor->flags &SNOR_F_NO_READ_CR ) +if (nor->params->flags &SNOR_F_NO_READ_CR )return spi_nor_write_16bit_cr_and_check (nor,SR2_QUAD_EN_BIT1 ); ret =spi_nor_read_cr (nor, nor->bouncebuf);
@@ -2502,7 +2505,7 @@ spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps)* If the reset line is broken, we do not want to enter a stateful * mode. */ -if (nor->flags &SNOR_F_BROKEN_RESET ) +if (params->flags &SNOR_F_BROKEN_RESET ) *hwcaps &= ~(SNOR_HWCAPS_X_X_X |SNOR_HWCAPS_X_X_X_DTR );for (cap =0 ; cap <sizeof (*hwcaps) *BITS_PER_BYTE ; cap++) {
@@ -2526,13 +2529,13 @@ spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps) }/* Some SPI controllers might not support CR read opcode. */ -if (!(nor->flags &SNOR_F_NO_READ_CR )) { +if (!(params->flags &SNOR_F_NO_READ_CR )) {struct spi_mem_op op =SPI_NOR_RDCR_OP (nor->bouncebuf);spi_nor_spimem_setup_op (nor, &op, nor->reg_proto);if (!spi_mem_supports_op (nor->spimem, &op)) - nor->flags |=SNOR_F_NO_READ_CR ; + params->flags |=SNOR_F_NO_READ_CR ; } }
@@ -2749,6 +2752,8 @@ static int spi_nor_select_erase(struct spi_nor *nor)static int spi_nor_set_addr_nbytes (struct spi_nor *nor) { +struct spi_nor_flash_parameter *params = nor->params; +if (nor->params->addr_nbytes) { nor->addr_nbytes = nor->params->addr_nbytes; }else if (nor->read_proto ==SNOR_PROTO_8_8_8_DTR ) {
@@ -2783,8 +2788,8 @@ static int spi_nor_set_addr_nbytes(struct spi_nor *nor) }/* Set 4byte opcodes when possible. */ -if (nor->addr_nbytes ==4 && nor->flags &SNOR_F_4B_OPCODES && - !(nor->flags &SNOR_F_HAS_4BAIT )) +if (nor->addr_nbytes ==4 && params->flags &SNOR_F_4B_OPCODES && + !(params->flags &SNOR_F_HAS_4BAIT ))spi_nor_set_4byte_opcodes (nor);return 0 ;
@@ -2947,39 +2952,40 @@ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)*/ static void spi_nor_init_flags (struct spi_nor *nor) { +struct spi_nor_flash_parameter *params = nor->params;struct device_node *np =spi_nor_get_flash_node (nor);const u16 flags = nor->info->flags;if (of_property_read_bool (np,"broken-flash-reset" )) - nor->flags |=SNOR_F_BROKEN_RESET ; + params->flags |=SNOR_F_BROKEN_RESET ;if (of_property_read_bool (np,"no-wp" )) - nor->flags |=SNOR_F_NO_WP ; + params->flags |=SNOR_F_NO_WP ;if (flags &SPI_NOR_SWP_IS_VOLATILE ) - nor->flags |=SNOR_F_SWP_IS_VOLATILE ; + params->flags |=SNOR_F_SWP_IS_VOLATILE ;if (flags &SPI_NOR_HAS_LOCK ) - nor->flags |=SNOR_F_HAS_LOCK ; + params->flags |=SNOR_F_HAS_LOCK ;if (flags &SPI_NOR_HAS_TB ) { - nor->flags |=SNOR_F_HAS_SR_TB ; + params->flags |=SNOR_F_HAS_SR_TB ;if (flags &SPI_NOR_TB_SR_BIT6 ) - nor->flags |=SNOR_F_HAS_SR_TB_BIT6 ; + params->flags |=SNOR_F_HAS_SR_TB_BIT6 ; }if (flags &SPI_NOR_4BIT_BP ) { - nor->flags |=SNOR_F_HAS_4BIT_BP ; + params->flags |=SNOR_F_HAS_4BIT_BP ;if (flags &SPI_NOR_BP3_SR_BIT6 ) - nor->flags |=SNOR_F_HAS_SR_BP3_BIT6 ; + params->flags |=SNOR_F_HAS_SR_BP3_BIT6 ; }if (flags &SPI_NOR_HAS_CMP ) - nor->flags |=SNOR_F_HAS_SR2_CMP_BIT6 ; + params->flags |=SNOR_F_HAS_SR2_CMP_BIT6 ;if (flags &SPI_NOR_RWW && nor->params->n_banks >1 && !nor->controller_ops) - nor->flags |=SNOR_F_RWW ; + params->flags |=SNOR_F_RWW ; }/**
@@ -2992,13 +2998,14 @@ static void spi_nor_init_flags(struct spi_nor *nor)*/ static void spi_nor_init_fixup_flags (struct spi_nor *nor) { +struct spi_nor_flash_parameter *params = nor->params;const u8 fixup_flags = nor->info->fixup_flags;if (fixup_flags &SPI_NOR_4B_OPCODES ) - nor->flags |=SNOR_F_4B_OPCODES ; + params->flags |=SNOR_F_4B_OPCODES ;if (fixup_flags &SPI_NOR_IO_MODE_EN_VOLATILE ) - nor->flags |=SNOR_F_IO_MODE_EN_VOLATILE ; + params->flags |=SNOR_F_IO_MODE_EN_VOLATILE ; }/**
@@ -3043,7 +3050,7 @@ static int spi_nor_late_init_params(struct spi_nor *nor)* NOR protection support. When locking_ops are not provided, we pick * the default ones. */ -if (nor->flags &SNOR_F_HAS_LOCK && !nor->params->locking_ops) +if (params->flags &SNOR_F_HAS_LOCK && !nor->params->locking_ops)spi_nor_init_default_locking_ops (nor);if (params->n_banks >1 )
@@ -3108,7 +3115,7 @@ static void spi_nor_init_default_params(struct spi_nor *nor) params->otp.org = info->otp;/* Default to 16-bit Write Status (01h) Command */ - nor->flags |=SNOR_F_HAS_16BIT_SR ; + params->flags |=SNOR_F_HAS_16BIT_SR ;/* Set SPI NOR sizes. */ params->writesize =1 ;
@@ -3229,7 +3236,7 @@ static int spi_nor_set_octal_dtr(struct spi_nor *nor, bool enable) nor->write_proto == SNOR_PROTO_8_8_8_DTR))return 0 ; -if (!(nor->flags &SNOR_F_IO_MODE_EN_VOLATILE )) +if (!(nor->params->flags &SNOR_F_IO_MODE_EN_VOLATILE ))return 0 ; ret = nor->params->set_octal_dtr (nor, enable);
@@ -3282,7 +3289,7 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)* reboots (e.g., crashes). Warn the user (or hopefully, system * designer) that this is bad. */ -WARN_ONCE (nor->flags &SNOR_F_BROKEN_RESET , +WARN_ONCE (nor->params->flags &SNOR_F_BROKEN_RESET ,"enabling reset hack; may not recover from unexpected reboots\n" ); }
@@ -3303,6 +3310,7 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)static int spi_nor_init (struct spi_nor *nor) { +struct spi_nor_flash_parameter *params = nor->params;int err; err =spi_nor_set_octal_dtr (nor, true);
@@ -3330,13 +3338,13 @@ static int spi_nor_init(struct spi_nor *nor)spi_nor_cache_sr_lock_bits (nor,NULL );if (IS_ENABLED (CONFIG_MTD_SPI_NOR_SWP_DISABLE ) || (IS_ENABLED (CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE ) && - nor->flags &SNOR_F_SWP_IS_VOLATILE )) { + params->flags &SNOR_F_SWP_IS_VOLATILE )) {spi_nor_try_unlock_all (nor); }if (nor->addr_nbytes ==4 && nor->read_proto !=SNOR_PROTO_8_8_8_DTR && - !(nor->flags &SNOR_F_4B_OPCODES )) + !(params->flags &SNOR_F_4B_OPCODES ))return spi_nor_set_4byte_addr_mode (nor, true);return 0 ;
@@ -3451,11 +3459,12 @@ static void spi_nor_put_device(struct mtd_info *mtd)static void spi_nor_restore (struct spi_nor *nor) { +struct spi_nor_flash_parameter *params = nor->params;int ret;/* restore the addressing mode */ -if (nor->addr_nbytes ==4 && !(nor->flags &SNOR_F_4B_OPCODES ) && - nor->flags &SNOR_F_BROKEN_RESET ) { +if (nor->addr_nbytes ==4 && !(params->flags &SNOR_F_4B_OPCODES ) && + params->flags &SNOR_F_BROKEN_RESET ) { ret =spi_nor_set_4byte_addr_mode (nor, false);if (ret)/*
@@ -3466,7 +3475,7 @@ static void spi_nor_restore(struct spi_nor *nor)dev_err (nor->dev,"Failed to exit 4-byte address mode, err = %d\n" , ret); } -if (nor->flags &SNOR_F_SOFT_RESET ) +if (params->flags &SNOR_F_SOFT_RESET )spi_nor_soft_reset (nor); }
@@ -3590,7 +3599,7 @@ static int spi_nor_set_mtd_info(struct spi_nor *nor) mtd->type =MTD_NORFLASH ; mtd->flags =MTD_CAP_NORFLASH ;/* Unset BIT_WRITEABLE to enable JFFS2 write buffer for ECC'd NOR */ -if (nor->flags &SNOR_F_ECC ) +if (nor->params->flags &SNOR_F_ECC ) mtd->flags &= ~MTD_BIT_WRITEABLE ;if (nor->info->flags &SPI_NOR_NO_ERASE ) mtd->flags |=MTD_NO_ERASE ;
drivers/mtd/spi-nor/core.h +2 -0
@@ -348,6 +348,7 @@ struct spi_nor_otp {* * @bank_size: the flash memory bank density in bytes. * @size: the total flash memory density in bytes. +* @flags: flag options for the current SPI NOR (SNOR_F_*) * @writesize Minimal writable flash unit size. Defaults to 1. Set to * ECC unit size for ECC-ed flashes. * @page_size: the page size of the SPI NOR flash memory.
@@ -386,6 +387,7 @@ struct spi_nor_otp {struct spi_nor_flash_parameter {u64 bank_size;u64 size; +u32 flags;u32 writesize;u32 page_size;u8 addr_nbytes;
drivers/mtd/spi-nor/debugfs.c +2 -2
@@ -99,7 +99,7 @@ static int spi_nor_params_show(struct seq_file *s, void *data)seq_printf (s,"address nbytes\t%u\n" , nor->addr_nbytes);seq_puts (s,"flags\t\t" ); -spi_nor_print_flags (s, nor->flags, snor_f_names, +spi_nor_print_flags (s, params->flags, snor_f_names,ARRAY_SIZE (snor_f_names));seq_puts (s,"\n" );
@@ -144,7 +144,7 @@ static int spi_nor_params_show(struct seq_file *s, void *data) } } -if (!(nor->flags &SNOR_F_NO_OP_CHIP_ERASE )) { +if (!(params->flags &SNOR_F_NO_OP_CHIP_ERASE )) {string_get_size (params->size,1 ,STRING_UNITS_2 , buf,sizeof (buf));seq_printf (s," %02x (%s)\n" , params->die_erase_opcode, buf); }
drivers/mtd/spi-nor/macronix.c +1 -1
@@ -40,7 +40,7 @@ mx25l25635_post_bfpt_fixups(struct spi_nor *nor,* its BFPT table. */ if (bfpt->dwords[SFDP_DWORD (5 )] &BFPT_DWORD5_FAST_READ_4_4_4 ) - nor->flags |=SNOR_F_4B_OPCODES ; + nor->params->flags |=SNOR_F_4B_OPCODES ;return 0 ; }
drivers/mtd/spi-nor/micron-st.c +3 -3
@@ -229,7 +229,7 @@ static int mt25qu512a_post_bfpt_fixup(struct spi_nor *nor,const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt) { - nor->flags &= ~SNOR_F_HAS_16BIT_SR; + nor->params->flags &= ~SNOR_F_HAS_16BIT_SR;return 0 ; }
@@ -632,8 +632,8 @@ static int micron_st_nor_ready(struct spi_nor *nor)static void micron_st_nor_default_init (struct spi_nor *nor) { - nor->flags |=SNOR_F_HAS_LOCK ; - nor->flags &= ~SNOR_F_HAS_16BIT_SR ; + nor->params->flags |=SNOR_F_HAS_LOCK ; + nor->params->flags &= ~SNOR_F_HAS_16BIT_SR ; nor->params->quad_enable =NULL ; }
drivers/mtd/spi-nor/sfdp.c +8 -8
@@ -586,17 +586,17 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,* Read Configuration Register (35h) instruction is not * supported. */ - nor->flags |=SNOR_F_HAS_16BIT_SR |SNOR_F_NO_READ_CR ; + params->flags |=SNOR_F_HAS_16BIT_SR |SNOR_F_NO_READ_CR ; params->quad_enable = spi_nor_sr2_bit1_quad_enable;break ;case BFPT_DWORD15_QER_SR1_BIT6 : - nor->flags &= ~SNOR_F_HAS_16BIT_SR ; + params->flags &= ~SNOR_F_HAS_16BIT_SR ; params->quad_enable = spi_nor_sr1_bit6_quad_enable;break ;case BFPT_DWORD15_QER_SR2_BIT7 : - nor->flags &= ~SNOR_F_HAS_16BIT_SR ; + params->flags &= ~SNOR_F_HAS_16BIT_SR ; params->quad_enable = spi_nor_sr2_bit7_quad_enable;break ;
@@ -607,7 +607,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,* Register 2, so let's be cautious and keep the default * assumption of a 16-bit Write Status (01h) command. */ - nor->flags |=SNOR_F_HAS_16BIT_SR ; + params->flags |=SNOR_F_HAS_16BIT_SR ; params->quad_enable = spi_nor_sr2_bit1_quad_enable;break ;
@@ -629,7 +629,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,/* Soft Reset support. */ if (bfpt.dwords[SFDP_DWORD (16 )] &BFPT_DWORD16_SWRST_EN_RST ) - nor->flags |=SNOR_F_SOFT_RESET ; + params->flags |=SNOR_F_SOFT_RESET ;/* Stop here if not JESD216 rev C or later. */ if (bfpt_header->length ==BFPT_DWORD_MAX_JESD216B )
@@ -682,7 +682,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,/* Byte order in 8D-8D-8D mode */ if (bfpt.dwords[SFDP_DWORD (18 )] &BFPT_DWORD18_BYTE_ORDER_SWAPPED ) - nor->flags |=SNOR_F_SWAP16 ; + params->flags |=SNOR_F_SWAP16 ;return spi_nor_post_bfpt_fixups (nor, bfpt_header, &bfpt); }
@@ -1169,7 +1169,7 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,* SFDP compliant memories. */ params->addr_nbytes =4 ; - nor->flags |=SNOR_F_4B_OPCODES |SNOR_F_HAS_4BAIT ; + params->flags |=SNOR_F_4B_OPCODES |SNOR_F_HAS_4BAIT ;/* fall through */ out:
@@ -1315,7 +1315,7 @@ static int spi_nor_parse_sccr(struct spi_nor *nor,if (FIELD_GET (SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE , dwords[SFDP_DWORD (22 )])) - nor->flags |=SNOR_F_IO_MODE_EN_VOLATILE ; + params->flags |=SNOR_F_IO_MODE_EN_VOLATILE ; out:kfree (dwords);
drivers/mtd/spi-nor/spansion.c +2 -2
@@ -537,7 +537,7 @@ static void cypress_nor_ecc_init(struct spi_nor *nor)* same ECC data unit without an erase are not allowed. */ nor->params->writesize =16 ; - nor->flags |=SNOR_F_ECC ; + nor->params->flags |=SNOR_F_ECC ; } static int
@@ -1139,7 +1139,7 @@ static int spansion_nor_late_init(struct spi_nor *nor)u8 mfr_flags = nor->info->mfr_flags;if (params->size >SZ_16M ) { - nor->flags |=SNOR_F_4B_OPCODES ; + params->flags |=SNOR_F_4B_OPCODES ;/* No small sector erase for 4-byte command set */ nor->erase_opcode =SPINOR_OP_SE ; nor->mtd.erasesize = nor->info->sector_size ?:
drivers/mtd/spi-nor/swp.c +32 -20
189 lines not on this page · raw message
drivers/mtd/spi-nor/winbond.c +2 -2
@@ -64,7 +64,7 @@ w25q256_post_bfpt_fixups(struct spi_nor *nor,*/ if (bfpt_header->major ==SFDP_JESD216_MAJOR && bfpt_header->minor ==SFDP_JESD216A_MINOR ) - nor->flags |=SNOR_F_4B_OPCODES ; + nor->params->flags |=SNOR_F_4B_OPCODES ;return 0 ; }
@@ -84,7 +84,7 @@ winbond_rdcr_post_bfpt_fixup(struct spi_nor *nor,* both incorrect and impractical, as the chip features a CMP bit for its * locking scheme that lays in the Control Register, and needs to be read. */ - nor->flags &= ~SNOR_F_NO_READ_CR ; + nor->params->flags &= ~SNOR_F_NO_READ_CR ;return 0 ; }
include/linux/mtd/spi-nor.h +0 -2
@@ -365,7 +365,6 @@ struct spi_nor_flash_parameter;* @read_dummy: the dummy needed by the read operation * @program_opcode: the program opcode * @sst_write_second: used by the SST write operation -* @flags: flag options for the current SPI NOR (SNOR_F_*) * @read_proto: the SPI protocol for read operations * @write_proto: the SPI protocol for write operations * @reg_proto: the SPI protocol for read_reg/write_reg/erase operations
@@ -406,7 +405,6 @@ struct spi_nor {enum spi_nor_protocol write_proto;enum spi_nor_protocol reg_proto;bool sst_write_second; -u32 flags;struct sfdp *sfdp;struct dentry *debugfs_root;u8 dfs_sr_cache[2 ];
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 5/8 mtd: spi-nor: move spi_nor_post_bfpt_fixups() into sfdp
In reply to Michael WalleMove spi_nor_post_bfpt_fixups() into the sfdp module because it's really only needed there. While at it, add some documentation.
--- drivers/mtd/spi-nor/core.c | 20 -------------------- drivers/mtd/spi-nor/core.h | 4 ---- drivers/mtd/spi-nor/sfdp.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 24 deletions(-)
drivers/mtd/spi-nor/core.c +0 -20
@@ -2581,26 +2581,6 @@ void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map, map->n_regions =1 ; } -int spi_nor_post_bfpt_fixups (struct spi_nor *nor, -const struct sfdp_parameter_header *bfpt_header, -const struct sfdp_bfpt *bfpt) -{ -int ret; - -if (nor->manufacturer && nor->manufacturer->fixups && - nor->manufacturer->fixups->post_bfpt) { - ret = nor->manufacturer->fixups->post_bfpt (nor, bfpt_header, - bfpt); -if (ret) -return ret; - } - -if (nor->info->fixups && nor->info->fixups->post_bfpt) -return nor->info->fixups->post_bfpt (nor, bfpt_header, bfpt); - -return 0 ; -} -static int spi_nor_select_read (struct spi_nor *nor,u32 shared_hwcaps) {
drivers/mtd/spi-nor/core.h +0 -4
@@ -687,10 +687,6 @@ void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase);void spi_nor_init_uniform_erase_map (struct spi_nor_erase_map *map,u8 erase_mask,u64 flash_size); -int spi_nor_post_bfpt_fixups (struct spi_nor *nor, -const struct sfdp_parameter_header *bfpt_header, -const struct sfdp_bfpt *bfpt); -void spi_nor_init_default_locking_ops (struct spi_nor *nor);bool spi_nor_has_default_locking_ops (struct spi_nor *nor);void spi_nor_try_unlock_all (struct spi_nor *nor);
drivers/mtd/spi-nor/sfdp.c +31 -0
@@ -401,6 +401,37 @@ static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map) } } +/** +* spi_nor_post_bfpt_fixups() - Updates the flash's parameters and settings +* after BFPT has been parsed. Called only for flashes that define JESD216 SFDP +* tables. +* @nor: pointer to a 'struct spi_nor' +* @bfpt_header: pointer to the 'struct sfdp_parameter_header' describing +* the Basic Flash Parameter Table length and version +* +* Used to tweak various flash parameters when information provided by the SFDP +* tables are wrong. +*/ +static int spi_nor_post_bfpt_fixups (struct spi_nor *nor, +const struct sfdp_parameter_header *bfpt_header, +const struct sfdp_bfpt *bfpt) +{ +int ret; + +if (nor->manufacturer && nor->manufacturer->fixups && + nor->manufacturer->fixups->post_bfpt) { + ret = nor->manufacturer->fixups->post_bfpt (nor, bfpt_header, + bfpt); +if (ret) +return ret; + } + +if (nor->info->fixups && nor->info->fixups->post_bfpt) +return nor->info->fixups->post_bfpt (nor, bfpt_header, bfpt); + +return 0 ; +} +/** * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. * @nor: pointer to a 'struct spi_nor'
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 6/8 mtd: spi-nor: spansion: s25fs256t: move ARCFN check into .late_init
In reply to Michael WalleThe SFPD parsing is optional. It not meant to fail if something is wrong with the chip (except for the SFDP itself). Thus it doesn't make any sense to return -ENODEV.
Move that check to late_init(), which might fail and abort the flash probing.
--- drivers/mtd/spi-nor/spansion.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
drivers/mtd/spi-nor/spansion.c +16 -14
@@ -545,7 +545,6 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor,const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt) { - struct spi_mem_op op; int ret;/* Assign 4-byte address mode method that is not determined in BFPT */
@@ -555,19 +554,6 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor,if (ret)return ret; -/* Read Architecture Configuration Register (ARCFN) */ - op = (struct spi_mem_op ) -CYPRESS_NOR_RD_ANY_REG_OP (nor->params->addr_mode_nbytes, -SPINOR_REG_CYPRESS_ARCFN ,1 , - nor->bouncebuf); - ret =spi_nor_read_any_reg (nor, &op, nor->reg_proto); -if (ret) -return ret; - -/* ARCFN value must be 0 if uniform sector is selected */ -if (nor->bouncebuf[0 ]) -return -ENODEV ; -return 0 ; }
@@ -598,6 +584,22 @@ static int s25fs256t_post_sfdp_fixup(struct spi_nor *nor)static int s25fs256t_late_init (struct spi_nor *nor) { +struct spi_mem_op op; +int ret; + +/* Read Architecture Configuration Register (ARCFN) */ + op = (struct spi_mem_op ) +CYPRESS_NOR_RD_ANY_REG_OP (nor->params->addr_mode_nbytes, +SPINOR_REG_CYPRESS_ARCFN ,1 , + nor->bouncebuf); + ret =spi_nor_read_any_reg (nor, &op, nor->reg_proto); +if (ret) +return ret; + +/* ARCFN value must be 0 if uniform sector is selected */ +if (nor->bouncebuf[0 ]) +return -ENODEV ; +cypress_nor_ecc_init (nor);return 0 ;
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 7/8 mtd: spi-nor: push the rollback mechanism into the sfdp module
In reply to Michael WalleRight now, the core is handling the rollback of the parameters. But it doesn't have the knowledge what has to be rolled back. And in fact, havent rolled back everything. Push it down to the called function and make it mandatory, that this function has no side effects if it fails.
Funny enough, there is a comment in the SFDP table handling code that each table parser is responsible to roll back any changes. But none of them did. So while add it, expand the logic to that and roll it back for them. There is one simple rule though:
SFDP parsing and fixups may only modify the spi_nor_flash_parameters.
--- drivers/mtd/spi-nor/core.c | 20 +------------------- drivers/mtd/spi-nor/sfdp.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 21 deletions(-)
drivers/mtd/spi-nor/core.c +1 -19
@@ -3039,24 +3039,6 @@ static int spi_nor_late_init_params(struct spi_nor *nor)return 0 ; } -/** -* spi_nor_sfdp_init_params_deprecated() - Deprecated way of initializing flash -* parameters and settings based on JESD216 SFDP standard. -* @nor: pointer to a 'struct spi_nor'. -* -* The method has a roll-back mechanism: in case the SFDP parsing fails, the -* legacy flash parameters and settings will be restored. -*/ -static void spi_nor_sfdp_init_params_deprecated (struct spi_nor *nor) -{ -struct spi_nor_flash_parameter sfdp_params; - -memcpy (&sfdp_params, nor->params,sizeof (sfdp_params)); - -if (spi_nor_parse_sfdp (nor)) -memcpy (nor->params, &sfdp_params,sizeof (*nor->params)); -} -/** * spi_nor_init_params_deprecated() - Deprecated way of initializing flash * parameters and settings.
@@ -3076,7 +3058,7 @@ static void spi_nor_init_params_deprecated(struct spi_nor *nor) SPI_NOR_QUAD_READ | SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) -spi_nor_sfdp_init_params_deprecated (nor); +spi_nor_parse_sfdp (nor); }/**
drivers/mtd/spi-nor/sfdp.c +17 -2
@@ -1473,12 +1473,16 @@ int spi_nor_check_sfdp_signature(struct spi_nor *nor)* runtime the main parameters needed to perform basic SPI flash operations such * as Fast Read, Page Program or Sector Erase commands. * +* Because the parsing is optional, all the settings have to be reverted. IOW, +* nothing of struct spi_nor shall be changed. +* * Return: 0 on success, -errno otherwise. */ int spi_nor_parse_sfdp (struct spi_nor *nor) {const struct sfdp_parameter_header *param_header, *bfpt_header;struct sfdp_parameter_header *param_headers =NULL ; +struct spi_nor_flash_parameter params, params2;struct sfdp_header header;struct device *dev = nor->dev;struct sfdp *sfdp;
@@ -1486,6 +1490,12 @@ int spi_nor_parse_sfdp(struct spi_nor *nor)size_t psize;int i, err; +/* +* Get a backup of all the parameter to roll back to in case of an +* error. +*/ +memcpy (¶ms, nor->params,sizeof (params)); +/* Get the SFDP header. */ err =spi_nor_read_sfdp_dma_unsafe (nor,0 ,sizeof (header), &header);if (err <0 )
@@ -1607,6 +1617,7 @@ int spi_nor_parse_sfdp(struct spi_nor *nor)/* Parse optional parameter tables. */ for (i =0 ; i < header.nph; i++) { +memcpy (¶ms2, nor->params,sizeof (params2)); param_header = ¶m_headers[i];switch (SFDP_PARAM_HEADER_ID (param_header)) {
@@ -1640,15 +1651,19 @@ int spi_nor_parse_sfdp(struct spi_nor *nor)/* * Let's not drop all information we extracted so far * if optional table parsers fail. In case of failing, -* each optional parser is responsible to roll back to -* the previously known spi_nor data. +* roll back to the previously known +* spi_nor_flash_parameter data. */ err =0 ; +memcpy (nor->params, ¶ms2,sizeof (*nor->params)); } } err =spi_nor_post_sfdp_fixups (nor); exit:kfree (param_headers); +if (err) +memcpy (nor->params, ¶ms,sizeof (*nor->params)); +return err; }
Signature · 1 line
2.47.3
Michael Walle
maintainerPATCH v2 8/8 mtd: spi-nor: rework flash parameter initialization
In reply to Michael WalleRework how the flash parameters are initialized. It used to make a difference whether a flash is in the in-kernel database, whether it supports multi I/O and so on. Recently, that makes more and more problems because flash IDs are reused among legacy flashes (w/o SFDP support) and newer flashes [1,2,3,4].
Simplify the whole parameter initialization, by starting with the parameters we have in the in-kernel database and the try to parse SFDP (and let it override any settings).
This has the consequence that all the flashes now get a RDSFPD opcode which might be an unknown opcode from the perspective of the flash. With the generic SPI NOR flash driver, this was already the case for any flashes not listed in the in-kernel database. So far, there was not a single complaint.
[1] https://lore.kernel.org/linux-mtd/CAAyq3SYX9UPwhC_Ume_S2yxhQwimRvB=Y6O_+FFqokhNmw7jQg@mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/[email protected]/
[3] https://lore.kernel.org/linux-mtd/[email protected]/
[4] https://lore.kernel.org/linux-mtd/[email protected]/
--- drivers/mtd/spi-nor/core.c | 53 ++++++++++---------------------------- drivers/mtd/spi-nor/core.h | 5 +--- 2 files changed, 15 insertions(+), 43 deletions(-)
drivers/mtd/spi-nor/core.c +14 -39
@@ -2853,11 +2853,10 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)/** * spi_nor_no_sfdp_init_params() - Initialize the flash's parameters and -* settings based on nor->info->sfdp_flags. This method should be called only by -* flashes that do not define SFDP tables. If the flash supports SFDP but the -* information is wrong and the settings from this function can not be retrieved -* by parsing SFDP, one should instead use the fixup hooks and update the wrong -* bits. +* settings based on nor->info->sfdp_flags. +* If the flash supports SFDP but the information is wrong and the settings from +* this function can not be retrieved by parsing SFDP, one should instead use +* the fixup hooks and update the wrong bits. * @nor: pointer to a 'struct spi_nor'. */ static void spi_nor_no_sfdp_init_params (struct spi_nor *nor)
@@ -3039,28 +3038,6 @@ static int spi_nor_late_init_params(struct spi_nor *nor)return 0 ; } -/** -* spi_nor_init_params_deprecated() - Deprecated way of initializing flash -* parameters and settings. -* @nor: pointer to a 'struct spi_nor'. -* -* The method assumes that flash doesn't support SFDP so it initializes flash -* parameters in spi_nor_no_sfdp_init_params() which later on can be overwritten -* when parsing SFDP, if supported. -*/ -static void spi_nor_init_params_deprecated (struct spi_nor *nor) -{ -spi_nor_no_sfdp_init_params (nor); - -spi_nor_manufacturer_init_params (nor); - -if (nor->info->no_sfdp_flags & (SPI_NOR_DUAL_READ | -SPI_NOR_QUAD_READ | -SPI_NOR_OCTAL_READ | -SPI_NOR_OCTAL_DTR_READ )) -spi_nor_parse_sfdp (nor); -} -/** * spi_nor_init_default_params() - Default initialization of flash parameters * and settings. Done for all flashes, regardless is they define SFDP tables
@@ -3121,7 +3098,8 @@ static void spi_nor_init_default_params(struct spi_nor *nor)* * 1/ Default flash parameters initialization. The initializations are done * based on nor->info data: -* spi_nor_info_init_params() +* spi_nor_init_default_params() +* spi_nor_no_sfdp_init_params() * * which can be overwritten by: * 2/ Manufacturer flash parameters initialization. The initializations are
@@ -3132,7 +3110,7 @@ static void spi_nor_init_default_params(struct spi_nor *nor)* which can be overwritten by: * 3/ SFDP flash parameters initialization. JESD216 SFDP is a standard and * should be more accurate that the above. -* spi_nor_parse_sfdp() or spi_nor_no_sfdp_init_params() +* spi_nor_parse_sfdp() * * Please note that there is a ->post_bfpt() fixup hook that can overwrite * the flash parameters and settings immediately after parsing the Basic
@@ -3158,17 +3136,14 @@ static int spi_nor_init_params(struct spi_nor *nor)return -ENOMEM ;spi_nor_init_default_params (nor); +spi_nor_no_sfdp_init_params (nor); +spi_nor_manufacturer_init_params (nor); -if (spi_nor_needs_sfdp (nor)) { - ret =spi_nor_parse_sfdp (nor); -if (ret) { -dev_err (nor->dev,"BFPT parsing failed. Please consider using SPI_NOR_SKIP_SFDP when declaring the flash\n" ); -return ret; - } - }else if (nor->info->no_sfdp_flags &SPI_NOR_SKIP_SFDP ) { -spi_nor_no_sfdp_init_params (nor); - }else { -spi_nor_init_params_deprecated (nor); + ret =spi_nor_parse_sfdp (nor); +if (ret &&spi_nor_needs_sfdp (nor)) { +dev_err (nor->dev, +"SFDP parsing failed. You need to manually declare the flash parameters.\n" ); +return ret; } ret =spi_nor_late_init_params (nor);
drivers/mtd/spi-nor/core.h +1 -4
@@ -502,9 +502,7 @@ struct spi_nor_id {* be used with SPI_NOR_HAS_LOCK. * * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP. -* Used when SFDP tables are not defined in the flash. These -* flags are used together with the SPI_NOR_SKIP_SFDP flag. -* SPI_NOR_SKIP_SFDP: skip parsing of SFDP tables. +* Used when SFDP tables are not defined in the flash. * SECT_4K: SPINOR_OP_BE_4K works uniformly. * SPI_NOR_DUAL_READ: flash supports Dual Read. * SPI_NOR_QUAD_READ: flash supports Quad Read.
@@ -552,7 +550,6 @@ struct flash_info {#define SPI_NOR_HAS_CMP BIT(10)u8 no_sfdp_flags; -#define SPI_NOR_SKIP_SFDP BIT(0)#define SECT_4K BIT(1)#define SPI_NOR_DUAL_READ BIT(3)#define SPI_NOR_QUAD_READ BIT(4)
Signature · 1 line
2.47.3
Quoted 11 lines · Michael Walle
Try to simplify the flash initialization and get rid of the legacy handling. As default, all the flags of the in-kernel database are taken and amended with the SFDP data.
This might have the consequence that all the flashes now get a RDSFPD opcode which might be an unknown opcode. But that was already the case for any flashes which were unknown to the linux kernel. So far, there was not a single complaint. See patch 8 for more information.
[...]
Applied, thanks!
[1/8] mtd: spi-nor: spansion: s25fl256s0: remove SKIP_SFDP flag
commit: 0132eaac40518f6ebb42131e5005efc375473e8e
[2/8] mtd: spi-nor: don't clear the SNOR_F_4B_OPCODES flag on failure
commit: a4cd8da7f2bda7562a7e156ee9c9e9b3ba98208e
[3/8] mtd: spi-nor: move cmd_ext_type into spi_nor_flash_parameter
commit: e37ee8734881a7f92dbbeecf8cc129dd8a6a76b8
[4/8] mtd: spi-nor: move flags into spi_nor_flash_parameter
commit: 0ede46b4f5b38cb43225927abbf088dd568db54e
[5/8] mtd: spi-nor: move spi_nor_post_bfpt_fixups() into sfdp
commit: 69d9d7dabbebd91cd8aba4e23caabe9b34d2722c
[6/8] mtd: spi-nor: spansion: s25fs256t: move ARCFN check into .late_init
commit: d395d4b8e76b1dfdb2f46b29c62e7f1f4850c9b2
[7/8] mtd: spi-nor: push the rollback mechanism into the sfdp module
commit: d20029474a76a06a2a92427453c2326cc3e98dfa
[8/8] mtd: spi-nor: rework flash parameter initialization
commit: 90a8ed3c63b905dcd375585da6f4851d88cc343dBest regards,
Signature · 1 line
Michael Walle <[email protected]>