* [PATCH] mtd: spi-nor: allow force unlocking via DT property
@ 2026-08-05 17:12 Chen Minqiang
2026-08-06 5:41 ` Takahiro.Kuwano
0 siblings, 1 reply; 3+ messages in thread
From: Chen Minqiang @ 2026-08-05 17:12 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: Takahiro Kuwano, linux-mtd, linux-kernel, Chen Minqiang
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.
Signed-off-by: Chen Minqiang <ptpt52@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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* RE: [PATCH] mtd: spi-nor: allow force unlocking via DT property
2026-08-05 17:12 [PATCH] mtd: spi-nor: allow force unlocking via DT property Chen Minqiang
@ 2026-08-06 5:41 ` Takahiro.Kuwano
0 siblings, 0 replies; 3+ messages in thread
From: Takahiro.Kuwano @ 2026-08-06 5:41 UTC (permalink / raw)
To: ptpt52, pratyush, mwalle, miquel.raynal, richard, vigneshr
Cc: linux-mtd, linux-kernel
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@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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] mtd: spi-nor: allow force unlocking via DT property
[not found] <2026-08-05171214.2934-1-ptpt52@gmail.com>
@ 2026-08-06 11:24 ` Chen Minqiang
0 siblings, 0 replies; 3+ messages in thread
From: Chen Minqiang @ 2026-08-06 11:24 UTC (permalink / raw)
To: Pratyush Yadav, Michael Walle, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra
Cc: Takahiro Kuwano, linux-mtd, linux-kernel
Hi,
Thank you for your valuable insight!
You are completely right that for unlisted/generic chips that feature a 4-bit
BP layout (BP3 at bit 5 or bit 6) or a CMP (Complement Protect) bit in SR2,
spi_nor_unlock() won't clear those extra bits without the corresponding flags
(SNOR_F_HAS_4BIT_BP / SNOR_F_HAS_SR2_CMP_BIT6) set by the ID database or SFDP.
However, in practice:
1. The vast majority of 3.3V/1.8V generic SPI NOR flashes (e.g. 4MB-16MB chips
commonly found in vendor devices like Tenda AX12L Pro) use the standard
3-bit BP (BP0-BP2, SR1 bits 2..4).
2. The current main issue is that even for these standard 3-bit BP chips, the
kernel currently skips spi_nor_try_unlock_all() completely at boot time if
CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE is set (for non-volatile chips)
or if SNOR_F_HAS_LOCK is not set in chip flags. As a result, status registers
locked by factory bootloaders are never cleared.
`linux,force-sr-unlock` serves as a pragmatic DT override to force the unlock
attempt at probe time.
To address your point regarding 4-bit BP and CMP bits for unlisted chips, we
have two potential options:
Option A (Current Best-Effort):
Keep the patch as-is, treating `linux,force-sr-unlock` as a best-effort DT
trigger to invoke standard spi_nor_unlock(). It successfully unlocks the vast
majority of standard 3-bit BP generic chips. For rare unlisted chips with 4-bit
BP or CMP bits, explicit entries can still be added to the ID database when
discovered.
Option B (Aggressive Force-Clear):
When `linux,force-sr-unlock` is present in DT, enhance spi_nor_try_unlock_all()
to perform a broader clear operation on SR1 (masking bits 2..6 to clear BP0-BP3/TB)
and SR2 (clearing CMP bit if SR2 is readable).
Which approach would you prefer? I'd be happy to revise the patch based on your
guidance.
Best regards,
Chen Minqiang
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-06 11:24 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 17:12 [PATCH] mtd: spi-nor: allow force unlocking via DT property Chen Minqiang
2026-08-06 5:41 ` Takahiro.Kuwano
[not found] <2026-08-05171214.2934-1-ptpt52@gmail.com>
2026-08-06 11:24 ` Chen Minqiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox