[PATCH v5 09/14] mtd: spi-nor: core: Init all flash parameters based on SFDP where possible

Pratyush Yadav p.yadav at ti.com
Mon Dec 6 07:04:13 PST 2021


On 06/12/21 01:52PM, Tudor.Ambarus at microchip.com wrote:
> On 12/6/21 2:22 PM, Pratyush Yadav wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > On 03/12/21 04:22PM, Tudor Ambarus wrote:
> >> New flash additions that support SFDP should be declared with
> >> PARSE_SFDP and with all the other flags that are not SFDP
> >> discoverable.
> >>
> >> Keep the old way of initializing the flash, until all the flashes
> >> are converted to use either PARSE_SFDP or SPI_NOR_SKIP_SFDP.
> >>
> >> Flashes that declare PARSE_SFDP do not have a roll-back mechanism
> >> because if spi_nor_parse_sfdp() returns an error it means that either
> >> BFPT is not supported, thus SFDP is not supported and the user didn't
> >> correctly declared the flash_info entry, or some memalloc failed.
> >> Either way we should return an error. The rest of the SFDP tables are
> >> optional, if one of the optional SFDP tables fails, we just continue.
> >> We would like to get rid of the default_init() hook, so the
> >> spi_nor_manufacturer_init_params() is not called in the new sequnce
> >> of flash initialization that is based solely on SFDP.
> >>
> >> Split spi_nor_info_init_params() in spi_nor_init_default_params()
> >> and spi_nor_no_sfdp_init_params(). spi_nor_init_default_params() is
> >> called for all the flashes regardless if they support SFDP or not.
> >> spi_nor_no_sfdp_init_params() is called just for the flashes that
> >> do not define SFDP and initializes parameters and setting solely
> >> based on flash_info data.
> >>
> >> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> >> ---
> >>  drivers/mtd/spi-nor/core.c | 194 ++++++++++++++++++++++---------------
> >>  1 file changed, 116 insertions(+), 78 deletions(-)
> >>
> >> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> >> index 86bbd1ca22fc..d5eaf9a705ae 100644
> >> --- a/drivers/mtd/spi-nor/core.c
> >> +++ b/drivers/mtd/spi-nor/core.c
> >> @@ -2509,74 +2509,21 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
> >>  }
> >>
> >>  /**
> >> - * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
> >> - * based on JESD216 SFDP standard.
> >> + * 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
> > 
> > s/fixup hooks/fixup flags/ ?
> 
> fixup hooks is fine if we want to fix a wrong SFDP table.
> fixup flags for settings that are not SFDP discoverable, i.e. where the table
> is missing.

Ok.

> 
> 3/ 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.
> > 
> >> + * bits.
> >>   * @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(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));
> >> -             nor->addr_width = 0;
> >> -             nor->flags &= ~SNOR_F_4B_OPCODES;
> >> -     }
> >> -}
> > [...]
> >> +
> >> +/**
> >> + * 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 ((SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_OCTAL_READ |
> >> +          SPI_NOR_OCTAL_DTR_READ) &&
> >> +         !(nor->info->no_sfdp_flags & SPI_NOR_SKIP_SFDP))
> >> +             spi_nor_sfdp_init_params_deprecated(nor);
> >> +}
> >> +
> > [...]
> >> @@ -2773,24 +2807,28 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
> >>   * parameters that are not declared in the JESD216 SFDP standard, or where SFDP
> >>   * tables are not defined at all.
> >>   *           spi_nor_late_init_params()
> >> + *
> >> + * Return: 0 on success, -errno otherwise.
> >>   */
> >>  static int spi_nor_init_params(struct spi_nor *nor)
> >>  {
> >> +     int ret;
> >> +
> >>       nor->params = devm_kzalloc(nor->dev, sizeof(*nor->params), GFP_KERNEL);
> >>       if (!nor->params)
> >>               return -ENOMEM;
> >>
> >> -     spi_nor_info_init_params(nor);
> >> -
> >> -     spi_nor_manufacturer_init_params(nor);
> >> +     spi_nor_init_default_params(nor);
> >>
> >> -     if ((nor->info->parse_sfdp ||
> >> -          (nor->info->no_sfdp_flags & (SPI_NOR_DUAL_READ |
> >> -                                       SPI_NOR_QUAD_READ |
> >> -                                       SPI_NOR_OCTAL_READ |
> >> -                                       SPI_NOR_OCTAL_DTR_READ))) &&
> >> -         !(nor->info->no_sfdp_flags & SPI_NOR_SKIP_SFDP))
> >> -             spi_nor_sfdp_init_params(nor);
> >> +     if (nor->info->parse_sfdp) {
> >> +             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 {
> >> +             spi_nor_init_params_deprecated(nor);
> > 
> > Hmm, a flash without SFDP would always go via the "deprecated" path even
> > if it is a new entry. It makes no difference in practice, but is just
> > slightly confusing logically. Can we make this a bit clearer? How about
> > this:
> > 
> >   if (nor->info->parse_sfdp) {
> >         ...
> >   } else if (nor->info->no_sfdp_flags & SPI_NOR_SKIP_SFDP) {
> >         spi_nor_no_sfdp_init_params();
> >         spi_nor_manufacturer_init_params();
> >   } else {
> >         spi_nor_init_params_deprecated();
> >   }
> > 
> >> +     }
> 
> Ok, will do. Can I add your R-b tag on a local v6 with this change that you
> proposed? It will spare me of sending v6.

Sure, go ahead.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.



More information about the linux-mtd mailing list