From nobody Tue Apr 7 00:08:32 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 02D8D3CD8B5 for ; Fri, 3 Apr 2026 16:09:38 +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=1775232580; cv=none; b=O67Sdlu4Y5C2+mziHbCGcPO3l/R+5DR3b8G9xuLZP5zpWE7CTZnTWlfKIzGWeTa4A0jG4snDS3SsDf9nf9lvxuOdy+xU2lavuqHJInpNaqReC5DLbM2dPqvh8HkAY+/bC2EL2cwIXkI5sdPikEBM6oBOgsMoVhQ7DQsZQLKQrY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232580; c=relaxed/simple; bh=wTTB6e/8ePxI86D4Nfy1cUgRHfcwns176A2TR63+Vjg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PZ4d36iOoAToikK/RTLTSB47ZbebZhAMxloP83oQnDAEQVi543ucEg+YrcXLHgSmZBQnNOkwn4he6p/qOYfLUCOoi0ngqfGjHLOtTsAKzfhSwLapO5LjytGX7NO9Vt84lmI6N5yID/G9D9b+MibVsoeXp18ctxk3FloQPHLAQEU= 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=Hn4h7qIM; 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="Hn4h7qIM" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id AE19C1A312C; Fri, 3 Apr 2026 16:09:37 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7CE46603C1; Fri, 3 Apr 2026 16:09:37 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3EDFF104500FB; Fri, 3 Apr 2026 18:09:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232576; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=leC2dd2KClzTPcQ+8AI037xoM94Wj2JcMmNh8kB3Pi8=; b=Hn4h7qIM4fJSHsGqMHx5JY8OqoBGLRKnqcJvlZopGP+HUvWSPk+5wKvKSgPr2E/5Uvg4Ax Q8uAUayCOe7YAnuqfmI+o4y0gnSD5fIQwjE/aBOMa2Z9wqFpkPh2gTavoc3kCqYJd6EkPD Su0lLda10KhbJ6wQmZYR/tLoQIWeuh+JVfekdpPK6G1a7cjbRwaVv7vloQ+6xZK+cPaxOE pQN21+xK94Vw9DiJJsA0rXZ9/An1Hy6KNpClW3H0el0SQ5NzDnULNOqttbESydTRAxYdB0 5YhDudGOqNJSuXSGhWOjRQxBcOR3Qz0CjwBdgfyyqS9zsC3IPF+Fsu9zHhUq3w== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:19 +0200 Subject: [PATCH v4 01/27] mtd: spi-nor: Drop duplicate Kconfig dependency 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-1-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 I do not think the MTD dependency is needed twice. This is likely a duplicate coming from a former rebase when the spi-nor core got cleaned up a while ago. Remove the extra line. Fixes: b35b9a10362d ("mtd: spi-nor: Move m25p80 code in spi-nor.c") Signed-off-by: Miquel Raynal Reviewed-by: Michael Walle --- drivers/mtd/spi-nor/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig index 24cd25de2b8b..fd05a24d64a9 100644 --- a/drivers/mtd/spi-nor/Kconfig +++ b/drivers/mtd/spi-nor/Kconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig MTD_SPI_NOR tristate "SPI NOR device support" - depends on MTD depends on MTD && SPI_MASTER select SPI_MEM help --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 D881A3CE48E for ; Fri, 3 Apr 2026 16:09:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232583; cv=none; b=rkOCCz7y5nHSCsJNo9CUTGyQwE6ViMmOciI3E5BhfCmJjZ8prbNZF/vVDdEpe1q/7PJ0lCwbPI/Dmrk/Ec8ojnA9I9Q0lkZnfTTHQDlqKUAHA5it6lcEMbB6lX+pEuHDx2SO3vvxFWFF4U9xSSgb9exHKLj3BXxrL0gXqqvK2ZQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232583; c=relaxed/simple; bh=FUqMuwPe/VeYULAiVeahm1trZi1oXESB2z3mCxIRzWc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Lhl3EJcw5YqWjdseg6NPTlt/PBaBfh9Jg8+29tin+RCX45M2FfNU20XhLCTSfnyQbmI9qkjApNfbUHftWdKHcnrn5eCdmB1N3y8ciqphR3jZ0EfVpdrfDibNiB6YrC7kt3m8FXrHKEJgT822ZYbsWjtURmnwcFAToCTxRmeuzyg= 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=Ain+qWEc; arc=none smtp.client-ip=185.246.85.4 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="Ain+qWEc" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 9127B4E428D6; Fri, 3 Apr 2026 16:09:40 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 61187603C1; Fri, 3 Apr 2026 16:09:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2290110450102; Fri, 3 Apr 2026 18:09:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232579; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=p/VrR2zWyEuP7FnbthxkSprPO27GGH7TRyCzje2SKqM=; b=Ain+qWEcyhuuX+PCskNbms0GFrH6Fa6gXs37+OO6mzb0XsoVcZZYNGydKLDbaaGKkPP/g4 ml9KZiGns3hIF3CEpI0jpRV9JIxRA7qvByxPx9Mwy/o5zIGdwNEF2SBM0QrfluQZCt7Ple xE/pivzaNzOiN8Fp2h4zEvg3NsVRbPk/cRxcTXy3i2bfYQv7/m7Vu3ailzz/VeVq6plx4Y MplF8QC7Ol5LHj6N+2jgfWmqwHvwB3rLeNqVdXyvD17oJx6MDaD/MqjHBX2mArmJnYm6gQ i0IxqsIEesk+pyNXnm6kkAo9Rlz4bPscweTG18Wsz0uH6aHIaDZkJQYXIPZlAw== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:20 +0200 Subject: [PATCH v4 02/27] mtd: spi-nor: debugfs: Fix the flags list 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-2-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 As mentioned above the spi_nor_option_flags enumeration in core.h, this list should be kept in sync with the one in the core. Add the missing flag. Fixes: 6a42bc97ccda ("mtd: spi-nor: core: Allow specifying the byte order i= n Octal DTR mode") Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/debugfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index fa6956144d2e..d700e0b27182 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -28,6 +28,7 @@ static const char *const snor_f_names[] =3D { SNOR_F_NAME(RWW), SNOR_F_NAME(ECC), SNOR_F_NAME(NO_WP), + SNOR_F_NAME(SWAP16), }; #undef SNOR_F_NAME =20 --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 59B833D333D for ; Fri, 3 Apr 2026 16:09:44 +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=1775232585; cv=none; b=Efpz2UU6+aYBCgY167FbgTl07chy/GotpK06ugzNfZviXaPUIu5yPQKiIOn/dY923ou39oSGJDlLKXDyjupF6rp+t8twJv63MPxNO7OHauqzWa5UivmgCDvBR/vCaEA7721HDZSJ98wC8GrEGkxIumhGm+DXRkc41IGHCR/mMpo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232585; c=relaxed/simple; bh=Jns2CIUjvfqMc8vkfAzCQiarYG40DUVF+LP86IQHB5Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uN7bRpAMoR44p3dOO9OtKTlb9WWIvwS8AYxFz/1VcqJgtjqEBn+wPkfOOKSYcNbnT/ZTyypfoorAISTxepsdgEATk4xQQOr6pLvMhX85w+gZdHJyT6NsVHrPekOBDyqHWK1bPdz2MjkZEFQoEL/DftwYVRkTE8goBxJZCo3fuVc= 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=yyYukdm8; 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="yyYukdm8" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 202A41A312E; Fri, 3 Apr 2026 16:09:43 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EA8F4603C1; Fri, 3 Apr 2026 16:09:42 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F3AE3104500FB; Fri, 3 Apr 2026 18:09:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232582; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=FOjmpf/BiPzAyc0p3HUqSMX9zMlXNwI7+2z6Kuibe7o=; b=yyYukdm86ZsAGlKG/3f3PQKPIfYDuOQx1VPnli+S74aXqfjp+2mQ6UJdTZrIw7f5QNqyg5 mIBaOo+eM2CRlZuu25RWyN/8ozqLlk+5J3tDVYK5Q1/OtwfZUTiLVaeYyLIKG6pItD8dlF NgcpnYshN4V9VkyuV0dEWYBQ7mFQyUhs7OYcMl2IxBxlr56JhFCmWH3ATvDRVQc8whNV78 Ox4uaIbR40Low5OEyUCaXsP88triWvZ1obqchLLc0mtfQQV5MnvYiv4lDPVG/z1h6pxcWB xdfeeEWalx9p4oJYuqgMsrN+zYk9GZ1QnUtt/WPsRjGpOI4/NF+Vadya2kOTwQ== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:21 +0200 Subject: [PATCH v4 03/27] mtd: spi-nor: swp: Improve locking user experience 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-3-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 , stable@kernel.org X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 In the case of the first block being locked (or the few first blocks), if the user want to fully unlock the device it has two possibilities: - either it asks to unlock the entire device, and this works; - or it asks to unlock just the block(s) that are currently locked, which fails. It fails because the conditions "can_be_top" and "can_be_bottom" are true. Indeed, in this case, we unlock everything, so the TB bit does not matter. However in the current implementation, use_top would be true (as this is the favourite option) and lock_len, which in practice should be reduced down to 0, is set to "nor->params->size - (ofs + len)" which is a positive number. This is wrong. An easy way is to simply add an extra condition. In the unlock() path, if we can achieve the same result from both sides, it means we unlock everything and lock_len must simply be 0. A comment is added to clarify that logic. Fixes: 3dd8012a8eeb ("mtd: spi-nor: add TB (Top/Bottom) protect support") Cc: stable@kernel.org Signed-off-by: Miquel Raynal Reviewed-by: Michael Walle --- drivers/mtd/spi-nor/swp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 9b07f83aeac7..1d50db1ef1a0 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -280,8 +280,15 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff= _t ofs, u64 len) /* Prefer top, if both are valid */ use_top =3D can_be_top; =20 - /* lock_len: length of region that should remain locked */ - if (use_top) + /* + * lock_len: length of region that should remain locked. + * + * When can_be_top and can_be_bottom booleans are true, both adjacent + * regions are unlocked, thus the entire flash can be unlocked. + */ + if (can_be_top && can_be_bottom) + lock_len =3D 0; + else if (use_top) lock_len =3D nor->params->size - (ofs + len); else lock_len =3D ofs; --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 067D83D34B3 for ; Fri, 3 Apr 2026 16:09:46 +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=1775232588; cv=none; b=pWu8KMPFLlK2NNW5llpq4nqOJHF7EJHUFCKuhXWtZnWlffQHz+UKkHRE6AfX1C1aekMVhVsbt/D3aHA32ImKUeHYj3C08xXwAiXRUdXuly3Ct+CZqM1p5AY4OYo9xVy4ahrO3teZHEeDaM+Xx2PHsX2W1t+w4Z/tfrX7PcvJz8U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232588; c=relaxed/simple; bh=yZMj00763w8r8wUBQCaUh5FU4u4u6hQXAxOsrUapcsc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EsM1Be+zMptibzHRCCtc6aYqkRc2mY3qjYFNpTwARlg7bN1WPmIHuBp0Azcuqi123CPzuJDgD0TVLI7ftyoFsti4iGe/+8ZkS647dJVGx5JGkjRhCGUu2UGDSspR0nTSfM5NHvkhE409IfiGEq0/UrNzAlLsukwGB01Qcr6ndTM= 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=Dsu3Enba; 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="Dsu3Enba" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 9CC5D1A312D; Fri, 3 Apr 2026 16:09:45 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7271B603C1; Fri, 3 Apr 2026 16:09:45 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8A02C104500FA; Fri, 3 Apr 2026 18:09:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232584; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=qqYr/KNjLLcJYcEfDklSWHxXQ8BxYrzb3yZHrjztITk=; b=Dsu3EnbaILNX5V0F5ab8fLoPGLUjrRk1csn9QUM3knb3I4gmjcGUBz5JsmTAFeghkV6wEu Slhq73+GW9A7ie28CVBpGZ/7CIoUDTDXuFiIWkLkHHnWele1bpUXtYBsS4+6n96yX61Yg1 /ZSkUn8+7aDg6NzGd7W9DnA7poKLQQ/8lc0WKBj3mlNE7XewIRfd88uJDYycKSiw+yhsMO 5snhDSDx5gha83q0UZTBqvl7vPkMV1VxDVvnMMkh54aM3I4PzLJEPG6AQhWekmeEc3XoXe FsWy1DLTHV12rKUNPA4JGVlD4Omf7DwwmZW7L8OmhbLMurSrFv0DoogD1GOb2A== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:22 +0200 Subject: [PATCH v4 04/27] mtd: spi-nor: Improve opcodes documentation 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-4-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 There are two status registers, named 1 and 2. The current wording is misleading as "1" may refer to the status register ID as well as the number of bytes required (which, in this case can be 1 or 2). Clarify the comments by aligning them on the same pattern: "{read,write} status {1,2} register" Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal --- include/linux/mtd/spi-nor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index cdcfe0fd2e7d..90a0cf583512 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -21,8 +21,8 @@ /* Flash opcodes. */ #define SPINOR_OP_WRDI 0x04 /* Write disable */ #define SPINOR_OP_WREN 0x06 /* Write enable */ -#define SPINOR_OP_RDSR 0x05 /* Read status register */ -#define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ +#define SPINOR_OP_RDSR 0x05 /* Read status register 1 */ +#define SPINOR_OP_WRSR 0x01 /* Write status register 1 */ #define SPINOR_OP_RDSR2 0x3f /* Read status register 2 */ #define SPINOR_OP_WRSR2 0x3e /* Write status register 2 */ #define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 98F303D3D00 for ; Fri, 3 Apr 2026 16:09:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232590; cv=none; b=jmI5aHXiwVamW1hm8Ov+bZBwa3jfUJfVKSEx/FTmKZUFVtMxzqqd4yYly9X0mclmJvu9jwbz+ndsoJz1UiJQBn6c80tWAD8kfBs8CW5OdsFGg8hSxvuZxB+aDl2l0uGpWQp1LoPbLoQwnAasU1SlYeuQ2ZfKHtjVvKpCwa/vm3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232590; c=relaxed/simple; bh=9MefzCIV+tnB/FnzOtLFwFa7sENOrT3OAIQ9rTsmCUI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hNwKO6/dLMsSo/1Y7VA9zmjJyCnaTcfDNvBbPt9bMtd+IP3q5npR/w+NDCwDwveQ2ulxS4W/W3d+eNzLZi6PWtFJQlO9ci7Fm4ibH0aBmMtdOwyLlaxjDCkjcqOtVqZowm4gmR4Mpy85VZvFt20E6Tve3lvfdgdoCIHmkHqa0PU= 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=beNsjK4q; arc=none smtp.client-ip=185.246.85.4 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="beNsjK4q" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 789DF4E428D5; Fri, 3 Apr 2026 16:09:48 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4F663603C1; Fri, 3 Apr 2026 16:09:48 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1DDD310450104; Fri, 3 Apr 2026 18:09:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232587; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=UWpfRE4WtdnRITw0PIgGXyjweTZSRtj+l56eZxMc4k0=; b=beNsjK4q//+q1Zgb3Ggz6kZ58H9Rh8De5IrbwClMCJgnF95ZDHbfpQgoQaUP5czuUHZXrb Qx2SxlYsvL6RqsFX9wQYB1+2aL0dP7/bbW96SXLGfW9fFnSf3N/GylbiXm4zrd2aTW/Xo/ LPcu4DzRh/u5iz7y3TqRgjcEaiJ0dksAIKFrEmu3AVehOlbjYsZhLgXDxZpC6PpDcXNAL/ cGOGq1cZS6H9xUMCN5sPi88ywglPg8hD2DVoROjMjePzSi6Ouk6+MilN4HLtz09vH9ulUS eiw2RRdNluejCF4YT30jqpWDExTs96yAurpY4xD7ToIGTmuGcMyv2Jttc/sP0w== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:23 +0200 Subject: [PATCH v4 05/27] mtd: spi-nor: debugfs: Align variable access with the rest of the file 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-5-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 The "params" variable is used everywhere else, align this particular line of the file to use "params" directly rather than the "nor" pointer. Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index d700e0b27182..69830ad43990 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -139,7 +139,7 @@ static int spi_nor_params_show(struct seq_file *s, void= *data) =20 if (!(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { string_get_size(params->size, 1, STRING_UNITS_2, buf, sizeof(buf)); - seq_printf(s, " %02x (%s)\n", nor->params->die_erase_opcode, buf); + seq_printf(s, " %02x (%s)\n", params->die_erase_opcode, buf); } =20 seq_puts(s, "\nsector map\n"); --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 0D1123CF047 for ; Fri, 3 Apr 2026 16:09:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232593; cv=none; b=Rf0bA8Q0H+HYi8zrODduETnG0989Fb6nggL9ml1v9AEaPmXe6/eJ3TzHkDJ8Mq3tAAB0twwr+txPgT/4+eWjhQoNNJsiTm7s16tXatwiP/ZHjPpqL4k7hQvoYhbX8jFptXhhEG+JiANkoE7OYxdq8XjQRV0JzkEQV6PRf6h0ye0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232593; c=relaxed/simple; bh=AJ5kgwcORFft8X7fGFxg332WWjDtcyKWpTMRFzOEUgE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jLIA5aiqlV8WvP/N/3bgL7rFbM/TuxE75QytvvqLsZS/Z88fEKFbgELNA465u0QXcswIWmy6QNRN6LUSAigNNmkB8KIHDB1OcpNsVxJG3urv/qeZ7ZXmMh/7cWKekQ+3YlCrGHyYoVYJf5cicVJBBvDwi/z/HCCqdkSSkd3BLPY= 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=mk8QuibA; arc=none smtp.client-ip=185.246.85.4 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="mk8QuibA" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id DA02B4E428D6 for ; Fri, 3 Apr 2026 16:09:50 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id AC2C2603C1; Fri, 3 Apr 2026 16:09:50 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 07CE010450109; Fri, 3 Apr 2026 18:09:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232589; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=380DMxOtkVf4S8j1lpaF5rnIUMKJfHDNDSHsb4bomqI=; b=mk8QuibAk95VamgZNE+FL3M989pwdgmWpqW4LMiT+KCNbITz2GPesT6IeR31Px2Vl9dy3A pnp2GYNhrn6fVGfxksGFmKjufllajN9DVXXN7nh4C46w+RjLRtPO+Pv2s+k7Mfesi0UkwG 7H4XojzYgaFAmnjh4dX8guOXXPBP5/lY2wS3xH+BppNNwH9Jg4MNEScIIA51GQJCqaHl/j u98bo7CJrqMFr2gEtZoqeO/vjiI1uNZAkXTgVFlAtlEMbqDmzJiK3AkmNudydq9oxjkz5H kNKmRjYRIf5GJS4upyXfmnHQyyHSxbjgVuhKsSA9CRRK54/OCqTHYYebCZD2zw== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:24 +0200 Subject: [PATCH v4 06/27] mtd: spi-nor: debugfs: Enhance output 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-6-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 Align the number of dashes to the bigger column width (the title in this case) to make the output more pleasant and aligned with what is done in the "params" file output. Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index 69830ad43990..d0191eb9f879 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -144,7 +144,7 @@ static int spi_nor_params_show(struct seq_file *s, void= *data) =20 seq_puts(s, "\nsector map\n"); seq_puts(s, " region (in hex) | erase mask | overlaid\n"); - seq_puts(s, " ------------------+------------+----------\n"); + seq_puts(s, " ------------------+------------+---------\n"); for (i =3D 0; i < erase_map->n_regions; i++) { u64 start =3D region[i].offset; u64 end =3D start + region[i].size - 1; --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 8AD883D47B3 for ; Fri, 3 Apr 2026 16:09:54 +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=1775232595; cv=none; b=KNpncMglzbPdkkxaUZH107Gv7PhkVUwHtLOL+475cCN6H7gduob0kr6vaFYwMRJKG5kqogP2hL5Lbz1PkVbag8JFpernjWnQ4YwgLpsamzb1MOEMKDSuM0WmjdJRitOsCWO+3EWwOI3MdSfz4nsZOguhljsRDl1bDHjWp60N8zs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232595; c=relaxed/simple; bh=kWw1aR6p8m7hAlouR4+sYFaGHye+H3XbCAC0JIcdhhk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dAQEyoZwDYXMiyobkW9X4VCGBcEAY4w6ae4ZBvQ9QZhyLUmAhNJ9hitpx6fSj3j+hpyaKMetHdaO5/4p1rD0hvWIHmPkgp7U0XgG8UZjfLdgyGX9qdAPLy652gh1p2Dy2lN1xVuA6xnchnunI1JkVuEhkpu+swFfOo2ozyJfSZ8= 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=lvA4n3WW; 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="lvA4n3WW" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 47EC81A312B; Fri, 3 Apr 2026 16:09:53 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1E72F603C1; Fri, 3 Apr 2026 16:09:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 52F0510450103; Fri, 3 Apr 2026 18:09:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232592; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=tFedJhlwMXaI/keWu4o5kk0Lj8Dpliq7e9ukabUVktc=; b=lvA4n3WWkwT+4QMF+Rrao8+Z7oiN4v5mOxgXfzmPLYv4BJ+sMBFUM3JFq7QphWgVyL4+/X /sSihHBKuCalFojGjweW8+QBvVNLbWWYMLz03xX8J6fQYMznczIaHwhjoMGdJewqRqzuTp 4GqzuTbaAePzTVkXhOrD47J/HEFnhpJY4fxDHMGQrCyhL9hvNroEHxA5A7sQxif0DnlzaX KDFtVOc+mfDJctN3JF29BIK6K5TBwraB3p+jt4fxI2IHuKgsciwtuK3YkYAowEFhKxP+sE CqU3/3LGmEdQMiEZvfgzOM4Ag1dqn29q2eGhZAATSgaWDCnsADlW5gC5R2cSaA== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:25 +0200 Subject: [PATCH v4 07/27] mtd: spi-nor: swp: Explain the MEMLOCK ioctl implementation behaviour 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-7-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 Add comments about how these requests are actually handled in the SPI NOR core. Their behaviour was not entirely clear to me at first, and explaining them in plain English sounds the way to go. Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 1d50db1ef1a0..64a917543928 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -346,6 +346,14 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, l= off_t ofs, u64 len) return spi_nor_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]); } =20 +/* + * These ioctls behave according to the following rules: + * ->lock(): Never locks more than what is requested, ie. may lock less + * ->unlock(): Never unlocks more than what is requested, ie. may unlock l= ess + * -is_locked(): Checks if the region is *fully* locked, returns false oth= erwise. + * This feeback may be misleading because users may get an "= unlocked" + * status even though a subpart of the region is effectively= locked. + */ static const struct spi_nor_locking_ops spi_nor_sr_locking_ops =3D { .lock =3D spi_nor_sr_lock, .unlock =3D spi_nor_sr_unlock, --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 D056C3D523F; Fri, 3 Apr 2026 16:09:56 +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=1775232598; cv=none; b=cOF7MTIbKGguMH7SrIQtJ8bTVDWmiNqYzGKH+Mfec+itCwEIt3YfnYSWr5CJQaAPXCUkSttQFbMd4UK/Av05qzgw+l0S4oX5dTfBpZvyBfFJFvRF1WyPk6Non8vE2n4V5y5xUYq/ssAVGgGhUnmKjVsJVusOK8ryp3KPkQqpT4k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232598; c=relaxed/simple; bh=qPLXMm+0NZCXebRLpkoMzE/4h3YXK09rjoiIyhtHPnE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qYPzu6B7TCwaI4kGdvgzqLEcOYD4gAjryDcLlrto64pQHxlsepGbtsvdzLG03ahw/F8JtpzLt0NcmZNyIEG5PPDRVm32tzd+/qxYvGTr+lubreCeMaOWv4oPblkXipKeupc4JlaKNSZErF++jvA01mlBF1eUGW3ssrcOxK0NT0A= 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=Ki2kEhL/; 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="Ki2kEhL/" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 961251A312D; Fri, 3 Apr 2026 16:09:55 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 6BC1E603C1; Fri, 3 Apr 2026 16:09:55 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B386D1045010A; Fri, 3 Apr 2026 18:09:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232594; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=mfKlFM5DiGOhHJ1K9VJE1K/I5oWuny30sbh2IlUETAU=; b=Ki2kEhL/JO8VidYg5ks4h+IeDSHZzT9+wxi83xrg35C40ExITmee9IgiLmAf5swMwKDIk2 YgaJr9DmYluzBhOGeDEshGusZOsZ08M9r8HEwlB9tExHg2A7I+lRKovZQ3iP6qLEhiRKyQ /M4eM0aOF09QKuuEN6ylnJv6yI0oQaMa73kWQ6HSxgk3MH1nmpU0SpTQK1OzmKpvg5dLZg 1fOk9tpGL6FbmdDNv7p2SO3+wXqTy0n2+bHfD2LXZtEUSvhGcWsr3jFbxCV8QapX6yV7vv 064CLCEQImJMy53DRqpjgJ2os6g5D7KTdkkX0R2GbVTJTnjXDFYb+qgPYkxi6w== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:26 +0200 Subject: [PATCH v4 08/27] mtd: spi-nor: swp: Clarify a comment 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-8-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 The comment states that some power of two sizes are not supported. This is very device dependent (based on the size), so modulate a bit the sentence to make it more accurate. Reviewed-by: Michael Walle Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 64a917543928..246f6d5ca8dd 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -303,7 +303,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_= t ofs, u64 len) if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3) val =3D (val & ~SR_BP3) | SR_BP3_BIT6; =20 - /* Some power-of-two sizes are not supported */ + /* Some power-of-two sizes may not be supported */ if (val & ~mask) return -EINVAL; } --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 4B31D3CF660 for ; Fri, 3 Apr 2026 16:09:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232600; cv=none; b=lxL9lIvJUzyB35ZavfZpzCCgj+ea6n1UukNuXtUAjboXj1bE5CjkaWwzNEWlcnwpAICMmRb2QQt2FljW+Gi60QsbzjC4wHbglU+a3MZsqUzEBCQu3UBpBhPKBV3iKbCeAE/iPWXSnQET2KtjPr2dnolMNl8Gj43M8wHxbPr3HIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232600; c=relaxed/simple; bh=HHzoRfRtO8iPYUe0lAcKZ4cCr9QDdcQCnPB6w3QCSCk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z46zcMg/EvXXqD9+d7hm3NPVX4Sj1M/gGUmBD2b1ubq495nn+m+qFbVMqKQ+DTZ7sd3l11y/Bj3NLoI5hNF3lvWSv02VoeODvHaowcpEcoerf7y/IBY3ssNGjWj+WPEiaAfKLUQrjTrEswgjeq/TrR33U4tQWnR1JY6+qwkSJn4= 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=RQQscKkl; arc=none smtp.client-ip=185.171.202.116 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="RQQscKkl" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id E1F37C59F65; Fri, 3 Apr 2026 16:10:29 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E5D20603C1; Fri, 3 Apr 2026 16:09:57 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EE5EE1045010B; Fri, 3 Apr 2026 18:09:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232597; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=FEEJakSsTWiMfYL5vUeTthcl4clNdNKUdcaA2VGznAA=; b=RQQscKklE9JLDBE2pkzvq5SjtLPYh6KpYMqw03+UcsgrhI9SCx8a/SG1gMf+MS8WSm+Ixy CsuSgwUJirWj7mwxqG1R1CMKgFPy0E36aM6pmQ+fIZcfevsDuLPgib2GywHU76kRUtVfoF rbeuicc4m4egh/lueoGr/0k+AfnrUn/fIp02VrViUYkrcR4H4vl9lONDUppC10lVASFw8a Elfto3s8YAQoK7IadWSGGNUcOMGRVAJw/HmDkvAtcsFV6c6Q0TvsdnI1v8Wv6bxtyG4lj+ 0xHV9DMIb/WHduO+8/5jJ+u5h8RNP6HaMVSXmd4P4MaOnjbZksfosT0L16ZrDQ== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:27 +0200 Subject: [PATCH v4 09/27] mtd: spi-nor: swp: Use a pointer for SR instead of a single byte 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-9-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 At this stage, the Status Register is most often seen as a single byte. This is subject to change when we will need to read the CMP bit which is located in the Control Register (kind of secondary status register). Both will need to be carried. Change a few prototypes to carry a u8 pointer. This way it also makes it very clear where we access the first register, and where we will access the second. There is no functional change. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 48 ++++++++++++++++++++++++-------------------= ---- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 246f6d5ca8dd..af6e577d9b42 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -53,13 +53,13 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_no= r *nor) return sector_size; } =20 -static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t= *ofs, +static void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr,= loff_t *ofs, u64 *len) { u64 min_prot_len; u8 mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); - u8 bp, val =3D sr & mask; + u8 bp, val =3D sr[0] & mask; =20 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3_BIT6) val =3D (val & ~SR_BP3_BIT6) | SR_BP3; @@ -79,7 +79,7 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *n= or, u8 sr, loff_t *ofs, if (*len > nor->params->size) *len =3D nor->params->size; =20 - if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask) + if (nor->flags & SNOR_F_HAS_SR_TB && sr[0] & tb_mask) *ofs =3D 0; else *ofs =3D nor->params->size - *len; @@ -90,7 +90,7 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *n= or, u8 sr, loff_t *ofs, * (if @locked is false); false otherwise. */ static bool spi_nor_check_lock_status_sr(struct spi_nor *nor, loff_t ofs, - u64 len, u8 sr, bool locked) + u64 len, const u8 *sr, bool locked) { loff_t lock_offs, lock_offs_max, offs_max; u64 lock_len; @@ -111,13 +111,13 @@ static bool spi_nor_check_lock_status_sr(struct spi_n= or *nor, loff_t ofs, return (ofs >=3D lock_offs_max) || (offs_max <=3D lock_offs); } =20 -static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len,= u8 sr) +static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len,= const u8 *sr) { return spi_nor_check_lock_status_sr(nor, ofs, len, sr, true); } =20 static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, u64 le= n, - u8 sr) + const u8 *sr) { return spi_nor_check_lock_status_sr(nor, ofs, len, sr, false); } @@ -158,7 +158,8 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor,= loff_t ofs, u64 len, static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len) { u64 min_prot_len; - int ret, status_old, status_new; + int ret; + u8 status_old[1] =3D {}, status_new[1] =3D {}; u8 mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); u8 pow, val; @@ -170,7 +171,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) if (ret) return ret; =20 - status_old =3D nor->bouncebuf[0]; + status_old[0] =3D nor->bouncebuf[0]; =20 /* If nothing in our range is unlocked, we don't need to do anything */ if (spi_nor_is_locked_sr(nor, ofs, len, status_old)) @@ -215,7 +216,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) return -EINVAL; } =20 - status_new =3D (status_old & ~mask & ~tb_mask) | val; + status_new[0] =3D (status_old[0] & ~mask & ~tb_mask) | val; =20 /* * Disallow further writes if WP# pin is neither left floating nor @@ -223,20 +224,20 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_= t ofs, u64 len) * WP# pin hard strapped to GND can be a valid use case. */ if (!(nor->flags & SNOR_F_NO_WP)) - status_new |=3D SR_SRWD; + status_new[0] |=3D SR_SRWD; =20 if (!use_top) - status_new |=3D tb_mask; + status_new[0] |=3D tb_mask; =20 /* Don't bother if they're the same */ - if (status_new =3D=3D status_old) + if (status_new[0] =3D=3D status_old[0]) return 0; =20 /* Only modify protection if it will not unlock other areas */ - if ((status_new & mask) < (status_old & mask)) + if ((status_new[0] & mask) < (status_old[0] & mask)) return -EINVAL; =20 - return spi_nor_write_sr_and_check(nor, status_new); + return spi_nor_write_sr_and_check(nor, status_new[0]); } =20 /* @@ -247,7 +248,8 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len) { u64 min_prot_len; - int ret, status_old, status_new; + int ret; + u8 status_old[1], status_new[1]; u8 mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); u8 pow, val; @@ -259,7 +261,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_= t ofs, u64 len) if (ret) return ret; =20 - status_old =3D nor->bouncebuf[0]; + status_old[0] =3D nor->bouncebuf[0]; =20 /* If nothing in our range is locked, we don't need to do anything */ if (spi_nor_is_unlocked_sr(nor, ofs, len, status_old)) @@ -308,24 +310,24 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, lof= f_t ofs, u64 len) return -EINVAL; } =20 - status_new =3D (status_old & ~mask & ~tb_mask) | val; + status_new[0] =3D (status_old[0] & ~mask & ~tb_mask) | val; =20 /* Don't protect status register if we're fully unlocked */ if (lock_len =3D=3D 0) - status_new &=3D ~SR_SRWD; + status_new[0] &=3D ~SR_SRWD; =20 if (!use_top) - status_new |=3D tb_mask; + status_new[0] |=3D tb_mask; =20 /* Don't bother if they're the same */ - if (status_new =3D=3D status_old) + if (status_new[0] =3D=3D status_old[0]) return 0; =20 /* Only modify protection if it will not lock other areas */ - if ((status_new & mask) > (status_old & mask)) + if ((status_new[0] & mask) > (status_old[0] & mask)) return -EINVAL; =20 - return spi_nor_write_sr_and_check(nor, status_new); + return spi_nor_write_sr_and_check(nor, status_new[0]); } =20 /* @@ -343,7 +345,7 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, lo= ff_t ofs, u64 len) if (ret) return ret; =20 - return spi_nor_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]); + return spi_nor_is_locked_sr(nor, ofs, len, nor->bouncebuf); } =20 /* --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 4DB6A3D523F for ; Fri, 3 Apr 2026 16:10:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232604; cv=none; b=tDX404/nGlLP7QiQ6cnxNOQfk+lWp0+o5n0fkAQ26BLV2hje5dziAwNMCQRpmhb4fzFCskGOniZE2/p928xyDfS1DH0ZtaC1uyWfBNv95OZgBGf5FvO9Jeda0cqJXTz+XIrVCfI+OaplpnEvhNQ8PdNeL4n/R/7UZsNNRUTR/Tg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232604; c=relaxed/simple; bh=JdvNDxMGwnOySNlrLuQEPmtA+nOczOk0+21rq6zX8LM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sApBoexwqiBcM8CUenRcehRz+v3J0g4xGrolIaG8tK6dD5IPKqBz5gUBk8KYT0LSrVKNv2Mys3N+l1HZIhA3OXduykSYlIgGm9XY/Q0Znxvs7pC5srHUecGE2VWcCioY409AyEfs1w4VEseVVjUK/M8yk8O/gaaUJyAlvj750v0= 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=xT/WFOe3; arc=none smtp.client-ip=185.171.202.116 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="xT/WFOe3" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 99ABAC59F66; Fri, 3 Apr 2026 16:10:32 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9D860603C1; Fri, 3 Apr 2026 16:10:00 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9157610450106; Fri, 3 Apr 2026 18:09:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232599; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=/AjRw+s7RE2lXtZjyitxYQ9NqjIQGCFOfS5T/3HA2Ck=; b=xT/WFOe3l8zZQDPt/91FNOSFmxTy9zE138aqQnyeziRT4BScLjL2og9sQQwT6tG7naD1Sc t5VUHMCfjdQmaqG6mcZhvOFO61A5t/TGghstbiIj+komOyd3PNnMvh3Puv1lBxDj/Z9k3q vciH/9UdrgbTMkkeVCnJ/beZNxX/DcFTA5h9AUFLZzLIIZ09bk53hJtkh3/1SYA2/NhNoa wRO8hbVsOJewYHHHfdhbVXwjm+dEUoX0wx/m6GCpR0/n/AdNuR3up9F+En107CwlvUH+bb HDgStTNFsN9/yQfEy1uDyS9yDN0df+zXmPFcDBk9jxkl9gLG3Se6Af/9pxZ6FA== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:28 +0200 Subject: [PATCH v4 10/27] mtd: spi-nor: swp: Create a helper that writes SR, CR and checks 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-10-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 There are many helpers already to either read and/or write SR and/or CR, as well as sometimes check the returned values. In order to be able to switch from a 1 byte status register to a 2 bytes status register while keeping the same level of verification, let's introduce a new helper that writes them both (atomically) and then reads them back (separated) to compare the values. In case 2 bytes registers are not supported, we still have the usual fallback available in the helper being exported to the rest of the core. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 65 ++++++++++++++++++++++++++++++++++++++++++= ++++ drivers/mtd/spi-nor/core.h | 1 + 2 files changed, 66 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 1eee519c01e5..f007bd6b389a 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -976,6 +976,54 @@ int spi_nor_write_16bit_cr_and_check(struct spi_nor *n= or, u8 cr) return 0; } =20 +/** + * spi_nor_write_16bit_sr_cr_and_check() - Write the Status Register 1 and= the + * Configuration Register in one shot. Ensure that the bytes written in bo= th + * registers match the received value. + * @nor: pointer to a 'struct spi_nor'. + * @regs: two-byte array with values to be written to the status and + * configuration registers. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_write_16bit_sr_cr_and_check(struct spi_nor *nor, const = u8 *regs) +{ + u8 written_regs[2]; + int ret; + + written_regs[0] =3D regs[0]; + written_regs[1] =3D regs[1]; + nor->bouncebuf[0] =3D regs[0]; + nor->bouncebuf[1] =3D regs[1]; + + ret =3D spi_nor_write_sr(nor, nor->bouncebuf, 2); + if (ret) + return ret; + + ret =3D spi_nor_read_sr(nor, &nor->bouncebuf[0]); + if (ret) + return ret; + + if (written_regs[0] !=3D nor->bouncebuf[0]) { + dev_dbg(nor->dev, "SR: Read back test failed\n"); + return -EIO; + } + + if (nor->flags & SNOR_F_NO_READ_CR) + return 0; + + ret =3D spi_nor_read_cr(nor, &nor->bouncebuf[1]); + if (ret) + return ret; + + if (written_regs[1] !=3D nor->bouncebuf[1]) { + dev_dbg(nor->dev, "CR: read back test failed\n"); + return -EIO; + } + + return 0; +} + /** * spi_nor_write_sr_and_check() - Write the Status Register 1 and ensure t= hat * the byte written match the received value without affecting other bits = in the @@ -993,6 +1041,23 @@ int spi_nor_write_sr_and_check(struct spi_nor *nor, u= 8 sr1) return spi_nor_write_sr1_and_check(nor, sr1); } =20 +/** + * spi_nor_write_sr_cr_and_check() - Write the Status Register 1 and ensur= e that + * the byte written match the received value. Same for the Control Registe= r if + * available. + * @nor: pointer to a 'struct spi_nor'. + * @regs: byte array to be written to the registers. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_sr_cr_and_check(struct spi_nor *nor, const u8 *regs) +{ + if (nor->flags & SNOR_F_HAS_16BIT_SR) + return spi_nor_write_16bit_sr_cr_and_check(nor, regs); + + return spi_nor_write_sr1_and_check(nor, regs[0]); +} + /** * spi_nor_write_sr2() - Write the Status Register 2 using the * SPINOR_OP_WRSR2 (3eh) command. diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 16b382d4f04f..3dc9ba3bc6da 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -632,6 +632,7 @@ int spi_nor_read_cr(struct spi_nor *nor, u8 *cr); int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len); int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1); int spi_nor_write_16bit_cr_and_check(struct spi_nor *nor, u8 cr); +int spi_nor_write_sr_cr_and_check(struct spi_nor *nor, const u8 *regs); =20 ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf); --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 831D03D5251 for ; Fri, 3 Apr 2026 16:10:05 +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=1775232606; cv=none; b=sQRbcHfYiasWfeqsPMxhqO4Z/A0e+Equ2Bp+9SfSiDFjPjGrz/02N0wpMLguFT4IZs84MnjB5sg0PahUFbea6D+13SZUIGk+xl1TyYlH6BjhCbCmFfhrI1RhCU4CwOrsn3akWGoPv6n3Cet1CTCn6OF2mt/ClsH1pj6OR8eCj6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232606; c=relaxed/simple; bh=Y83KYn/IVlv0CuC1jWDIk1uUyPw9VZxig3d2hhCSWLk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dxODHTUTIN+9HUdyqpxhOfjr7JmGwpJSA+tv0OISHedCHi8KLwe0+kGHoEWhimunMHH0EsduyJ/KCLMLmCkPdG8aBVG/H2a6PR4pQLhDACQL57R8ZL2P0kdT10/zBpPbAshUKIwYLLndb4dbRmTiWeMiFa8oYs1mbeFuDpJTfpw= 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=fX0TW3G+; 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="fX0TW3G+" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 092911A312B; Fri, 3 Apr 2026 16:10:04 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id CC75B603C1; Fri, 3 Apr 2026 16:10:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3796A104500FB; Fri, 3 Apr 2026 18:10:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232602; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=8PfJAvOeYuhH5dbaDKJSTXCqDQ9KrVUp5a2zaIJVtqQ=; b=fX0TW3G+QCtp4oSRisM4uUPTCgxO0PWqGemlRIr5nkFNOHaoSzkduz4HpALyNhrYLSq8/F kGdMa5s3r718SBxAkzFC/oda64BcExkVZ4ZZGV2f7IZLyesthcuL2kXtBQnW1R0UccIlf0 slDX60Mz/1xNX6zErIDZnwBmC8Y01TPWCDH/JZ/uHHAaw5glgP918C7Rk6WHQHzjv/Oblj LJI4abbCNTT4UKd7Jyte5s8C2jbD8q8IeVkzjwLaDT5wP4aJMfRHDqF6MxzzB2DiIyuuPL RO8y4kgbaw4xBzGXVohvHl83fX3AdLQ0FUgHy7QRpmFOxyu/Y04Sh1/koj3bHQ== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:29 +0200 Subject: [PATCH v4 11/27] mtd: spi-nor: swp: Rename a mask 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-11-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 "mask" is not very descriptive when we already manipulate two masks, and soon will manipulate three. Rename it "bp_mask" to align with the existing "tb_mask" and soon "cmp_mask". Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index af6e577d9b42..66f85826ba0d 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -57,9 +57,9 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *n= or, const u8 *sr, loff_ u64 *len) { u64 min_prot_len; - u8 mask =3D spi_nor_get_sr_bp_mask(nor); + u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); - u8 bp, val =3D sr[0] & mask; + u8 bp, val =3D sr[0] & bp_mask; =20 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3_BIT6) val =3D (val & ~SR_BP3_BIT6) | SR_BP3; @@ -160,7 +160,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) u64 min_prot_len; int ret; u8 status_old[1] =3D {}, status_new[1] =3D {}; - u8 mask =3D spi_nor_get_sr_bp_mask(nor); + u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); u8 pow, val; loff_t lock_len; @@ -199,7 +199,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) lock_len =3D ofs + len; =20 if (lock_len =3D=3D nor->params->size) { - val =3D mask; + val =3D bp_mask; } else { min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); pow =3D ilog2(lock_len) - ilog2(min_prot_len) + 1; @@ -208,15 +208,15 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_= t ofs, u64 len) if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3) val =3D (val & ~SR_BP3) | SR_BP3_BIT6; =20 - if (val & ~mask) + if (val & ~bp_mask) return -EINVAL; =20 /* Don't "lock" with no region! */ - if (!(val & mask)) + if (!(val & bp_mask)) return -EINVAL; } =20 - status_new[0] =3D (status_old[0] & ~mask & ~tb_mask) | val; + status_new[0] =3D (status_old[0] & ~bp_mask & ~tb_mask) | val; =20 /* * Disallow further writes if WP# pin is neither left floating nor @@ -234,7 +234,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) return 0; =20 /* Only modify protection if it will not unlock other areas */ - if ((status_new[0] & mask) < (status_old[0] & mask)) + if ((status_new[0] & bp_mask) < (status_old[0] & bp_mask)) return -EINVAL; =20 return spi_nor_write_sr_and_check(nor, status_new[0]); @@ -250,7 +250,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_= t ofs, u64 len) u64 min_prot_len; int ret; u8 status_old[1], status_new[1]; - u8 mask =3D spi_nor_get_sr_bp_mask(nor); + u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); u8 pow, val; loff_t lock_len; @@ -306,11 +306,11 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, lof= f_t ofs, u64 len) val =3D (val & ~SR_BP3) | SR_BP3_BIT6; =20 /* Some power-of-two sizes may not be supported */ - if (val & ~mask) + if (val & ~bp_mask) return -EINVAL; } =20 - status_new[0] =3D (status_old[0] & ~mask & ~tb_mask) | val; + status_new[0] =3D (status_old[0] & ~bp_mask & ~tb_mask) | val; =20 /* Don't protect status register if we're fully unlocked */ if (lock_len =3D=3D 0) @@ -324,7 +324,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_= t ofs, u64 len) return 0; =20 /* Only modify protection if it will not lock other areas */ - if ((status_new[0] & mask) > (status_old[0] & mask)) + if ((status_new[0] & bp_mask) > (status_old[0] & bp_mask)) return -EINVAL; =20 return spi_nor_write_sr_and_check(nor, status_new[0]); --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 B088F3CFF45 for ; Fri, 3 Apr 2026 16:10:06 +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=1775232607; cv=none; b=X+INe/GV8/dmeSb9JFEcZDw4fWwwDU/Gg/YzZfSFsDk0QcbdR2FhpU0AvOGfwrycmjLWNx5nUBhlY7/OmyGAtYAxxeeOPnUBUmziYQtVXgMiBiz/LZ5NaBjZoMbHyDcTmdUp6UMkMm2NeTeVXrdbAc/6fSuTrJzN4pJXXu3JPr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232607; c=relaxed/simple; bh=+rienJCiJ/b99Px67gdPRlY+7XR/5LML7t7ieMvxoSE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HhgX0zQJHpTb2kamOwjwUY0Yk0o9KNrvnD77kDxHPcTdYyD9MtM/9v8Xd313qV+AVyZXUpURkDlMYriPIpxjn+Us9GIC8CnTq7kuDlgtmhFtp3V3Hs/dq4XCbF6C3XZ1fApD8oxrQEorLNr2jiorcauRbu69BH6xyQDtMGp3ggI= 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=Zoq8ydzG; 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="Zoq8ydzG" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 7AF501A312E; Fri, 3 Apr 2026 16:10:05 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 505D4603C1; Fri, 3 Apr 2026 16:10:05 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B3AB6104500FA; Fri, 3 Apr 2026 18:10:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232604; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=AtDuaW75HQVabGFbw4yfNgUHQh/r6FDMUHlhTNsHi9I=; b=Zoq8ydzGBO39ExDCZ4mO6pVU+QgDyeIx0qjTXWxWK3D7poKE2FUu9uQ63FFSQYkY42EVTn zM80Sd31Wq32YLiI+d/YIKkyHnuDNaLB4b4tPT2y54KrKrOFbh0t/RXOMY0H47VzLI1S+J EZNRLBnyT9liXdhn8bVrqEKHSL55QDR58LH49P1AMt/KqlTlfLBVcJAQQdjgs1ygPYbsin zk1QxZEdseEt6hUGyKdD5PeFFime4UJ/wi7Dp6RON5wbYbZv880pLcAOpQXli2RXwHwtPe pX/DVuVO8d4uPqAy3edNaDAZAWC+xlOBT53S2tLmHjRm1hyLtx2TwQdZ2faePQ== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:30 +0200 Subject: [PATCH v4 12/27] mtd: spi-nor: swp: Create a TB intermediate variable 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-12-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 Ease the future reuse of the tb (Top/Bottom) boolean by creating an intermediate variable. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 66f85826ba0d..f068cb9c8f6d 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -60,6 +60,7 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *n= or, const u8 *sr, loff_ u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); u8 bp, val =3D sr[0] & bp_mask; + bool tb =3D (nor->flags & SNOR_F_HAS_SR_TB) ? sr[0] & tb_mask : 0; =20 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3_BIT6) val =3D (val & ~SR_BP3_BIT6) | SR_BP3; @@ -79,7 +80,7 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *n= or, const u8 *sr, loff_ if (*len > nor->params->size) *len =3D nor->params->size; =20 - if (nor->flags & SNOR_F_HAS_SR_TB && sr[0] & tb_mask) + if (tb) *ofs =3D 0; else *ofs =3D nor->params->size - *len; --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 DB7513CFF7D for ; Fri, 3 Apr 2026 16:10:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232611; cv=none; b=g8pl3FWPxvFDZDSw0UMl/7xz5wuTGoEF3gLifxJYDsfBnidDvKBu2M0uj0axTNbWUGIo172siggG+uwsx5n+6HGPFkHaArubzGEMB3Jejaw/t56YMMkY5vp346dXyVdi9wPy1ZFJRp4btkQhzMSgCzxIAMVoYS9G1HMCaPN2mVI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232611; c=relaxed/simple; bh=wJlFUDPAi6ogepYsFHibAA47a35dOGAAG0yfdvRFbzw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IF+AoX9zGPss+witc3GWncn+9D0rAjsSpoiNKshVKii7lxVUwKM4JyKbN+GMU2VZcEv9PJ7+A9hwiud166Vr2O5Dyu0hK0txTltnOS6eQja8rCQCot3NK6Zb1tFGf5OCsTbJrMmOpAC604ZPqrxC8CM9Is6CxIXg0Rr8f8po4I4= 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=LUXasgoY; arc=none smtp.client-ip=185.246.85.4 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="LUXasgoY" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id B6CC34E428D7; Fri, 3 Apr 2026 16:10:08 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8BF11603C1; Fri, 3 Apr 2026 16:10:08 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EE5CA104500F6; Fri, 3 Apr 2026 18:10:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232607; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xzSy+EhNI9t9zTqMF1NixCi1hFBNiZkvrrCmxjn6Qww=; b=LUXasgoYgUxnSYaqKpNjymZ/Qvv340Urc9Z5AxflgEzL0mlHnOmx6ujlAOqq8HMTe4RnKl SqWLHFfhrDHx0Jp89i1tlZ52r2t5gkEnWBCJ/HR6dAZailfXtM/CXeibU+TJz/xNvDFmuP tBJthi+c4CQUWGOyXv9KKXt8PEQ6G/OFY5niqOnyn3bGp3JFoLke9oQprxN8WA9auU1M34 aa077vkc3vZVDiBF22ZZH9Db51bP0uqyS3sA3+L/Hj910K6OlS4zRwaNfMgpmDdd2ZS0nt CAr7ryl50sDv8YyimqmbKU8MARmDz0mnrHk0ZFHeWxgC/LSo87ber6jHXSw2ag== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:31 +0200 Subject: [PATCH v4 13/27] mtd: spi-nor: swp: Create helpers for building the SR register 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-13-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 The status register contains 3 or 4 BP (Block Protect) bits, 0 or 1 TB (Top/Bottom) bit, soon 0 or 1 CMP (Complement) bit. The last BP bit and the TB bit locations change between vendors. The whole logic of buildling the content of the status register based on some input conditions is used two times and soon will be used 4 times. Create dedicated helpers for these steps. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 83 +++++++++++++++++++++++++++++--------------= ---- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index f068cb9c8f6d..e2e423b20989 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -123,6 +123,43 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor= , loff_t ofs, u64 len, return spi_nor_check_lock_status_sr(nor, ofs, len, sr, false); } =20 +static int spi_nor_sr_set_bp_mask(struct spi_nor *nor, u8 *sr, u8 pow) +{ + u8 mask =3D spi_nor_get_sr_bp_mask(nor); + u8 val =3D pow << SR_BP_SHIFT; + + if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3) + val =3D (val & ~SR_BP3) | SR_BP3_BIT6; + + if (val & ~mask) + return -EINVAL; + + sr[0] =3D val; + + return 0; +} + +static int spi_nor_build_sr(struct spi_nor *nor, const u8 *old_sr, u8 *new= _sr, + u8 pow, bool use_top) +{ + u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); + u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); + int ret; + + new_sr[0] =3D old_sr[0] & ~bp_mask & ~tb_mask; + + /* Build BP field */ + ret =3D spi_nor_sr_set_bp_mask(nor, &new_sr[0], pow); + if (ret) + return ret; + + /* Build TB field */ + if (!use_top) + new_sr[0] |=3D tb_mask; + + return 0; +} + /* * 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 @@ -162,11 +199,10 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_= t ofs, u64 len) int ret; u8 status_old[1] =3D {}, status_new[1] =3D {}; u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); - u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); - u8 pow, val; loff_t lock_len; bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB; bool use_top; + u8 pow; =20 ret =3D spi_nor_read_sr(nor, nor->bouncebuf); if (ret) @@ -200,24 +236,19 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_= t ofs, u64 len) lock_len =3D ofs + len; =20 if (lock_len =3D=3D nor->params->size) { - val =3D bp_mask; + pow =3D (nor->flags & SNOR_F_HAS_4BIT_BP) ? GENMASK(3, 0) : GENMASK(2, 0= ); } else { min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); pow =3D ilog2(lock_len) - ilog2(min_prot_len) + 1; - val =3D pow << SR_BP_SHIFT; - - if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3) - val =3D (val & ~SR_BP3) | SR_BP3_BIT6; - - if (val & ~bp_mask) - return -EINVAL; - - /* Don't "lock" with no region! */ - if (!(val & bp_mask)) - return -EINVAL; } =20 - status_new[0] =3D (status_old[0] & ~bp_mask & ~tb_mask) | val; + ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top); + if (ret) + return ret; + + /* Don't "lock" with no region! */ + if (!(status_new[0] & bp_mask)) + return -EINVAL; =20 /* * Disallow further writes if WP# pin is neither left floating nor @@ -227,9 +258,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) if (!(nor->flags & SNOR_F_NO_WP)) status_new[0] |=3D SR_SRWD; =20 - if (!use_top) - status_new[0] |=3D tb_mask; - /* Don't bother if they're the same */ if (status_new[0] =3D=3D status_old[0]) return 0; @@ -252,11 +280,10 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, lof= f_t ofs, u64 len) int ret; u8 status_old[1], status_new[1]; u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); - u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); - u8 pow, val; loff_t lock_len; bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB; bool use_top; + u8 pow; =20 ret =3D spi_nor_read_sr(nor, nor->bouncebuf); if (ret) @@ -297,29 +324,21 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, lof= f_t ofs, u64 len) lock_len =3D ofs; =20 if (lock_len =3D=3D 0) { - val =3D 0; /* fully unlocked */ + pow =3D 0; /* fully unlocked */ } else { min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); pow =3D ilog2(lock_len) - ilog2(min_prot_len) + 1; - val =3D pow << SR_BP_SHIFT; =20 - if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3) - val =3D (val & ~SR_BP3) | SR_BP3_BIT6; - - /* Some power-of-two sizes may not be supported */ - if (val & ~bp_mask) - return -EINVAL; } =20 - status_new[0] =3D (status_old[0] & ~bp_mask & ~tb_mask) | val; + ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top); + if (ret) + return ret; =20 /* Don't protect status register if we're fully unlocked */ if (lock_len =3D=3D 0) status_new[0] &=3D ~SR_SRWD; =20 - if (!use_top) - status_new[0] |=3D tb_mask; - /* Don't bother if they're the same */ if (status_new[0] =3D=3D status_old[0]) return 0; --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 A53523D75BD for ; Fri, 3 Apr 2026 16:10:12 +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=1775232614; cv=none; b=ZRc2bj+pyiP7BR9smce9HSeB+D83CjuMHM4L07fN84ERILWysvGnvuWIDi97TyIoE+eQ4Q0PLCzzGdeEf7fRT5IrjCJkz8ghGchFILrpvIgMxzbFg9m04nH3pV8c3cYVpHdPV1B8Zf8wvpTsQUpXRz/PNiAgPhAUPIQqGSL5krc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232614; c=relaxed/simple; bh=2EFf5xOFrTZzA3C6TJkuzrE465Ubjd3W8p3pWLusQN4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pXF2cq2ZHBv+EprLDXoL0sZoyvPMU6ExJDoAF2jLWejngUEneRudNi5TNTD9ie3+LhjlotqaWRSyJkpYM5fbEyeKt7nUk8yULUPoTXYiv8hySXj0nOo5sqOVXu0sZUqCgU2W1aa/oAp2/KVrBwZ645Z7XlstGYiNnMqMkH5utx4= 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=POaCsvSW; 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="POaCsvSW" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 6ABC31A312B; Fri, 3 Apr 2026 16:10:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3FBD3603C1; Fri, 3 Apr 2026 16:10:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3F13010450102; Fri, 3 Apr 2026 18:10:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232610; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=myF1jFvrCgWbnH0NLIBXbT8w17K7kgr7HnwXrOW3SAM=; b=POaCsvSWv8pvL4ZxIPvr/kU4sumw6OyoWfrbwOe2J6TLuAhC7PwCME9zGOGgU4i0L+K5Lk hZGbjToX16mDPh9uU4OC230WtiySEsFuDRMLn/o1jAZSGJI13DL2oszZJkrsU2/VBEkaK5 Xp2+He6lV21tLxJlBGh5y4CXDQ7vQ4qdDsrj3e0h22MyxToVnxm2oD2t8rRtFLWFYeXKBo 3lSgc5KNJTfsVEl1OL/Z+L07d+ATfu/KayA8SiP3Ez6SY6yR9sPAK/PQbzJCoyPH+3ZBc2 IaNnxR3HGT+yg/JilhioanY+yf1/kTtCOM77/hHFhcVfQdSWVJiLxCmXB359Bg== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:32 +0200 Subject: [PATCH v4 14/27] mtd: spi-nor: swp: Simplify checking the locked/unlocked range 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-14-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 both the locking/unlocking steps, at the end we verify whether we do not lock/unlock more than requested (in which case an error must be returned). While being possible to do that with very simple mask comparisons, it does not scale when adding extra locking features such as the CMP possibility. In order to make these checks slightly easier to read and more future proof, use existing helpers to read the (future) status register, extract the covered range, and compare it with very usual algebric comparisons. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index e2e423b20989..c45a9ddd5788 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -198,7 +198,8 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) u64 min_prot_len; int ret; u8 status_old[1] =3D {}, status_new[1] =3D {}; - u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); + loff_t ofs_old, ofs_new; + u64 len_old, len_new; loff_t lock_len; bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB; bool use_top; @@ -246,10 +247,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t= ofs, u64 len) if (ret) return ret; =20 - /* Don't "lock" with no region! */ - if (!(status_new[0] & bp_mask)) - return -EINVAL; - /* * Disallow further writes if WP# pin is neither left floating nor * wrongly tied to GND (that includes internal pull-downs). @@ -262,8 +259,16 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t= ofs, u64 len) if (status_new[0] =3D=3D status_old[0]) return 0; =20 + spi_nor_get_locked_range_sr(nor, status_old, &ofs_old, &len_old); + spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + + /* Don't "lock" with no region! */ + if (!len_new) + return -EINVAL; + /* Only modify protection if it will not unlock other areas */ - if ((status_new[0] & bp_mask) < (status_old[0] & bp_mask)) + if (len_old && + (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]); @@ -279,7 +284,8 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_= t ofs, u64 len) u64 min_prot_len; int ret; u8 status_old[1], status_new[1]; - u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); + loff_t ofs_old, ofs_new; + u64 len_old, len_new; loff_t lock_len; bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB; bool use_top; @@ -344,7 +350,10 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff= _t ofs, u64 len) return 0; =20 /* Only modify protection if it will not lock other areas */ - if ((status_new[0] & bp_mask) > (status_old[0] & bp_mask)) + spi_nor_get_locked_range_sr(nor, status_old, &ofs_old, &len_old); + spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + if (len_old && len_new && + (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]); --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 B37D73D7D66 for ; Fri, 3 Apr 2026 16:10:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232616; cv=none; b=oziUvAF2727N2bViAoYi2mnzw9Igh5ogJLh4ylvOybCiY+1IfwWqrPLQCFzB+THCdC36OdWoGHnSWzwEsELAZUgDGKgnxVbBmLsvcoCafH2kBzsFN6qUMQZIfvLGeW41MdaMbiv0bCFTQtqMPQM5/EjGqqh4S50OblYKMvaVMGI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232616; c=relaxed/simple; bh=3W4mxwLiGIBZA6m3fADY2ZRcO48cfQ+97KUwrdQ6Sqs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FWxTxXWG10QNlMWFg8CY/HUALadzHUvs1JpCaasWzVFZ03pCWAZMKY7NgzeWW4fViG1kjhIUls+k1DAJz3en82Mo5/RSBxvzAvlr+xjBLwlD5D1LARsYrusU+wT0Uv76MFokO+Pvge2TUuV/rCNbP189NXq1cY2U5ULY036ABGM= 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=eDOTYLgi; arc=none smtp.client-ip=185.246.85.4 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="eDOTYLgi" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 7BE204E428D6; Fri, 3 Apr 2026 16:10:13 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 531D2603C1; Fri, 3 Apr 2026 16:10:13 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DF6DF10450103; Fri, 3 Apr 2026 18:10:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232612; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xR38gyrQC5XhhjYq85zVZxA7ePkj9xFcfqojI3JaBuI=; b=eDOTYLgib43BSK2VON0gYT0KXJz2WSOkmHGSSDQ2r/2MGo3XMbch10FjMtO65399sOrHM7 z6hPRz67qFQ85k+pkDOBtC1NCUugEtFbRdafrXG7y8IKefi7tsbO639VCKeecvfxQwJJ0Y k2ZkadLgedtepXWbg6YQO3gqvyWbfmZ/k2hVMjmNwcYzorQhxcVIvgQ5bSpxq4knllLkbF 9nBQRO1KbIzuG5Jn3kXK1PAnaAVxSf4lDKmr1kUoacBQYFLHtIjsa9fMZwop7PYyNG1PMq GI4f88DJfELXfxthQOOtfH18boC62941FnPXsRwcEp2Y7//ZAR4oJ26vblMSug== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:33 +0200 Subject: [PATCH v4 15/27] mtd: spi-nor: swp: Cosmetic changes 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-15-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 As a final preparation step for the introduction of CMP support, make a few more cosmetic changes to simplify the reading of the diff when adding the CMP feature. In particular, define "min_prot_len" earlier as it will be reused and move the definition of the "ret" variable at the end of the stack just because it looks better. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/swp.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index c45a9ddd5788..c3dbc8832025 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -195,14 +195,14 @@ static int spi_nor_build_sr(struct spi_nor *nor, cons= t u8 *old_sr, u8 *new_sr, */ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len) { - u64 min_prot_len; - int ret; + u64 min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); u8 status_old[1] =3D {}, status_new[1] =3D {}; loff_t ofs_old, ofs_new; u64 len_old, len_new; loff_t lock_len; bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB; bool use_top; + int ret; u8 pow; =20 ret =3D spi_nor_read_sr(nor, nor->bouncebuf); @@ -236,12 +236,10 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_= t ofs, u64 len) else lock_len =3D ofs + len; =20 - if (lock_len =3D=3D nor->params->size) { + if (lock_len =3D=3D nor->params->size) pow =3D (nor->flags & SNOR_F_HAS_4BIT_BP) ? GENMASK(3, 0) : GENMASK(2, 0= ); - } else { - min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); + else pow =3D ilog2(lock_len) - ilog2(min_prot_len) + 1; - } =20 ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top); if (ret) @@ -281,7 +279,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t = ofs, u64 len) */ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len) { - u64 min_prot_len; + u64 min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); int ret; u8 status_old[1], status_new[1]; loff_t ofs_old, ofs_new; @@ -329,14 +327,11 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, lof= f_t ofs, u64 len) else lock_len =3D ofs; =20 - if (lock_len =3D=3D 0) { + if (lock_len =3D=3D 0) pow =3D 0; /* fully unlocked */ - } else { - min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); + else pow =3D ilog2(lock_len) - ilog2(min_prot_len) + 1; =20 - } - ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top); if (ret) return ret; --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 4254A3D810E for ; Fri, 3 Apr 2026 16:10:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232620; cv=none; b=TmVcUlIpSS/71p0C74d5wG7S2Quu3rTg3p9+PT9Ny73nz/lRFaS8cdfvSa81P6mqSK6qttCLpZXgp5Xv64Uh/Tt/OeIinFlxnEWe+DiEOwBQr8/FCWdKx4I54squJ5q+soHkFCmZefrQzDG4XFi2rioXhm3xF8LddVazyt6/C4o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232620; c=relaxed/simple; bh=fnjrpXv34Zf28iqWHPQAjRfAv8pogayjSG2Scu/b18M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jsgYdBgOCt0uR+ZhxpahMddriOew09+SulC8fAg4XdMh8WjW03ZP6OwJzY1NPNDWucRrJuZ3qgOIpiw22pW/SNHfcaWZYSar2zHvS3rlLBKgW9DwlDVabEcuftaYThALq1HVAJhIwTJI4ucxIeOTcf+1s8k/6EMPXwDfUGm0duo= 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=zMM4hbm8; arc=none smtp.client-ip=185.246.85.4 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="zMM4hbm8" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 254484E428D7; Fri, 3 Apr 2026 16:10:18 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EF749603C1; Fri, 3 Apr 2026 16:10:17 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 32B7810450109; Fri, 3 Apr 2026 18:10:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232617; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=BTfD2i7QceyxCGKPOQo667FcG7sbtAJLIKE74Vn9+eQ=; b=zMM4hbm8g/TT9sNB1p3va8+BxJfTg1OaTe1CGq8hJU9ZRigsEF50tT2TfUkv3KR1W9iyrD OkZVDbn5wIwynP9CQ1T9Nd9SJhhVbHESsr/yKFODj+ra+TcmaANGueyK6roJJslB8j6p4c E0ZNs9cPGf5ajeQrGUd0ixX4oPaDOgYy71+c9afkcbc/00JRUJu/ydStcK/ni+6K+z5VDr RPj/FwXYYjPuOdrBvh/42v8OlUoyE2mqHim8aCkK1B5Q8eqwrI7JBR4YfnmRk/cstbrnNW HYL+d3SJqJy33GV+/xf/o8loSFlvFOM+AYI/Kfi1rBxEy03Ajs3FnUWxZkwEqA== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:35 +0200 Subject: [PATCH v4 17/27] mtd: spi-nor: debugfs: Add locking support 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-17-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 The ioctl output may be counter intuitive in some cases. Asking for a "locked status" over a region that is only partially locked will return "unlocked" whereas in practice maybe the biggest part is actually locked. Knowing what is the real software locking state through debugfs would be very convenient for development/debugging purposes, hence this proposal for adding an extra block at the end of the file: a "locked sectors" array which lists every section, if it is locked or not, showing both the address ranges and the sizes in numbers of blocks. Here is an example of output, what is after the "sector map" is new. $ cat /sys/kernel/debug/spi-nor/spi0.0/params name (null) id ef a0 20 00 00 00 size 64.0 MiB write size 1 page size 256 address nbytes 4 flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_16BIT_SR | HAS_S= R_TB_BIT6 | HAS_4BIT_BP | SOFT_RESET | NO_WP opcodes read 0xec dummy cycles 6 erase 0xdc program 0x34 8D extension none protocols read 1S-4S-4S write 1S-1S-4S register 1S-1S-1S erase commands 21 (4.00 KiB) [1] dc (64.0 KiB) [3] c7 (64.0 MiB) sector map region (in hex) | erase mask | overlaid ------------------+------------+--------- 00000000-03ffffff | [ 3] | no locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03ffffff | unlocked | 1024 Signed-off-by: Miquel Raynal --- Here are below more examples of output with various situations. The full output of the "params" content has been manually removed to only show what has been added and how it behaves. $ flash_lock -l /dev/mtd0 0x3f00000 16 $ cat /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03efffff | unlocked | 1008 03f00000-03ffffff | locked | 16 $ $ flash_lock -u /dev/mtd0 0x3f00000 8 $ cat /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03f7ffff | unlocked | 1016 03f80000-03ffffff | locked | 8 $ $ flash_lock -u /dev/mtd0 $ cat /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03ffffff | unlocked | 1024 $ $ flash_lock -l /dev/mtd0 $ cat /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03ffffff | locked | 1024 $ $ flash_lock -u /dev/mtd0 0x20000 1022 $ cat /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0001ffff | locked | 2 00020000-03ffffff | unlocked | 1022 --- drivers/mtd/spi-nor/core.h | 5 +++++ drivers/mtd/spi-nor/debugfs.c | 27 +++++++++++++++++++++++++++ drivers/mtd/spi-nor/swp.c | 16 ++++++++++++---- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 091eb934abe4..8717a0ad90f0 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -673,6 +673,7 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_bfpt *bfpt); =20 void spi_nor_init_default_locking_ops(struct spi_nor *nor); +bool spi_nor_has_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); @@ -707,6 +708,10 @@ static inline bool spi_nor_needs_sfdp(const struct spi= _nor *nor) return !nor->info->size; } =20 +u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor); +void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t= *ofs, u64 *len); +bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const = u8 *sr); + #ifdef CONFIG_DEBUG_FS void spi_nor_debugfs_register(struct spi_nor *nor); void spi_nor_debugfs_shutdown(void); diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index d0191eb9f879..298ce3d9e905 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include +#include #include #include #include @@ -77,10 +78,12 @@ static void spi_nor_print_flags(struct seq_file *s, uns= igned long flags, static int spi_nor_params_show(struct seq_file *s, void *data) { struct spi_nor *nor =3D s->private; + unsigned int min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); struct spi_nor_flash_parameter *params =3D nor->params; struct spi_nor_erase_map *erase_map =3D ¶ms->erase_map; struct spi_nor_erase_region *region =3D erase_map->regions; const struct flash_info *info =3D nor->info; + loff_t lock_start, lock_length; char buf[16], *str; unsigned int i; =20 @@ -159,6 +162,30 @@ static int spi_nor_params_show(struct seq_file *s, voi= d *data) region[i].overlaid ? "yes" : "no"); } =20 + if (!spi_nor_has_default_locking_ops(nor)) + return 0; + + seq_puts(s, "\nlocked sectors\n"); + seq_puts(s, " region (in hex) | status | #blocks\n"); + seq_puts(s, " ------------------+----------+--------\n"); + + spi_nor_get_locked_range_sr(nor, nor->dfs_sr_cache, &lock_start, &lock_le= ngth); + if (!lock_length || lock_length =3D=3D params->size) { + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, params->size - 1, + lock_length ? " locked" : "unlocked", + div_u64(params->size, min_prot_len)); + } else if (!lock_start) { + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_length - 1, + " locked", div_u64(lock_length, min_prot_len)); + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_length, params->size = - 1, + "unlocked", div_u64(params->size - lock_length, min_prot_len)); + } else { + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_start - 1, + "unlocked", div_u64(lock_start, min_prot_len)); + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_start, params->size -= 1, + " locked", div_u64(lock_length, min_prot_len)); + } + return 0; } DEFINE_SHOW_ATTRIBUTE(spi_nor_params); diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 7a6c2b8ef921..d75ed83eb787 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -32,7 +32,7 @@ static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor) return SR_TB_BIT5; } =20 -static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor) +u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor) { unsigned int bp_slots, bp_slots_needed; /* @@ -53,8 +53,8 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor = *nor) return sector_size; } =20 -static void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr,= loff_t *ofs, - u64 *len) +void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t= *ofs, + u64 *len) { u64 min_prot_len; u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); @@ -112,7 +112,7 @@ static bool spi_nor_check_lock_status_sr(struct spi_nor= *nor, loff_t ofs, return (ofs >=3D lock_offs_max) || (offs_max <=3D lock_offs); } =20 -static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len,= const u8 *sr) +bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const = u8 *sr) { return spi_nor_check_lock_status_sr(nor, ofs, len, sr, true); } @@ -410,6 +410,9 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, lo= ff_t ofs, u64 len) * -is_locked(): Checks if the region is *fully* locked, returns false oth= erwise. * This feeback may be misleading because users may get an "= unlocked" * status even though a subpart of the region is effectively= locked. + * + * If in doubt during development, check-out the debugfs output which trie= s to + * be more user friendly. */ static const struct spi_nor_locking_ops spi_nor_sr_locking_ops =3D { .lock =3D spi_nor_sr_lock, @@ -422,6 +425,11 @@ void spi_nor_init_default_locking_ops(struct spi_nor *= nor) nor->params->locking_ops =3D &spi_nor_sr_locking_ops; } =20 +bool spi_nor_has_default_locking_ops(struct spi_nor *nor) +{ + return nor->params->locking_ops =3D=3D &spi_nor_sr_locking_ops; +} + static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, u64 len) { struct spi_nor *nor =3D mtd_to_spi_nor(mtd); --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 14FFF3D811F; Fri, 3 Apr 2026 16:10:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232622; cv=none; b=eqUNCV1am5jxA82QQOZonJud/FV1sJhuEMPbkxkrOdn8bTTa/iylH53RxVK5FmqSFUeTwOFqcv1eWqoPSHUgws2iq3hA/VhvE1l1SZUDoaRHlRicO/1gUlkIVXFhO+VVoozasYsiLSKMn8YURP0M2C3YEXwU07XqxsJej/nR8kU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232622; c=relaxed/simple; bh=pKZ/G6wKEecTeYkFLWZ6DAKqA9csX9Huo8ULTkyXwIA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ul3UB+ULql0nuHCUsy7+C72fUTLIWr+OBTZckX+EQC46zeoFtcqmf8g5wPgXSlQxp5bL5PxAvKj3vjKp+VLfzcRxIMM0+e0SY/Wb1ynJ2IHDKrzvIEM9wW6tBjM7+Ig91xJzBAkcGc15W9RX/n3SjOswe6XliG2Yr4YZm2htojk= 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=d/PELGgm; arc=none smtp.client-ip=185.171.202.116 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="d/PELGgm" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 05088C59F68; Fri, 3 Apr 2026 16:10:52 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 09274603C1; Fri, 3 Apr 2026 16:10:20 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9724A10450106; Fri, 3 Apr 2026 18:10:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232619; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Q9l5x2r5UdhKn08UDwTKQGOl9IC4XLp/x1cNumetPAg=; b=d/PELGgmZKF3PB7LQij5Q9+DHLB+FgmaOfUs+jPBgbW1naHZ6koVNgQ5EUar2il5L0jNFQ GNSP0q88m9YxjDsxGe0hrg9ZdItUAcKiWsZ8ogiK6HWDXgRvYZoB5pv2Hlh5orjegYYbX2 YK5umDAkNRqRiLD76vZyebCWzxaBikuN5rnEFRi80jgjhOy4Mm9uSRIRQbFdEUqr9uTucj QJZAl7KlVA9yEL4yjgX6ZcYQ6R6yjpg8U2XGWmEG+08cWwmuaMrk1f0tJ3yv3SwMcqcRid IKvzZ7hUkMvup0onCUR+y+KhQrJ81q7RJ2KUU9aFIsT/88WJtTK0Ir1yfQQJgQ== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:36 +0200 Subject: [PATCH v4 18/27] mtd: spi-nor: debugfs: Add a locked sectors map 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-18-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 get a very clear view of the sectors being locked, besides the `params` output giving the ranges, we may want to see a proper map of the sectors and for each of them, their status. Depending on the use case, this map may be easier to parse by humans and gives a more acurate feeling of the situation. At least myself, for the few locking-related developments I recently went through, I found it very useful to get a clearer mental model of what was locked/unlocked. Here is an example of output: $ cat /sys/kernel/debug/spi-nor/spi0.0/locked-sectors-map Locked sectors map (x: locked, .: unlocked, unit: 64kiB) 0x00000000 (# 0): ................ ................ ................ ..= .............. 0x00400000 (# 64): ................ ................ ................ ..= .............. 0x00800000 (# 128): ................ ................ ................ ..= .............. 0x00c00000 (# 192): ................ ................ ................ ..= .............. 0x01000000 (# 256): ................ ................ ................ ..= .............. 0x01400000 (# 320): ................ ................ ................ ..= .............. 0x01800000 (# 384): ................ ................ ................ ..= .............. 0x01c00000 (# 448): ................ ................ ................ ..= .............. 0x02000000 (# 512): ................ ................ ................ ..= .............. 0x02400000 (# 576): ................ ................ ................ ..= .............. 0x02800000 (# 640): ................ ................ ................ ..= .............. 0x02c00000 (# 704): ................ ................ ................ ..= .............. 0x03000000 (# 768): ................ ................ ................ ..= .............. 0x03400000 (# 832): ................ ................ ................ ..= .............. 0x03800000 (# 896): ................ ................ ................ ..= .............. 0x03c00000 (# 960): ................ ................ ................ ..= ............xx The output is wrapped at 64 sectors, spaces every 16 sectors are improving the readability, every line starts by the first sector offset (hex) and number (decimal). Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/debugfs.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index 298ce3d9e905..1ed1a0bbef3b 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -190,6 +190,40 @@ static int spi_nor_params_show(struct seq_file *s, voi= d *data) } DEFINE_SHOW_ATTRIBUTE(spi_nor_params); =20 +static int spi_nor_locked_sectors_map_show(struct seq_file *s, void *data) +{ + struct spi_nor *nor =3D s->private; + struct spi_nor_flash_parameter *params =3D nor->params; + unsigned int min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); + unsigned int offset =3D 0, sector =3D 0; + bool locked; + int i; + + seq_printf(s, "Locked sectors map (x: locked, .: unlocked, unit: %dkiB)\n= ", + min_prot_len / 1024); + while (offset < params->size) { + seq_printf(s, " 0x%08x (#%5d): ", offset, sector); + for (i =3D 0; i < 64 && offset < params->size; i++) { + locked =3D spi_nor_is_locked_sr(nor, offset, min_prot_len, + nor->dfs_sr_cache); + if (locked) + seq_puts(s, "x"); + else + seq_puts(s, "."); + + if (((i + 1) % 16) =3D=3D 0) + seq_puts(s, " "); + + offset +=3D min_prot_len; + sector++; + } + seq_puts(s, "\n"); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(spi_nor_locked_sectors_map); + static void spi_nor_print_read_cmd(struct seq_file *s, u32 cap, struct spi_nor_read_command *cmd) { @@ -275,6 +309,8 @@ void spi_nor_debugfs_register(struct spi_nor *nor) debugfs_create_file("params", 0444, d, nor, &spi_nor_params_fops); debugfs_create_file("capabilities", 0444, d, nor, &spi_nor_capabilities_fops); + if (spi_nor_has_default_locking_ops(nor)) + debugfs_create_file("locked-sectors-map", 0444, d, nor, &spi_nor_locked_= sectors_map_fops); } =20 void spi_nor_debugfs_shutdown(void) --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 CF28D3D88F6 for ; Fri, 3 Apr 2026 16:10:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232625; cv=none; b=HdP3u2NmTW/F9HKm6tCEwFu3/201wjx72GJV5IODxCvbZL83NhaarZoFXyB2qDY9uE5czL1HPsqkXdZo+pNYiokSWNxOgRRJqjAvtUnd3OzcVAl9uCW0Ssjl5b7iVvNNEhTW2a/UXZAc0hMAXoYYglLSRTGJo+gLeZ2wzYXoXhg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232625; c=relaxed/simple; bh=mPWsbGWJmTfmQFEmwkgWdRBVv/LfnUc663KKJDumT0Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UOoBRTDHeeYRV6t0yCV/PUpW34S5AuAX30FTq0RipqsyUYUGVyTd0wv5LEefCTiQByA+KjpdtrCHJCXmzsB1VsI1ebKwWIFnfBiXkOt153s/cogyoNgFVdLysFDMuGT9QbxVh/kn2Z+SYcXeJGq6kYgjhyiEBKWUujh5ZruEDoM= 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=WRUdMRLi; arc=none smtp.client-ip=185.246.85.4 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="WRUdMRLi" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 8E53E4E428D8; Fri, 3 Apr 2026 16:10:22 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 5B0EC603C1; Fri, 3 Apr 2026 16:10:22 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B134B1045010A; Fri, 3 Apr 2026 18:10:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232621; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=rBjeS7Y+svFeJ3kkZc7HFjvdCDhIs6VUadHpnKxpakQ=; b=WRUdMRLiLM1dBCv2ifyVz44zPpLmIdO2W03YMcMUY3RA99giK6iDbI2wWn5X8XOQ3PAg4r TCiHrBfOG4vwqwTdDysuV4RsgmyVc5aU1+HTyUlHmIbhUERt+EaltFEZhB24WTcORNe0Ig l7aOYDzYfriGmuzfNaQ+Ux4GSy7r8v/N5YVRZ7pOYsTo/Fd3veSZM2uUQTjXE8ezCLw3FO rDGh3RTgU3v89VRZOzL9vrxB0e7wBwDSmQuS4T//zzC+AlC7JdWj3JONyINHgQroc1GEOR QggETdPkVe8V0efdjIWFt+6eJbS36cbSnqs7nUD9NX7Q0SD05RLZRqKsTsF8jA== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:37 +0200 Subject: [PATCH v4 19/27] mtd: spi-nor: Add steps for testing locking support 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-19-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 As recently raised on the mailing list, it may be useful to propose a list of steps to go through in order to proove the devices have been described correctly, especially since all the block protection information is not stored in any kind of table and is instead filled manually by developpers. Use the debugfs output to ease the comparison between expectations and reality. Signed-off-by: Miquel Raynal --- Documentation/driver-api/mtd/spi-nor.rst | 128 +++++++++++++++++++++++++++= ++++ 1 file changed, 128 insertions(+) diff --git a/Documentation/driver-api/mtd/spi-nor.rst b/Documentation/drive= r-api/mtd/spi-nor.rst index 148fa4288760..4755eb75fe5e 100644 --- a/Documentation/driver-api/mtd/spi-nor.rst +++ b/Documentation/driver-api/mtd/spi-nor.rst @@ -203,3 +203,131 @@ section, after the ``---`` marker. mtd.writesize =3D 1 mtd.oobsize =3D 0 regions =3D 0 + +5) If your flash supports locking, please go through the following test + procedure to make sure it correctly behaves. The below example + expects the typical situation where eraseblocks and lock sectors have + the same size. In case you enabled MTD_SPI_NOR_USE_4K_SECTORS, you + must adapt `bs` accordingly. + + Warning: These tests may hard lock your device! Make sure: + - The device is not hard locked already (#WP strapped to low and + SR_SRWD bit set) + - If you have a WPn pin, you may want to set `no-wp` in your DT for + the time of the test, to only make use of software protection. + Otherwise, clearing the locking state depends on the WPn + signal and if it is tied to low, the flash will be permanently + locked. + + Test full chip locking and make sure expectations, the MEMISLOCKED + ioctl output, the debugfs output and experimental results are all + aligned:: + + root@1:~# alias show_sectors=3D'grep -A4 "locked sectors" /sys/kernel/= debug/spi-nor/spi0.0/params' + root@1:~# flash_lock -u /dev/mtd0 + root@1:~# flash_lock -i /dev/mtd0 + Device: /dev/mtd0 + Start: 0 + Len: 0x4000000 + Lock status: unlocked + Return code: 0 + root@1:~# mtd_debug erase /dev/mtd0 0 2097152 + Erased 2097152 bytes from address 0x00000000 in flash + root@1:~# mtd_debug write /dev/mtd0 0 2097152 spi_test + Copied 2097152 bytes from spi_test to address 0x00000000 in flash + root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read + Copied 2097152 bytes from address 0x00000000 in flash to spi_read + root@1:~# sha256sum spi* + c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_= read + c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_= test + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-03ffffff | unlocked | 1024 + + root@1:~# flash_lock -l /dev/mtd0 + root@1:~# flash_lock -i /dev/mtd0 + Device: /dev/mtd0 + Start: 0 + Len: 0x4000000 + Lock status: locked + Return code: 1 + root@1:~# mtd_debug erase /dev/mtd0 0 2097152 + Erased 2097152 bytes from address 0x00000000 in flash + root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read + Copied 2097152 bytes from address 0x00000000 in flash to spi_read + root@1:~# sha256sum spi* + c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_= read + c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_= test + root@1:~# dd if=3D/dev/urandom of=3D./spi_test2 bs=3D1M count=3D2 + 2+0 records in + 2+0 records out + root@1:~# mtd_debug write /dev/mtd0 0 2097152 spi_test2 + Copied 2097152 bytes from spi_test to address 0x00000000 in flash + root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read2 + Copied 2097152 bytes from address 0x00000000 in flash to spi_read + root@1:~# sha256sum spi* + c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_= read + c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_= read2 + c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_= test + bea9334df51c620440f86751cba0799214a016329f1736f9456d40cf40efdc88 spi_= test2 + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-03ffffff | locked | 1024 + + Once we trust the debugfs output we can use it to test various + situations. Check top locking/unlocking (end of the device):: + + root@1:~# bs=3D$(cat /sys/class/mtd/mtd0/erasesize) + root@1:~# size=3D$(cat /sys/class/mtd/mtd0/size) + + root@1:~# flash_lock -u /dev/mtd0 + root@1:~# flash_lock -l /dev/mtd0 $(($size - (2 * $bs))) 2 # last two + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-03fdffff | unlocked | 1022 + 03fe0000-03ffffff | locked | 2 + root@1:~# flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # last one + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-03feffff | unlocked | 1023 + 03ff0000-03ffffff | locked | 1 + + If the flash features 4 block protection bits (BP), we can protect + more than 4MB (typically 128 64kiB-blocks or more), with a finer + grain than locking the entire device:: + + root@1:~# flash_lock -u /dev/mtd0 + root@1:~# flash_lock -l /dev/mtd0 $(($size - (2**7 * $bs))) $((2**7)) + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-037fffff | unlocked | 896 + 03800000-03ffffff | locked | 128 + + If the flash features a Top/Bottom (TB) bit, we can protect the + beginning of the flash:: + + root@1:~# flash_lock -u /dev/mtd0 + root@1:~# flash_lock -l /dev/mtd0 0 2 # first two + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-0001ffff | locked | 2 + 00020000-03ffffff | unlocked | 1022 + root@1:~# flash_lock -u /dev/mtd0 $bs 1 # first one + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-0000ffff | locked | 1 + 00010000-03ffffff | unlocked | 1023 --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 003403D891C; Fri, 3 Apr 2026 16:10:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232627; cv=none; b=MGvXLRGPHfrqHaDxFPkaSa5Z9QSLf2eRBdNDs3tGqCR+LbbpX2AeOyLV5V3FWBYmvMC3Mg1aIIZ8dfHXIBb5cauVXYao9ybnR5/arYqyuO7FlMTPz+DE0cUG0zUu/dj0fVr4nXRUIhMi8bCMujg+R23agpBq9zyVEyvM0ePDHME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232627; c=relaxed/simple; bh=5k0J8Ntzo1FOXTCT9nvrHWuuhSO9d+XpbCw0VN2jsto=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dSq66Xk6osX5c77Xj8QKcEbxQEYSoTC3f9E5RKsMqKcKrg2dMNVMQ3+/Y9baxXO83bYWt07UW79nSK6dEPcpxn/jq1aVCLMioCY4qqZMRlOBzoqrZOvFlMJAD/pVL7lP/xwN/xW55jPKJaF/ImbN/xaFyzb657WDlHuB3C2/00w= 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=T2+m4DbZ; arc=none smtp.client-ip=185.246.85.4 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="T2+m4DbZ" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id C9C384E428D9; Fri, 3 Apr 2026 16:10:24 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id A0613603C1; Fri, 3 Apr 2026 16:10:24 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1F17510450107; Fri, 3 Apr 2026 18:10:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232623; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=iXL5jH9mmaZPVtSclR9ZGgChE+rApa+9y59mJvYGhKE=; b=T2+m4DbZIst6dAQaDNBb9l/kol4P7Q+CpK8jTe9YY0zLd+xeLp53BEOKWc+wHYfTJuuxpv Ot4u2QoR24QC4/ll3RQTxKSfaTQoEiSM2HO51/EJSzrfvC4IuPTc/xxAPsNaamGnOAZzDm rDHJLOS8wS22LfqrEUZ2FdbM/t8zgPo64TluHMILrUQ5tVZyCEc0UOu7RP9E7wTHG09EIn HYLyl1NlacF2cW0wPI7eQ0wN7B+MAhfQBxBBGTLHyyaRkhDFcm+PlK6TXbI/MEzDFu5rCf qb5omfT27BQ4/F8mwidk5yXULELtntch7bLfiBEBB454s8digOv1ZInjHumUlA== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:38 +0200 Subject: [PATCH v4 20/27] mtd: spi-nor: swp: Add support for the complement feature 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-20-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 The current locking implementation allows to select a power of two number of blocks, which is going to be the protected amount, as well as telling whether this is the data at the top (end of the device) or the bottom (beginning of the device). This means at most we can cover half of the device or the entire device, but nothing in between. The complement feature allows a much finer grain of configuration, by allowing to invert what is considered locked and unlocked. Add support for this feature. The only known position for the CMP bit is bit 6 of the configuration register. The locking and unlocking logics are kept unchanged if the CMP bit is unavailable. Otherwise, once the regular logic has been applied, we check if we already found an optimal configuration. If not, we try with the CMP bit set. If the coverage is closer to the request, we use it. Signed-off-by: Miquel Raynal --- drivers/mtd/spi-nor/core.c | 3 + drivers/mtd/spi-nor/core.h | 4 + drivers/mtd/spi-nor/debugfs.c | 1 + drivers/mtd/spi-nor/swp.c | 196 +++++++++++++++++++++++++++++++++++---= ---- include/linux/mtd/spi-nor.h | 1 + 5 files changed, 173 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index eb7744926e44..c1e1d6d7cdf0 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2974,6 +2974,9 @@ static void spi_nor_init_flags(struct spi_nor *nor) nor->flags |=3D SNOR_F_HAS_SR_BP3_BIT6; } =20 + if (flags & SPI_NOR_HAS_CMP) + nor->flags |=3D SNOR_F_HAS_SR2_CMP_BIT6; + if (flags & SPI_NOR_RWW && nor->params->n_banks > 1 && !nor->controller_ops) nor->flags |=3D SNOR_F_RWW; diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 8717a0ad90f0..842ab2a5a903 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -141,6 +141,7 @@ enum spi_nor_option_flags { SNOR_F_ECC =3D BIT(15), SNOR_F_NO_WP =3D BIT(16), SNOR_F_SWAP16 =3D BIT(17), + SNOR_F_HAS_SR2_CMP_BIT6 =3D BIT(18), }; =20 struct spi_nor_read_command { @@ -483,6 +484,8 @@ struct spi_nor_id { * SPI_NOR_NO_ERASE: no erase command needed. * SPI_NOR_QUAD_PP: flash supports Quad Input Page Program. * SPI_NOR_RWW: flash supports reads while write. + * SPI_NOR_HAS_CMP: flash SR2 has complement (CMP) protect bit. = Must + * be used with SPI_NOR_HAS_LOCK. * * @no_sfdp_flags: flags that indicate support that can be discovered via= SFDP. * Used when SFDP tables are not defined in the flash. Th= ese @@ -531,6 +534,7 @@ struct flash_info { #define SPI_NOR_NO_ERASE BIT(6) #define SPI_NOR_QUAD_PP BIT(8) #define SPI_NOR_RWW BIT(9) +#define SPI_NOR_HAS_CMP BIT(10) =20 u8 no_sfdp_flags; #define SPI_NOR_SKIP_SFDP BIT(0) diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index 1ed1a0bbef3b..e1b3406d489b 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -30,6 +30,7 @@ static const char *const snor_f_names[] =3D { SNOR_F_NAME(ECC), SNOR_F_NAME(NO_WP), SNOR_F_NAME(SWAP16), + SNOR_F_NAME(HAS_SR2_CMP_BIT6), }; #undef SNOR_F_NAME =20 diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index d75ed83eb787..f5a2d667379a 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -32,6 +32,15 @@ static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor) return SR_TB_BIT5; } =20 +static u8 spi_nor_get_sr_cmp_mask(struct spi_nor *nor) +{ + if (!(nor->flags & SNOR_F_NO_READ_CR) && + nor->flags & SNOR_F_HAS_SR2_CMP_BIT6) + return SR2_CMP_BIT6; + else + return 0; +} + u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor) { unsigned int bp_slots, bp_slots_needed; @@ -59,8 +68,10 @@ void spi_nor_get_locked_range_sr(struct spi_nor *nor, co= nst u8 *sr, loff_t *ofs, u64 min_prot_len; u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); + u8 cmp_mask =3D spi_nor_get_sr_tb_mask(nor); u8 bp, val =3D sr[0] & bp_mask; bool tb =3D (nor->flags & SNOR_F_HAS_SR_TB) ? sr[0] & tb_mask : 0; + bool cmp =3D sr[1] & cmp_mask; =20 if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3_BIT6) val =3D (val & ~SR_BP3_BIT6) | SR_BP3; @@ -68,22 +79,37 @@ void spi_nor_get_locked_range_sr(struct spi_nor *nor, c= onst u8 *sr, loff_t *ofs, bp =3D val >> SR_BP_SHIFT; =20 if (!bp) { - /* No protection */ - *ofs =3D 0; - *len =3D 0; - return; + if (!cmp) { + /* No protection */ + *ofs =3D 0; + *len =3D 0; + return; + } else { + /* Full protection */ + *ofs =3D 0; + *len =3D nor->params->size; + } } =20 min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); *len =3D min_prot_len << (bp - 1); - if (*len > nor->params->size) *len =3D nor->params->size; =20 - if (tb) - *ofs =3D 0; - else - *ofs =3D nor->params->size - *len; + if (cmp) + *len =3D nor->params->size - *len; + + if (!cmp) { + if (tb) + *ofs =3D 0; + else + *ofs =3D nor->params->size - *len; + } else { + if (tb) + *ofs =3D nor->params->size - *len; + else + *ofs =3D 0; + } } =20 /* @@ -140,13 +166,15 @@ static int spi_nor_sr_set_bp_mask(struct spi_nor *nor= , u8 *sr, u8 pow) } =20 static int spi_nor_build_sr(struct spi_nor *nor, const u8 *old_sr, u8 *new= _sr, - u8 pow, bool use_top) + u8 pow, bool use_top, bool cmp) { u8 bp_mask =3D spi_nor_get_sr_bp_mask(nor); u8 tb_mask =3D spi_nor_get_sr_tb_mask(nor); + u8 cmp_mask =3D spi_nor_get_sr_cmp_mask(nor); int ret; =20 new_sr[0] =3D old_sr[0] & ~bp_mask & ~tb_mask; + new_sr[1] =3D old_sr[1] & ~cmp_mask; =20 /* Build BP field */ ret =3D spi_nor_sr_set_bp_mask(nor, &new_sr[0], pow); @@ -154,9 +182,13 @@ static int spi_nor_build_sr(struct spi_nor *nor, const= u8 *old_sr, u8 *new_sr, return ret; =20 /* Build TB field */ - if (!use_top) + if ((!cmp && !use_top) || (cmp && use_top)) new_sr[0] |=3D tb_mask; =20 + /* Build CMP field */ + if (cmp) + new_sr[1] |=3D cmp_mask; + return 0; } =20 @@ -168,15 +200,22 @@ 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); + u8 cmp_mask =3D spi_nor_get_sr_cmp_mask(nor); =20 if (!sr) { if (spi_nor_read_sr(nor, nor->bouncebuf)) return; =20 + if (!(nor->flags & SNOR_F_NO_READ_CR)) { + if (spi_nor_read_cr(nor, nor->bouncebuf + 1)) + return; + } + sr =3D nor->bouncebuf; } =20 nor->dfs_sr_cache[0] =3D sr[0] & (bp_mask | tb_mask | SR_SRWD); + nor->dfs_sr_cache[1] =3D sr[1] & cmp_mask; } =20 /* @@ -185,10 +224,11 @@ void spi_nor_cache_sr_lock_bits(struct spi_nor *nor, = u8 *sr) * register * (SR). Does not support these features found in newer SR bitfields: * - SEC: sector/block protect - only handle SEC=3D0 (block protect) - * - CMP: complement protect - only support CMP=3D0 (range is not comple= mented) * * Support for the following is provided conditionally for some flash: * - TB: top/bottom protect + * - CMP: complement protect (BP and TP describe the unlocked part, while + * the reminder is locked) * * Sample table portion for 8MB flash (Winbond w25q64fw): * @@ -215,11 +255,13 @@ void spi_nor_cache_sr_lock_bits(struct spi_nor *nor, = u8 *sr) static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len) { u64 min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); - u8 status_old[1] =3D {}, status_new[1] =3D {}; - loff_t ofs_old, ofs_new; - u64 len_old, len_new; + u8 status_old[2] =3D {}, status_new[2] =3D {}, status_new_cmp[2] =3D {}; + u8 *best_status_new =3D status_new; + loff_t ofs_old, ofs_new, ofs_new_cmp; + u64 len_old, len_new, len_new_cmp; loff_t lock_len; - bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB; + bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB, + can_be_cmp =3D spi_nor_get_sr_cmp_mask(nor); bool use_top; int ret; u8 pow; @@ -230,6 +272,14 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t= ofs, u64 len) =20 status_old[0] =3D nor->bouncebuf[0]; =20 + if (!(nor->flags & SNOR_F_NO_READ_CR)) { + ret =3D spi_nor_read_cr(nor, nor->bouncebuf + 1); + if (ret) + return ret; + + status_old[1] =3D nor->bouncebuf[1]; + } + /* If nothing in our range is unlocked, we don't need to do anything */ if (spi_nor_is_locked_sr(nor, ofs, len, status_old)) return 0; @@ -260,24 +310,56 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_= t ofs, u64 len) else pow =3D ilog2(lock_len) - ilog2(min_prot_len) + 1; =20 - ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top); + ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top, false= ); if (ret) return ret; =20 + /* + * In case the region asked is not fully met, maybe we can try with the + * complement feature + */ + spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + if (can_be_cmp && len_new !=3D lock_len) { + pow =3D ilog2(nor->params->size - lock_len) - ilog2(min_prot_len) + 1; + ret =3D spi_nor_build_sr(nor, status_old, status_new_cmp, pow, use_top, = true); + if (ret) + return ret; + + /* + * ilog2() "floors" the result, which means in some cases we may have to + * manually reduce the scope when the complement feature is used. + * The uAPI is to never lock more than what is requested, but less is ac= cepted. + * Make sure we are not covering a too wide range, reduce it otherwise. + */ + spi_nor_get_locked_range_sr(nor, status_new_cmp, &ofs_new_cmp, &len_new_= cmp); + if (len_new_cmp > lock_len) { + pow++; + ret =3D spi_nor_build_sr(nor, status_old, status_new_cmp, pow, use_top,= true); + if (ret) + return ret; + } + + /* Pick the CMP configuration if we cover a closer range */ + spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + spi_nor_get_locked_range_sr(nor, status_new_cmp, &ofs_new_cmp, &len_new_= cmp); + if (len_new_cmp > len_new) + best_status_new =3D status_new_cmp; + } + /* * Disallow further writes if WP# pin is neither left floating nor * wrongly tied to GND (that includes internal pull-downs). * WP# pin hard strapped to GND can be a valid use case. */ if (!(nor->flags & SNOR_F_NO_WP)) - status_new[0] |=3D SR_SRWD; + best_status_new[0] |=3D SR_SRWD; =20 /* Don't bother if they're the same */ - if (status_new[0] =3D=3D status_old[0]) + if (best_status_new[0] =3D=3D status_old[0] && best_status_new[1] =3D=3D = status_old[1]) return 0; =20 spi_nor_get_locked_range_sr(nor, status_old, &ofs_old, &len_old); - spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + spi_nor_get_locked_range_sr(nor, best_status_new, &ofs_new, &len_new); =20 /* Don't "lock" with no region! */ if (!len_new) @@ -288,11 +370,11 @@ 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 - ret =3D spi_nor_write_sr_and_check(nor, status_new[0]); + ret =3D spi_nor_write_sr_cr_and_check(nor, best_status_new); if (ret) return ret; =20 - spi_nor_cache_sr_lock_bits(nor, status_new); + spi_nor_cache_sr_lock_bits(nor, best_status_new); =20 return 0; } @@ -306,11 +388,13 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, lof= f_t ofs, u64 len) { u64 min_prot_len =3D spi_nor_get_min_prot_length_sr(nor); int ret; - u8 status_old[1], status_new[1]; - loff_t ofs_old, ofs_new; - u64 len_old, len_new; + u8 status_old[2], status_new[2], status_new_cmp[2]; + u8 *best_status_new =3D status_new; + loff_t ofs_old, ofs_new, ofs_new_cmp; + u64 len_old, len_new, len_new_cmp; loff_t lock_len; - bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB; + bool can_be_top =3D true, can_be_bottom =3D nor->flags & SNOR_F_HAS_SR_TB, + can_be_cmp =3D spi_nor_get_sr_cmp_mask(nor); bool use_top; u8 pow; =20 @@ -320,6 +404,14 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff= _t ofs, u64 len) =20 status_old[0] =3D nor->bouncebuf[0]; =20 + if (!(nor->flags & SNOR_F_NO_READ_CR)) { + ret =3D spi_nor_read_cr(nor, nor->bouncebuf + 1); + if (ret) + return ret; + + status_old[1] =3D nor->bouncebuf[1]; + } + /* If nothing in our range is locked, we don't need to do anything */ if (spi_nor_is_unlocked_sr(nor, ofs, len, status_old)) return 0; @@ -357,30 +449,62 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, lof= f_t ofs, u64 len) else pow =3D ilog2(lock_len) - ilog2(min_prot_len) + 1; =20 - ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top); + ret =3D spi_nor_build_sr(nor, status_old, status_new, pow, use_top, false= ); if (ret) return ret; =20 + /* + * In case the region asked is not fully met, maybe we can try with the + * complement feature + */ + spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + if (can_be_cmp && len_new !=3D lock_len) { + pow =3D ilog2(nor->params->size - lock_len) - ilog2(min_prot_len) + 1; + ret =3D spi_nor_build_sr(nor, status_old, status_new_cmp, pow, use_top, = true); + if (ret) + return ret; + + /* + * ilog2() "floors" the result, which means in some cases we may have to + * manually reduce the scope when the complement feature is used. + * The uAPI is to never unlock more than what is requested, but less is = accepted. + * Make sure we are not covering a too small range, increase it otherwis= e. + */ + spi_nor_get_locked_range_sr(nor, status_new_cmp, &ofs_new_cmp, &len_new_= cmp); + if (len_new_cmp < lock_len) { + pow--; + ret =3D spi_nor_build_sr(nor, status_old, status_new_cmp, pow, use_top,= true); + if (ret) + return ret; + } + + /* Pick the CMP configuration if we cover a closer range */ + spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + spi_nor_get_locked_range_sr(nor, status_new_cmp, &ofs_new_cmp, &len_new_= cmp); + if (len_new_cmp > len_new) + best_status_new =3D status_new_cmp; + } + /* Don't protect status register if we're fully unlocked */ if (lock_len =3D=3D 0) - status_new[0] &=3D ~SR_SRWD; + best_status_new[0] &=3D ~SR_SRWD; =20 /* Don't bother if they're the same */ - if (status_new[0] =3D=3D status_old[0]) + if (best_status_new[0] =3D=3D status_old[0] && best_status_new[1] =3D=3D = status_old[1]) return 0; =20 /* Only modify protection if it will not lock other areas */ spi_nor_get_locked_range_sr(nor, status_old, &ofs_old, &len_old); - spi_nor_get_locked_range_sr(nor, status_new, &ofs_new, &len_new); + spi_nor_get_locked_range_sr(nor, best_status_new, &ofs_new, &len_new); if (len_old && len_new && (ofs_new < ofs_old || (ofs_old + len_old) < (ofs_new + len_new))) return -EINVAL; =20 - ret =3D spi_nor_write_sr_and_check(nor, status_new[0]); + ret =3D spi_nor_write_sr_cr_and_check(nor, best_status_new); if (ret) return ret; =20 - spi_nor_cache_sr_lock_bits(nor, status_new); + spi_nor_cache_sr_lock_bits(nor, best_status_new); =20 return 0; } @@ -400,6 +524,14 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, l= off_t ofs, u64 len) if (ret) return ret; =20 + if (!(nor->flags & SNOR_F_NO_READ_CR)) { + ret =3D spi_nor_read_cr(nor, nor->bouncebuf + 1); + if (ret) + return ret; + } else { + nor->bouncebuf[1] =3D 0; + } + return spi_nor_is_locked_sr(nor, ofs, len, nor->bouncebuf); } =20 diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 9ad77f9e76c2..4b92494827b1 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -125,6 +125,7 @@ #define SR2_LB1 BIT(3) /* Security Register Lock Bit 1 */ #define SR2_LB2 BIT(4) /* Security Register Lock Bit 2 */ #define SR2_LB3 BIT(5) /* Security Register Lock Bit 3 */ +#define SR2_CMP_BIT6 BIT(6) #define SR2_QUAD_EN_BIT7 BIT(7) =20 /* Supported SPI protocols */ --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 297A53D9049 for ; Fri, 3 Apr 2026 16:10:28 +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=1775232629; cv=none; b=GeB5JAvGsa7YubmXbjhMHqqHr98kPuRPzIGYJPiwC0U+l/praaYndK0ifrXz3EcuIBP7SkndmOuvGCdp+BAfhhkKAQIBZByxeWVhNXX1+oQVVWjtSBoRnuiSvrq2Ivgd0n0WG9uhj5xNJEUGCHck2e1A0jxQ38AU6TRx3ij45Ug= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232629; c=relaxed/simple; bh=gnzj7GWcp98ZnLLkgndMyN+X9yfr8XWTdmY+32KVcqc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M0Ix+Hvr0+xkJV2biyl9rD9Q3cgf1ecFQLGN5yBnb9Agzyvvk5rx7rew92SDn09K6Pd43fghkBdcXCqOkYmg3VZea+cPhBVZWZ7I3zyOhH/vPhvKlBW7AjGMUIRCU0jQjwzXnh05c/FejETzNjxiB8RpXYiHGu5/m5xW0v47bFI= 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=0JRh3nd7; 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="0JRh3nd7" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 104FA1A312E for ; Fri, 3 Apr 2026 16:10:27 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id DAF21603C1; Fri, 3 Apr 2026 16:10:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4FA44104500F6; Fri, 3 Apr 2026 18:10:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232626; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=3IYxtkzdeu6bnBo9MR5hdgZZXX41AGqFyUgLNr5QV1k=; b=0JRh3nd7uPxKBQjr0gpuMTv+uGoVpzl/OUHmv+NgwRBOaQgZ5jaETyEddbJfKTMamPPG8g kTEWoBYiMLLrxigSWWfHxTLD/V6IDDf0isVqztHjtkuDNIZ/cafXTLkevGhK+LVhkB9tQY kQd/dv88B34HM+du4N8Geh+3zS6OhEaoj7mibc1Kkq1r8aadPavB5LQ/nqiWjBJdai761H 6bCwHr7gCJq7ROek8qettAe3OPt1zqzOPqVtzyrhQIH68yDeIzyHjFxayEYkwZiRrZ+pSJ tSLbsLFNjBp+lWz80aqj6pbOjsllVmF21R1LJL5nXer/SSE7TtulLj1Z19ChIA== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:39 +0200 Subject: [PATCH v4 21/27] mtd: spi-nor: Add steps for testing locking with CMP 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-21-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 Extend the test coverage by giving guidelines to verify the CMP bit acts according to our expectations. Signed-off-by: Miquel Raynal --- The instructions listed in this file target people adding support for new chips, however here are below extra steps that I also ran with the same W25H512NWxxAM chip. They are here to prove core correctness. $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 0 1008 $ show_sectors software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03efffff | locked | 1008 03f00000-03ffffff | unlocked | 16 $ flash_lock -l /dev/mtd0 0 1009 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03efffff | locked | 1008 03f00000-03ffffff | unlocked | 16 $ flash_lock -l /dev/mtd0 0 1015 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03efffff | locked | 1008 03f00000-03ffffff | unlocked | 16 $ flash_lock -l /dev/mtd0 0 1016 $ show_sectors # should cover more software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03f7ffff | locked | 1016 03f80000-03ffffff | unlocked | 8 $ flash_lock -u /dev/mtd0 $((1015 * $bs)) 1 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03f7ffff | locked | 1016 03f80000-03ffffff | unlocked | 8 $ flash_lock -u /dev/mtd0 $((1009 * $bs)) 7 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03f7ffff | locked | 1016 03f80000-03ffffff | unlocked | 8 $ flash_lock -u /dev/mtd0 $((1008 * $bs)) 8 $ show_sectors # range should reduce down to initial value software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03efffff | locked | 1008 03f00000-03ffffff | unlocked | 16 [Similar situations, on the other side of the device] $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 $((16 * $bs)) 1008 $ show_sectors software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-000fffff | unlocked | 16 00100000-03ffffff | locked | 1008 $ flash_lock -l /dev/mtd0 $((15 * $bs)) 1009 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-000fffff | unlocked | 16 00100000-03ffffff | locked | 1008 $ flash_lock -l /dev/mtd0 $((9 * $bs)) 1015 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-000fffff | unlocked | 16 00100000-03ffffff | locked | 1008 $ flash_lock -l /dev/mtd0 $((8 * $bs)) 1016 $ show_sectors # should cover more software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0007ffff | unlocked | 8 00080000-03ffffff | locked | 1016 $ flash_lock -u /dev/mtd0 $((8 * $bs)) 1 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0007ffff | unlocked | 8 00080000-03ffffff | locked | 1016 $ flash_lock -u /dev/mtd0 $((8 * $bs)) 7 $ show_sectors # should not change software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0007ffff | unlocked | 8 00080000-03ffffff | locked | 1016 $ flash_lock -u /dev/mtd0 $((8 * $bs)) 8 $ show_sectors # range should reduce down to initial value software locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-000fffff | unlocked | 16 00100000-03ffffff | locked | 1008 --- Documentation/driver-api/mtd/spi-nor.rst | 36 ++++++++++++++++++++++++++++= ++++ 1 file changed, 36 insertions(+) diff --git a/Documentation/driver-api/mtd/spi-nor.rst b/Documentation/drive= r-api/mtd/spi-nor.rst index 4755eb75fe5e..ec46bba8297a 100644 --- a/Documentation/driver-api/mtd/spi-nor.rst +++ b/Documentation/driver-api/mtd/spi-nor.rst @@ -331,3 +331,39 @@ section, after the ``---`` marker. ------------------+----------+-------- 00000000-0000ffff | locked | 1 00010000-03ffffff | unlocked | 1023 + + If the flash features a Complement (CMP) bit, we can protect with + more granularity above half of the capacity. Let's lock all but one + block, then unlock one more block:: + + root@1:~# all_but_one=3D$((($size / $bs) - 1)) + root@1:~# flash_lock -u /dev/mtd0 + root@1:~# flash_lock -l /dev/mtd0 $bs $all_but_one # all but the first + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-0000ffff | unlocked | 1 + 00010000-03ffffff | locked | 1023 + root@1:~# flash_lock -u /dev/mtd0 $bs 1 # all but the two first + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-0001ffff | unlocked | 2 + 00020000-03ffffff | locked | 1022 + root@1:~# flash_lock -u /dev/mtd0 + root@1:~# flash_lock -l /dev/mtd0 0 $all_but_one # same from the other= side + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-03feffff | locked | 1023 + 03ff0000-03ffffff | unlocked | 1 + root@1:~# flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # all but t= wo + root@1:~# show_sectors + software locked sectors + region (in hex) | status | #blocks + ------------------+----------+-------- + 00000000-03fdffff | locked | 1022 + 03fe0000-03ffffff | unlocked | 2 --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 A15463D9DA0 for ; Fri, 3 Apr 2026 16:10:30 +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=1775232631; cv=none; b=QuLFQ6hnJUU6vxaMrsypLcBsGJDtY9BLuwxyp5fWlWC4lGtoqhFVzlEXGniDv4TAczadPzzKNwX8w5efR9q3Qz+8SJuD8TA9GtfDRfaR6B89I7H+9ke+Gofd5659rWR48zSf8dx4YxpTH+GfBSpn52JD273/NLXqVPF5MYSCNkU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232631; c=relaxed/simple; bh=he2fkQh23Q6LQdB8d/NMg4t1Yu0lUqOwdbUn62LjTKY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MjL4Ck3vM3qBAQxfYg8NpRq/qls7bRQsTcDTeUw9DcKAk2mniA85+egiX1jAgto7+Z6PjSWoY3TZ6FoKQl+pd+pMeOguBoH5JromDUuhAQMelTNOogQjRgrkUGggkimY6DW4EWa+lq3HWjow+hoze8TaDxO1ViePBGLxFUVhSTU= 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=Vdr5oWDY; 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="Vdr5oWDY" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 5E2AE1A312B; Fri, 3 Apr 2026 16:10:29 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 33261603C1; Fri, 3 Apr 2026 16:10:29 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8F953104500FA; Fri, 3 Apr 2026 18:10:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232628; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=o3gJUgDW9H+8FokaFsD1jp2lD0qzceXQjBYL+wiCljw=; b=Vdr5oWDY7qm5YRAhfp9Z4Ia8tLdvlHkHrDK9fHlNUEZoNdgKWCBF5258VfkX+seO3KiFnR O+bufpYOM9TyEYBqKk/NI7SNtFgpifrGk1RRlY0dvCi5KDxNECQNioCdO+mj+KBJwWC6Lw LY2PF6kn61NpZByQ2uZcSm+Mu7ku4Sw591l4nQiw5yfZGFzC2cKQc6MKgTna385pw4AIPH lMCTw3zdhwbLJhct+6iAGUakxx/sRHhY+FHMVsi91ckZpCB04bqfjDHeu7oi25N4MKbsvx lIwP8UnbJLCLqPxiKVEadfHUg0QsLTWBN16WMEO2J5MvN/qefoBlo++BphO+eg== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:40 +0200 Subject: [PATCH v4 22/27] mtd: spi-nor: winbond: Add W25H512NWxxAM CMP locking support 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-22-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 This chip has support for the locking complement (CMP) feature. Add the relevant bit to enable it. Signed-off-by: Miquel Raynal --- Test run following the freshly written documentation: $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 $bs $all_but_one # all but the first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0000ffff | unlocked | 1 00010000-03ffffff | locked | 1023 $ flash_lock -u /dev/mtd0 $bs 1 # all but the two first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0001ffff | unlocked | 2 00020000-03ffffff | locked | 1022 $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 0 $all_but_one # same from the other side $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03feffff | locked | 1023 03ff0000-03ffffff | unlocked | 1 $ flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # all but two $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-03fdffff | locked | 1022 03fe0000-03ffffff | unlocked | 2 --- drivers/mtd/spi-nor/winbond.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index fb855fe44733..7609dcc768f0 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -358,7 +358,8 @@ static const struct flash_info winbond_nor_parts[] =3D { }, { /* W25H512NWxxAM */ .id =3D SNOR_ID(0xef, 0xa0, 0x20), - .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_= NOR_4BIT_BP, + .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | + SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP, }, { /* W25H01NWxxAM */ .id =3D SNOR_ID(0xef, 0xa0, 0x21), --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 AF04D3D9DCC for ; Fri, 3 Apr 2026 16:10:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232634; cv=none; b=Dk1ny0sTloWoRpiZW1AJMt3pSdmiFaCUo+eW2zlL36y32FX9Yd2LNy6Nd74tQJXIbZja8pYu+IB8N1OFg8udAcwKBHNp62V0hhlbf67+mA3gpqMzh3EDCB9eHinUscUb2NUCnTwcZh6vNU+THmD1pyJK3IaaQ/+6N+oMFihmW80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232634; c=relaxed/simple; bh=j22T9jJtFwoN8n0/7oJopyLdPfhWuHSvgQknFb9Qf3I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IgcrWvE/+jY+FIzO71hxyhKNB8BqFQj/x1GiGB6l27AXyUzUWHvpTwmUQ9QCnm6cmzqo7FR/g3yPdewVOwpFmSH+l7dqtyWpUFvBonjVuWaggMkvOuo3tEzGwKANT0kjYSFh4AlZ+TapGIgnfES4ESJxNDowvM/kEz/psAqjwZI= 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=tbAxAZ/V; arc=none smtp.client-ip=185.246.85.4 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="tbAxAZ/V" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 903A14E428D5; Fri, 3 Apr 2026 16:10:31 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 65B30603C1; Fri, 3 Apr 2026 16:10:31 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E783B104500FB; Fri, 3 Apr 2026 18:10:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232630; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=yhH+eLu6fxqdAQZiuioR7i/D/pMDWxpaQ3+CJS2/QWU=; b=tbAxAZ/VAzy8IwFmhTTzqwRSl+g4GlfVzdSfv9xI4hU/wuFm+qnHf9r0c4JtQ6LGOI8PJ2 ozPkom7cEawzaD6No7+oJIrw7qdZOKJW5jSPg9tAn0ayc/Ra/1M0JjFqPwTFlAfROKUkzD Ox2BeqJIbdqoJB1WBWvdxc5YwUxzYVIikyRLMvmi9D19ZeGlUM8KYad7yI7J3CZIf8xPfp 2G+z0834XE4cu8O0fjPqcVkooIzEv/TjdzzkgE6Su4Ntfnf1O+DDB+mHq5agNT4gG+IqvI Gxe9XIWC/16RnoN+X+wYuWQy1eR8rg6P02229wTzjVofkrvUmi6CzK4ZqTpi3w== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:41 +0200 Subject: [PATCH v4 23/27] mtd: spi-nor: winbond: Add W25H01NWxxAM CMP locking support 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-23-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 This chip has support for the locking complement (CMP) feature. Add the relevant bit to enable it. Signed-off-by: Miquel Raynal --- Test run with W25H01NWxxAM: $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 $bs $all_but_one # all but the first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0000ffff | unlocked | 1 00010000-07ffffff | locked | 2047 $ flash_lock -u /dev/mtd0 $bs 1 # all but the two first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0001ffff | unlocked | 2 00020000-07ffffff | locked | 2046 $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 0 $all_but_one # same from the other side $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-07feffff | locked | 2047 07ff0000-07ffffff | unlocked | 1 $ flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # all but two $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-07fdffff | locked | 2046 07fe0000-07ffffff | unlocked | 2 --- drivers/mtd/spi-nor/winbond.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 7609dcc768f0..1b9b0e9598ef 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -363,7 +363,8 @@ static const struct flash_info winbond_nor_parts[] =3D { }, { /* W25H01NWxxAM */ .id =3D SNOR_ID(0xef, 0xa0, 0x21), - .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_= NOR_4BIT_BP, + .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | + SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP, }, { /* W25H02NWxxAM */ .id =3D SNOR_ID(0xef, 0xa0, 0x22), --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 E1FFA3DA5CB for ; Fri, 3 Apr 2026 16:10:35 +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=1775232637; cv=none; b=NYMNJ4UUq7UiQGipIEVJ7K8Vpk3MJLSAUx9IJU8dV2W5hR8NAe0NCGbgfPahN1LrN9oatmet8/NbFSnA6WToxC1D8S3nlEGzv2chZqH3ZCxejht3yLLb5UgSoS+KSkv/5hCK3v6w0xMBFi1fQhVi4a6JPswO3DIRW4PPXeyOfWk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232637; c=relaxed/simple; bh=0qBZYTUTAN63ktaPIFP5bJwyScD4rw8O3x2EI+I+6Uc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UU2BHrfYOqvVOp9UY1n/ZoV6C5g6dPdiw3hruyBUw0ra07ZLbbUUOqKOGZQoz+ttwefCaH8zZ2g4JfRlQuGSLeapcMxARZqkCJ4BOAr4Su822xW7aV56pxYHRIzjkzk5a0MBP9V4DEDWQ0k2Bdtk/aEbEtcZGC20t/jF6Q4aftU= 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=q8lUnjwH; 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="q8lUnjwH" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id C92E51A312B; Fri, 3 Apr 2026 16:10:34 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9887D603C1; Fri, 3 Apr 2026 16:10:34 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 23F4010450102; Fri, 3 Apr 2026 18:10:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232633; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=R7OT2YlAzzFHwB/uvEM78CXYvmQMpqZLz49OKpEP2YA=; b=q8lUnjwH9jPWI4Yb3j8YS90x52RZKXekZVFr7dYwDVHBPhlSn/m+pxLA7xKcFSeqrFaC5x 0E8c6amxWmqFbkBZqGPkXqokVy3j2BPz1dVAiUFbpB5KQAiG5dAw1Ct4A6SHWLKs3MaP22 QWhrMfpeidVa3cmm/y4YDM3Fl31rDLEcZwanNJezFJGO4neVxOF1D9ngzh3RQFb62FXtFq jpNXk50SIpXnRi6KmBQuRGrteLAMQ7hPYwi0pBeat+gsytxp32HDzmjGZ70LDlSHR+5ATV miiTeZG242ctUsKzCLNrqitlc0Yk3wcFe+tdBhxMNSUvj0Z6yLYUM+Si5HvNPg== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:42 +0200 Subject: [PATCH v4 24/27] mtd: spi-nor: winbond: Add W25H02NWxxAM CMP locking support 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-24-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 This chip has support for the locking complement (CMP) feature. Add the relevant bit to enable it. Unfortunately, this chip also comes with an incorrect BFPT table, indicating the Control Register cannot be read back. This is wrong, reading back the register works and has no (observed) side effect. The datasheet clearly indicates supporting the 35h command and all bits from the CR are marked readable. QE and CMP bits are inside, and can be properly read back. Add a fixup for this, otherwise it would defeat the use of the CMP feature. Signed-off-by: Miquel Raynal --- Test run with W25H02NWxxAM: $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 $bs $all_but_one # all but the first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0000ffff | unlocked | 1 00010000-0fffffff | locked | 4095 $ flash_lock -u /dev/mtd0 $bs 1 # all but the two first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0001ffff | unlocked | 2 00020000-0fffffff | locked | 4094 $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 0 $all_but_one # same from the other side $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0ffeffff | locked | 4095 0fff0000-0fffffff | unlocked | 1 $ flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # all but two $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0ffdffff | locked | 4094 0ffe0000-0fffffff | unlocked | 2 --- drivers/mtd/spi-nor/winbond.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 1b9b0e9598ef..959fd4f46eb5 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -73,6 +73,26 @@ static const struct spi_nor_fixups w25q256_fixups =3D { .post_bfpt =3D w25q256_post_bfpt_fixups, }; =20 +static int +winbond_rdcr_post_bfpt_fixup(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt) +{ + /* + * W25H02NW, unlike its W25H512NW nor W25H01NW cousins, improperly sets + * the QE BFPT configuration bits, indicating a non readable CR. This is + * both incorrect and impractical, as the chip features a CMP bit for its + * locking scheme that lays in the Control Register, and needs to be read. + */ + nor->flags &=3D ~SNOR_F_NO_READ_CR; + + return 0; +} + +static const struct spi_nor_fixups winbond_rdcr_fixup =3D { + .post_bfpt =3D winbond_rdcr_post_bfpt_fixup, +}; + /** * winbond_nor_select_die() - Set active die. * @nor: pointer to 'struct spi_nor'. @@ -368,7 +388,9 @@ static const struct flash_info winbond_nor_parts[] =3D { }, { /* W25H02NWxxAM */ .id =3D SNOR_ID(0xef, 0xa0, 0x22), - .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_= NOR_4BIT_BP, + .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | + SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP, + .fixups =3D &winbond_rdcr_fixup, }, }; =20 --=20 2.53.0 From nobody Tue Apr 7 00:08:32 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 57D483CCFDF; Fri, 3 Apr 2026 16:10:38 +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=1775232639; cv=none; b=LjE2D2u7k1TNUKl2qRv80RyHF6qH9LzWOLI0y3HOMZ9/FBBXDryYUrsYAv24s/aL4xC21l/qIgv0xOnSuxfv5JHQMaqgJGW5343cLbGegG8x05xfzEPCFJeksFSr1bB5MH+yUQNqy8F+ZdnTrUVSeycEQhESrMc2hlkvmLaP9TI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232639; c=relaxed/simple; bh=d6UzTnF+MBsI9IkjxPSPcOkLJl3Jmn543+MUHvaWiuM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TYWbScDBqtxLs0/rWBRmG3zgOEK8HMBkCkLIE90FdMTL57LcXPmxbiCtqZaNVhBqRxmR4b8be+fwZp7aiulx5gqI3rlFqMfYZqJAKWznaeoW6lsHBSdhfOH69GI6RIupGjR9ji+n9OGfAO4QefI7rVatOX/YZ4V1NFD7nNeDQvM= 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=TJsY1hAL; 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="TJsY1hAL" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 2231A1A312C; Fri, 3 Apr 2026 16:10:37 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EC8FF603C1; Fri, 3 Apr 2026 16:10:36 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 421B01045010E; Fri, 3 Apr 2026 18:10:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232636; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=9HHkcU7E3iEbQwyhNOO8botbJmQi1btZtCu9+8skmvc=; b=TJsY1hAL7ofvIcIJ2LUkiEhNoAvzsbVG8CEQwEPdYi5nzHikDIFhIC3YIWsJI2teL7OXze y4trR8m570ofgB5OVWhj2FvqOqV9FAbE9TcQdCk5zaHBiHUQ20wCJZKkooU17gfHeHYjQW DtXxK0hAM2YwO0PM/aBi1w2FCF5kgaykBa9jilkipvekLYubiCWY4b2MIBWwekajOBG+KJ AyvnjUTAmSMSxRI8fV/SxEteQYu7mCT0yGrPaxAqT2Ezq9xGZ83qvVNau2Ko6yF6ED59Ry Z56AMSzcDSBnm/amoI2dz4+sNXOfa+U5lbP6ruIAiQyXpwPWYZBddjQqhJXylg== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:43 +0200 Subject: [PATCH v4 25/27] mtd: spi-nor: winbond: Add W25H01NWxxIQ CMP locking support 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-25-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 This chip has support for the locking complement (CMP) feature. Add the relevant bit to enable it. Unfortunately, this chip also comes with an incorrect BFPT table, indicating the Control Register cannot be read back. This is wrong, reading back the register works and has no (observed) side effect. The datasheet clearly indicates supporting the 35h command and all bits from the CR are marked readable. QE and CMP bits are inside, and can be properly read back. Add a fixup for this, otherwise it would defeat the use of the CMP feature. Signed-off-by: Miquel Raynal --- Test run with W25H01NWxxIQ: $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 $bs $all_but_one # all but the first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0000ffff | unlocked | 1 00010000-07ffffff | locked | 2047 $ flash_lock -u /dev/mtd0 $bs 1 # all but the two first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0001ffff | unlocked | 2 00020000-07ffffff | locked | 2046 $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 0 $all_but_one # same from the other side $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-07feffff | locked | 2047 07ff0000-07ffffff | unlocked | 1 $ flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # alll but two $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-07fdffff | locked | 2046 07fe0000-07ffffff | unlocked | 2 --- drivers/mtd/spi-nor/winbond.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 959fd4f46eb5..373c0af9daa2 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -366,7 +366,9 @@ static const struct flash_info winbond_nor_parts[] =3D { }, { /* W25Q01NWxxIQ */ .id =3D SNOR_ID(0xef, 0x60, 0x21), - .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_= NOR_4BIT_BP, + .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | + SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP, + .fixups =3D &winbond_rdcr_fixup, }, { /* W25Q01NWxxIM */ .id =3D SNOR_ID(0xef, 0x80, 0x21), --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 8AC6C3CD8C1 for ; Fri, 3 Apr 2026 16:10:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232641; cv=none; b=OGr6yOF42HGiqWf2IVJ+ke6BKgh4PhPIV1/jT6JO3cP1lRwUGm7zhOgASTHqpDil1C77ztJsjxzsyE78HPkgMaaYI/AKprkpE0w9iN/i6BIofxt8YkZRX6D+0LuRAaTuurBapTOepZng1UkL/FKBvDpMQsHcNSZqKa6qxMjkGNY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232641; c=relaxed/simple; bh=cUbVbBcqMKFf1RX/kOt4gC70kPohUUtTfwikvgWJF+I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qjQjgd/+mkkm3UzPDQc8vhTMZ1Zawaw9o3JFj8W++f0oMWqmZDMuX8WvmPCk+H4R/SvhMOMabP1m7PsiuOuAwPjT2X6YW3HSxN0iRc/DVAgBT+KEADAOGJxspEUdcdabJgZgUrcvUfHlpC7X3/KvBenQAYP/c/U4LN6LRdJjiIk= 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=15oiMRxl; arc=none smtp.client-ip=185.171.202.116 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="15oiMRxl" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 413E6C59F68; Fri, 3 Apr 2026 16:11:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4599F603C1; Fri, 3 Apr 2026 16:10:39 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id A3CD910450112; Fri, 3 Apr 2026 18:10:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232638; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=/FS22rx9mnkniTA7eh480b/dmZecJqM9SydOvsfJsvI=; b=15oiMRxlYqVbFyLnQ1HGp225CzUqKV8R4vWR9i3TJCZsuYpk90Nmjy0Q0pxhXV7nDpLEy3 kFQrTRNbqsxKU7wUi8MFXcnJhMubkzAzLJnaeugSjh6Ti4m8W+qWgQ6Kg4qmn3a00UZppf 3mkIBVdjDjFtAkz8WR0fROkdDgPP276fC0Nvb2ZlilC++7I02D9hdjvbN1Y0+jafEvu/ha aIgL3jp4TfyksNZcPsBQONuNwlOCvZ3HjtqRGDxNSVIgFxJSjTJPmd7IIk6yi4hFPk6OT8 d6js6pvtvhtE4fxN0okPuqEJIPrb4a9SJ3dNc8niarZWq5cZM2nyK6cgBnW4gw== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:44 +0200 Subject: [PATCH v4 26/27] mtd: spi-nor: winbond: Add W25Q01NWxxIM CMP locking support 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-26-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 This chip has support for the locking complement (CMP) feature. Add the relevant bit to enable it. Signed-off-by: Miquel Raynal --- Test run with W25Q01NWxxIM: $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 $bs $all_but_one # all but the first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0000ffff | unlocked | 1 00010000-0fffffff | locked | 4095 $ flash_lock -u /dev/mtd0 $bs 1 # all but the two first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0001ffff | unlocked | 2 00020000-0fffffff | locked | 4094 $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 0 $all_but_one # same from the other side $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0ffeffff | locked | 4095 0fff0000-0fffffff | unlocked | 1 $ flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # all but two $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0ffdffff | locked | 4094 0ffe0000-0fffffff | unlocked | 2 --- drivers/mtd/spi-nor/winbond.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 373c0af9daa2..72053a4505f9 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -372,7 +372,8 @@ static const struct flash_info winbond_nor_parts[] =3D { }, { /* W25Q01NWxxIM */ .id =3D SNOR_ID(0xef, 0x80, 0x21), - .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_= NOR_4BIT_BP, + .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | + SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP, }, { /* W25Q02NWxxIM */ .id =3D SNOR_ID(0xef, 0x80, 0x22), --=20 2.53.0 From nobody Tue Apr 7 00:08:32 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 D11223DA7CF; Fri, 3 Apr 2026 16:10:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232644; cv=none; b=up8XmFRkFdg34JL7tvDD4fikR16BvIK+Tyc0IJG42tzlcaTIfIqWG8pUtYYe1vTxAcIDyjamSN7mPA4S+JteUEm/DL+Oh/R6kY6LLKbP/Qg+YSvPrPnxdUjX2diFYH4x8XPw7qkM11FUcsn8eaJWAtEbnMxDjuYqdKGk2IkW0ns= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775232644; c=relaxed/simple; bh=CqbYqkoQqh+0D35g5HcSsYYzUUg1QfemNwma1WIXWyM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OJkrNUutDENNy3KGFyKzeP4VPEKKReROkKk7A8mCnq05ZZpBIXVUuFTuG58X7RXYf9CY9z4YohcTDDaUporEH1KxcegVfrxk5XbLEQrqzGQJraVpcgxmKPtuSyIg7Z5TrVlDrFUxtxyAVql/SoLIeQ6sbSVSyLB/HUUpDiRIDsU= 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=mdDBZJMT; arc=none smtp.client-ip=185.171.202.116 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="mdDBZJMT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id C12D8C59F67; Fri, 3 Apr 2026 16:11:13 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id C67B1603C1; Fri, 3 Apr 2026 16:10:41 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F3AA210450103; Fri, 3 Apr 2026 18:10:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1775232641; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=AGr7/3+8bpTRkTV5LZlQ/ojfudXHIefGQxlwloROzME=; b=mdDBZJMTvZOeGrG8HRZS3PKJMvv0xM5ZjFPUizOP3bS8fi9nXilmjfxOH76UoNsGsSs8yv BBjhMsiZ51Pj01u8p2uqerbEZYzk0ABQnlV4OAfjtVBkBElIyR/Ua96GzLY2xtwxOF10Da I836w3+lAmj5o18vsbU+HIOOr9VR8CUZ6V5NABaZ9BMrcHpTul1hBSQ5X7YIprY5inUOH2 HkXRr1ryrQJkwRjhYWr3HKe7Av1IlMXNcqLQjgwABCzuum9yH0zE0Vq/kEvYVpxWrvZHcM QFy2aOzwCivI5gWbJdOGxVGK5ClRMQ4gS76UzD7WJYA9utdA8e19i7CeanJ4HQ== From: Miquel Raynal Date: Fri, 03 Apr 2026 18:09:45 +0200 Subject: [PATCH v4 27/27] mtd: spi-nor: winbond: Add W25Q02NWxxIM CMP locking support 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-27-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 This chip has support for the locking complement (CMP) feature. Add the relevant bit to enable it. Unfortunately, this chip also comes with an incorrect BFPT table, indicating the Control Register cannot be read back. This is wrong, reading back the register works and has no (observed) side effect. The datasheet clearly indicates supporting the 35h command and all bits from the CR are marked readable. QE and CMP bits are inside, and can be properly read back. Add a fixup for this, otherwise it would defeat the use of the CMP feature. Signed-off-by: Miquel Raynal --- Test run with W25Q02NWxxIM: $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 $bs $all_but_one # all but the first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0000ffff | unlocked | 1 00010000-0fffffff | locked | 4095 $ flash_lock -u /dev/mtd0 $bs 1 # all but the two first $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0001ffff | unlocked | 2 00020000-0fffffff | locked | 4094 $ flash_lock -u /dev/mtd0 $ flash_lock -l /dev/mtd0 0 $all_but_one # same from the other side $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0ffeffff | locked | 4095 0fff0000-0fffffff | unlocked | 1 $ flash_lock -u /dev/mtd0 $(($size - (2 * $bs))) 1 # all but two $ show_sectors locked sectors region (in hex) | status | #blocks ------------------+----------+-------- 00000000-0ffdffff | locked | 4094 0ffe0000-0fffffff | unlocked | 2 --- drivers/mtd/spi-nor/winbond.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 72053a4505f9..639d72f48769 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -377,7 +377,9 @@ static const struct flash_info winbond_nor_parts[] =3D { }, { /* W25Q02NWxxIM */ .id =3D SNOR_ID(0xef, 0x80, 0x22), - .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_= NOR_4BIT_BP, + .flags =3D SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | + SPI_NOR_4BIT_BP | SPI_NOR_HAS_CMP, + .fixups =3D &winbond_rdcr_fixup, }, { /* W25H512NWxxAM */ .id =3D SNOR_ID(0xef, 0xa0, 0x20), --=20 2.53.0