Message ID | 20200226125606.22684-10-p.yadav@ti.com |
---|---|
State | Superseded |
Headers | show |
Series | mtd: spi-nor-core: add xSPI Octal DTR support | expand |
On 26/02/20 6:25 pm, Pratyush Yadav wrote: > diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c > index 1ed4f0907b..94e99eb99f 100644 > --- a/drivers/mtd/spi/spi-nor-core.c > +++ b/drivers/mtd/spi/spi-nor-core.c > @@ -148,6 +148,32 @@ struct sfdp_header { > struct sfdp_bfpt { > u32 dwords[BFPT_DWORD_MAX]; > }; > + > +/** > + * struct spi_nor_fixups - SPI NOR fixup hooks > + * @default_init: called after default flash parameters init. Used to tweak > + * flash parameters when information provided by the flash_info > + * table is incomplete or wrong. > + * @post_bfpt: called after the BFPT table has been parsed > + * @post_sfdp: called after SFDP has been parsed (is also 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 > + * incomplete or wrong). > + * > + * Those hooks can be used to tweak the SPI NOR configuration when the SFDP > + * table is broken or not available. > + */ > +struct spi_nor_fixups { > + void (*default_init)(struct spi_nor *nor); > + int (*post_bfpt)(struct spi_nor *nor, > + const struct sfdp_parameter_header *bfpt_header, > + const struct sfdp_bfpt *bfpt, > + struct spi_nor_flash_parameter *params); > + void (*post_sfdp)(struct spi_nor *nor, > + struct spi_nor_flash_parameter *params); > +}; > + > #endif /* SPI_FLASH_SFDP_SUPPORT */ > > static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op > @@ -1743,6 +1769,19 @@ static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] = { > > static int spi_nor_hwcaps_read2cmd(u32 hwcaps); > > +static int > +spi_nor_post_bfpt_fixups(struct spi_nor *nor, > + const struct sfdp_parameter_header *bfpt_header, > + const struct sfdp_bfpt *bfpt, > + struct spi_nor_flash_parameter *params) > +{ > + if (nor->info->fixups && nor->info->fixups->post_bfpt) > + return nor->info->fixups->post_bfpt(nor, bfpt_header, bfpt, > + params); > + > + return 0; > +} > + > /** > * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. > * @nor: pointer to a 'struct spi_nor' > @@ -1914,7 +1953,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, > return -EINVAL; > } > > - return 0; > + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); > } > > /** > @@ -2074,6 +2113,29 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, > } > #endif /* SPI_FLASH_SFDP_SUPPORT */ > > +/** > + * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings > + * after SFDP has been parsed (is also called for SPI NORs that do not > + * support RDSFDP). > + * @nor: pointer to a 'struct spi_nor' > + * > + * 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 incomplete or wrong). > + */ > +static void spi_nor_post_sfdp_fixups(struct spi_nor *nor, > + struct spi_nor_flash_parameter *params) > +{ > + if (nor->info->fixups && nor->info->fixups->post_sfdp) > + nor->info->fixups->post_sfdp(nor, params); > +} > + This would cause build failure as spi_nor_fixups is only available when SFDP support is enabled: drivers/mtd/spi/spi-nor-core.c: In function ?spi_nor_post_sfdp_fixups?: drivers/mtd/spi/spi-nor-core.c:2280:44: error: dereferencing pointer to incomplete type ?const struct spi_nor_fixups? 2280 | if (nor->info->fixups && nor->info->fixups->post_sfdp) May be move all definitions of out the #ifdef Regards Vignesh
On 12/03/20 12:04PM, Vignesh Raghavendra wrote: > > > On 26/02/20 6:25 pm, Pratyush Yadav wrote: > > diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c > > index 1ed4f0907b..94e99eb99f 100644 > > --- a/drivers/mtd/spi/spi-nor-core.c > > +++ b/drivers/mtd/spi/spi-nor-core.c > > @@ -148,6 +148,32 @@ struct sfdp_header { > > struct sfdp_bfpt { > > u32 dwords[BFPT_DWORD_MAX]; > > }; > > + > > +/** > > + * struct spi_nor_fixups - SPI NOR fixup hooks > > + * @default_init: called after default flash parameters init. Used to tweak > > + * flash parameters when information provided by the flash_info > > + * table is incomplete or wrong. > > + * @post_bfpt: called after the BFPT table has been parsed > > + * @post_sfdp: called after SFDP has been parsed (is also 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 > > + * incomplete or wrong). > > + * > > + * Those hooks can be used to tweak the SPI NOR configuration when the SFDP > > + * table is broken or not available. > > + */ > > +struct spi_nor_fixups { > > + void (*default_init)(struct spi_nor *nor); > > + int (*post_bfpt)(struct spi_nor *nor, > > + const struct sfdp_parameter_header *bfpt_header, > > + const struct sfdp_bfpt *bfpt, > > + struct spi_nor_flash_parameter *params); > > + void (*post_sfdp)(struct spi_nor *nor, > > + struct spi_nor_flash_parameter *params); > > +}; > > + > > #endif /* SPI_FLASH_SFDP_SUPPORT */ > > > > static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op > > @@ -1743,6 +1769,19 @@ static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] = { > > > > static int spi_nor_hwcaps_read2cmd(u32 hwcaps); > > > > +static int > > +spi_nor_post_bfpt_fixups(struct spi_nor *nor, > > + const struct sfdp_parameter_header *bfpt_header, > > + const struct sfdp_bfpt *bfpt, > > + struct spi_nor_flash_parameter *params) > > +{ > > + if (nor->info->fixups && nor->info->fixups->post_bfpt) > > + return nor->info->fixups->post_bfpt(nor, bfpt_header, bfpt, > > + params); > > + > > + return 0; > > +} > > + > > /** > > * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. > > * @nor: pointer to a 'struct spi_nor' > > @@ -1914,7 +1953,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, > > return -EINVAL; > > } > > > > - return 0; > > + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); > > } > > > > /** > > @@ -2074,6 +2113,29 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, > > } > > #endif /* SPI_FLASH_SFDP_SUPPORT */ > > > > +/** > > + * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings > > + * after SFDP has been parsed (is also called for SPI NORs that do not > > + * support RDSFDP). > > + * @nor: pointer to a 'struct spi_nor' > > + * > > + * 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 incomplete or wrong). > > + */ > > +static void spi_nor_post_sfdp_fixups(struct spi_nor *nor, > > + struct spi_nor_flash_parameter *params) > > +{ > > + if (nor->info->fixups && nor->info->fixups->post_sfdp) > > + nor->info->fixups->post_sfdp(nor, params); > > +} > > + > > This would cause build failure as spi_nor_fixups is only available when > SFDP support is enabled: > > drivers/mtd/spi/spi-nor-core.c: In function ?spi_nor_post_sfdp_fixups?: > drivers/mtd/spi/spi-nor-core.c:2280:44: error: dereferencing pointer to incomplete type ?const struct spi_nor_fixups? > 2280 | if (nor->info->fixups && nor->info->fixups->post_sfdp) > > May be move all definitions of out the #ifdef Thanks for catching this. Will fix.
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 940b2e4c9e..d689b673ce 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -67,6 +67,9 @@ struct flash_info { #define USE_CLSR BIT(14) /* use CLSR command */ #define SPI_NOR_HAS_SST26LOCK BIT(15) /* Flash supports lock/unlock via BPR */ #define SPI_NOR_OCTAL_READ BIT(16) /* Flash supports Octal Read */ + + /* Part specific fixup hooks. */ + const struct spi_nor_fixups *fixups; }; extern const struct flash_info spi_nor_ids[]; diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 1ed4f0907b..94e99eb99f 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -148,6 +148,32 @@ struct sfdp_header { struct sfdp_bfpt { u32 dwords[BFPT_DWORD_MAX]; }; + +/** + * struct spi_nor_fixups - SPI NOR fixup hooks + * @default_init: called after default flash parameters init. Used to tweak + * flash parameters when information provided by the flash_info + * table is incomplete or wrong. + * @post_bfpt: called after the BFPT table has been parsed + * @post_sfdp: called after SFDP has been parsed (is also 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 + * incomplete or wrong). + * + * Those hooks can be used to tweak the SPI NOR configuration when the SFDP + * table is broken or not available. + */ +struct spi_nor_fixups { + void (*default_init)(struct spi_nor *nor); + int (*post_bfpt)(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params); + void (*post_sfdp)(struct spi_nor *nor, + struct spi_nor_flash_parameter *params); +}; + #endif /* SPI_FLASH_SFDP_SUPPORT */ static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op @@ -1743,6 +1769,19 @@ static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] = { static int spi_nor_hwcaps_read2cmd(u32 hwcaps); +static int +spi_nor_post_bfpt_fixups(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) +{ + if (nor->info->fixups && nor->info->fixups->post_bfpt) + return nor->info->fixups->post_bfpt(nor, bfpt_header, bfpt, + params); + + return 0; +} + /** * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. * @nor: pointer to a 'struct spi_nor' @@ -1914,7 +1953,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, return -EINVAL; } - return 0; + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); } /** @@ -2074,6 +2113,29 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, } #endif /* SPI_FLASH_SFDP_SUPPORT */ +/** + * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings + * after SFDP has been parsed (is also called for SPI NORs that do not + * support RDSFDP). + * @nor: pointer to a 'struct spi_nor' + * + * 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 incomplete or wrong). + */ +static void spi_nor_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + if (nor->info->fixups && nor->info->fixups->post_sfdp) + nor->info->fixups->post_sfdp(nor, params); +} + +static void spi_nor_default_init_fixups(struct spi_nor *nor) +{ + if (nor->info->fixups && nor->info->fixups->default_init) + nor->info->fixups->default_init(nor); +} + static int spi_nor_init_params(struct spi_nor *nor, const struct flash_info *info, struct spi_nor_flash_parameter *params) @@ -2152,6 +2214,8 @@ static int spi_nor_init_params(struct spi_nor *nor, } } + spi_nor_default_init_fixups(nor); + /* Override the parameters with data read from SFDP tables. */ nor->addr_width = 0; nor->mtd.erasesize = 0; @@ -2168,6 +2232,8 @@ static int spi_nor_init_params(struct spi_nor *nor, } } + spi_nor_post_sfdp_fixups(nor, params); + return 0; } @@ -2463,6 +2529,7 @@ int spi_nor_scan(struct spi_nor *nor) info = spi_nor_read_id(nor); if (IS_ERR_OR_NULL(info)) return -ENOENT; + nor->info = info; /* Parse the Serial Flash Discoverable Parameters table. */ ret = spi_nor_init_params(nor, info, ¶ms); if (ret) @@ -2567,7 +2634,6 @@ int spi_nor_scan(struct spi_nor *nor) } /* Send all the required SPI flash commands to initialize device */ - nor->info = info; ret = spi_nor_init(nor); if (ret) return ret;
Sometimes the information in a flash's SFDP tables is wrong. Sometimes some information just can't be expressed in the SFDP table. So, introduce the fixup hooks to allow tailoring settings for a specific flash. Three hooks are added: default_init, post_sfdp, and post_bfpt. These allow tweaking the flash settings at different point in the probe sequence. Since the hooks reside in nor->info, set that value just before the call to spi_nor_init_params(). The hooks and at what points they are executed mimics Linux's spi-nor framework. Signed-off-by: Pratyush Yadav <p.yadav at ti.com> --- drivers/mtd/spi/sf_internal.h | 3 ++ drivers/mtd/spi/spi-nor-core.c | 70 +++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-)