From nobody Tue Apr 7 01:35:35 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16CE73D7D81 for ; Fri, 3 Apr 2026 16:10:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232618; cv=none; b=Sdj1+rGwruOlhX8ezNL5X+gCdq8UuHr4Gk4IPZxQcee9wFacqxnabZBx7y6qhK5E+wzHo2FLu0tABgbxWxQV452poujPa1mRDER+7WdQkxkPmKfn3LuPaBy1oDYmXtqJC/E4QJRk+QPie9U/hI/7XNAhSTCLpv0RDHkKunj4tBs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232618; c=relaxed/simple; bh=mkmEtHjfno7BrqYxn+2qtBCwbKqk9Eb1hL7hQgRprbE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NRYk+q1YOgEY6YXl2ZGNdNww/uAgLMbpkWfxwTF1LzCsZsIwzk+Uz/befnfNSIOY8tav0guH9DX2Oe5g62kEnX8TB3rQJ5UWldnT8jNLpAoTNoxCDuBVC2HohOIlvfXA7lvlpeavgXIvchs2JkR4naY15qeVJkzp1qzIjeU7UM8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=1Xp0eFXy; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="1Xp0eFXy" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id DD6D71A312D; Fri, 3 Apr 2026 16:10:15 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B4F83603C1; Fri, 3 Apr 2026 16:10:15 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EBC7510450104; Fri, 3 Apr 2026 18:10:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232614; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=gf2sz28V6drZB5H8n8sxIavE5yDvazDOrc553DkZdjo=; b=1Xp0eFXyL4sxm/atxcMaeiXBZ82kBdtGv2DArMboLTPdIthESUq7lFiox/jgKruMZpLKkf DVLZXruh/L4VD1LqNQUWqiw7DYBbIFUyy3kTU1Vprd142fhPDwKGhJWilaP8Km+q/EV9uy OeuQnSPb6GRsutfBCrDxqTQG3435IiSUjxaf2Mo90piS/Je3LD6ds62p8O0lgBS1WGLrKP zD/F/eR0G/SSWPzYlpafDcuhx6psGmpdTMYX6p1QBSWFvK+YP3D3OCj7n19ZwLq/lCSmVw GMNBbxM0Agn6GG1Halkyif3orgSHopE0NMDu5Xgm8JObz8ZmsVGqqgv5F0PTlg== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:34 +0200 Subject: [PATCH v4 16/27] mtd: spi-nor: Create a local SR cache Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260403-winbond-v6-18-rc1-spi-nor-swp-v4-16-833dab5e7288@bootlin.com> References: <20260403-winbond-v6-18-rc1-spi-nor-swp-v4-0-833dab5e7288@bootlin.com> In-Reply-To: <20260403-winbond-v6-18-rc1-spi-nor-swp-v4-0-833dab5e7288@bootlin.com> To: Pratyush Yadav , Michael Walle , Takahiro Kuwano , Richard Weinberger , Vignesh Raghavendra , Jonathan Corbet Cc: Sean Anderson , Thomas Petazzoni , Steam Lin , linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Miquel Raynal X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 In order to be able to generate debugfs output without having to actually reach the flash, create a SPI NOR local cache of the status registers. What matters in our case are all the bits related to sector locking. As such, in order to make it clear that this cache is not intended to be used anywhere else, we zero the irrelevant bits. The cache is initialized once during the early init, and then maintained every time the write protection scheme is updated. Suggested-by: Michael Walle Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 6 +++++- drivers/mtd/spi-nor/core.h | 1 + drivers/mtd/spi-nor/swp.c | 35 +++++++++++++++++++++++++++++++++-- include/linux/mtd/spi-nor.h | 2 ++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index f007bd6b389a..eb7744926e44 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -3328,8 +3328,12 @@ static int spi_nor_init(struct spi_nor *nor) */ 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)) { spi_nor_try_unlock_all(nor); + } else { + /* In the other cases, make sure the debugfs SR cache is up to date */ + spi_nor_cache_sr_lock_bits(nor, NULL); + } =20 if (nor->addr_nbytes =3D=3D 4 && nor->read_proto !=3D SNOR_PROTO_8_8_8_DTR && diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 3dc9ba3bc6da..091eb934abe4 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -674,6 +674,7 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor, =20 void spi_nor_init_default_locking_ops(struct spi_nor *nor); void spi_nor_try_unlock_all(struct spi_nor *nor); +void spi_nor_cache_sr_lock_bits(struct spi_nor *nor, u8 *sr); void spi_nor_set_mtd_locking_ops(struct spi_nor *nor); void spi_nor_set_mtd_otp_ops(struct spi_nor *nor); =20 diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index c3dbc8832025..7a6c2b8ef921 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -160,6 +160,25 @@ static int spi_nor_build_sr(struct spi_nor *nor, const= u8 *old_sr, u8 *new_sr, return 0; } =20 +/* + * Keep a local cache containing all lock-related bits for debugfs use onl= y. + * This way, debugfs never needs to access the flash directly. + */ +void spi_nor_cache_sr_lock_bits(struct spi_nor *nor, u8 *sr) +{ + u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); + u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); + + if (!sr) { + if (spi_nor_read_sr(nor, nor->bouncebuf)) + return; + + sr =3D nor->bouncebuf; + } + + nor->dfs_sr_cache[0] =3D sr[0] & (bp_mask | tb_mask | SR_SRWD); +} + /* * Lock a region of the flash. Compatible with ST Micro and similar flash. * Supports the block protection bits BP{0,1,2}/BP{0,1,2,3} in the status @@ -269,7 +288,13 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t= ofs, u64 len) (ofs_old < ofs_new || (ofs_new + len_new) < (ofs_old + len_old))) return -EINVAL; =20 - return spi_nor_write_sr_and_check(nor, status_new[0]); + ret =3D spi_nor_write_sr_and_check(nor, status_new[0]); + if (ret) + return ret; + + spi_nor_cache_sr_lock_bits(nor, status_new); + + return 0; } =20 /* @@ -351,7 +376,13 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff= _t ofs, u64 len) (ofs_new < ofs_old || (ofs_old + len_old) < (ofs_new + len_new))) return -EINVAL; =20 - return spi_nor_write_sr_and_check(nor, status_new[0]); + ret =3D spi_nor_write_sr_and_check(nor, status_new[0]); + if (ret) + return ret; + + spi_nor_cache_sr_lock_bits(nor, status_new); + + return 0; } =20 /* diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 90a0cf583512..9ad77f9e76c2 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -371,6 +371,7 @@ struct spi_nor_flash_parameter; * @reg_proto: the SPI protocol for read_reg/write_reg/erase operations * @sfdp: the SFDP data of the flash * @debugfs_root: pointer to the debugfs directory + * @dfs_sr_cache: Status Register cached value for debugfs use only * @controller_ops: SPI NOR controller driver specific operations. * @params: [FLASH-SPECIFIC] SPI NOR flash parameters and settings. * The structure includes legacy flash parameters and @@ -409,6 +410,7 @@ struct spi_nor { enum spi_nor_cmd_ext cmd_ext_type; struct sfdp *sfdp; struct dentry *debugfs_root; + u8 dfs_sr_cache[2]; =20 const struct spi_nor_controller_ops *controller_ops; =20 --=20 2.53.0