[PATCH] mtd: spi-nor: allow force unlocking via DT property

Takahiro.Kuwano at infineon.com Takahiro.Kuwano at infineon.com
Wed Aug 5 22:41:18 PDT 2026


Hi,
 
> Some SPI NOR flash chips (such as generic or unlisted chips used in vendor
> devices like Tenda AX12L Pro) have Block Protection (BP) bits set in the
> Status Register by bootloaders or factory settings, locking flash blocks.
> 
> Because vendors frequently switch between various generic SPI NOR flash
> chips ("Flash Lottery"), it is impractical to upstream explicit chip ID
> flags (SNOR_F_HAS_LOCK) for every possible generic chip variant.
> 
> This patch introduces support for the "linux,force-sr-unlock" Device Tree
> property:
> 1. In spi_nor_init(), trigger spi_nor_try_unlock_all() if "linux,force-sr-unlock"
>    is present in the flash DT node, even when CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE
>    is active and the chip is non-volatile.
> 2. In spi_nor_try_unlock_all(), bypass the SNOR_F_HAS_LOCK flag check when
>    "linux,force-sr-unlock" is specified, ensure locking_ops are initialized,
>    and invoke Linux kernel's native spi_nor_unlock() mechanism.

Does this work for generic(unlisted) SPI NOR flash chips with 4-bit BP
and/or CMP bit? I think we need to rely on ID database to know what block
protection bits are available in the chip.

> 
> Signed-off-by: Chen Minqiang <ptpt52 at gmail.com>
> ---
>  drivers/mtd/spi-nor/core.c | 3 ++-
>  drivers/mtd/spi-nor/swp.c  | 7 ++++++-
>  2 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index ccf4396cdcd0..ef0bdc1254bb 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3332,7 +3332,8 @@ 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)) {
> +            nor->flags & SNOR_F_SWP_IS_VOLATILE) ||
> +           of_property_read_bool(spi_nor_get_flash_node(nor), "linux,force-sr-unlock")) {
>                 spi_nor_try_unlock_all(nor);
>         }
> 
> diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
> index 235070b215d1..a190d10c1630 100644
> --- a/drivers/mtd/spi-nor/swp.c
> +++ b/drivers/mtd/spi-nor/swp.c
> @@ -628,11 +628,16 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, u64 len)
>   */
>  void spi_nor_try_unlock_all(struct spi_nor *nor)
>  {
> +       struct device_node *np = spi_nor_get_flash_node(nor);
> +       bool force_unlock = of_property_read_bool(np, "linux,force-sr-unlock");
>         int ret;
> 
> -       if (!(nor->flags & SNOR_F_HAS_LOCK))
> +       if (!(nor->flags & SNOR_F_HAS_LOCK) && !force_unlock)
>                 return;
> 
> +       if (!nor->params->locking_ops)
> +               spi_nor_init_default_locking_ops(nor);
> +
>         dev_dbg(nor->dev, "Unprotecting entire flash array\n");
> 
>         ret = spi_nor_unlock(&nor->mtd, 0, nor->params->size);
> --
> 2.17.1

Thanks,
Takahiro




More information about the linux-mtd mailing list