From nobody Mon Feb 9 13:17:15 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 33FDC2E0412; Thu, 8 Jan 2026 16:58: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=1767891529; cv=none; b=jjCeXjJC+JRB88YIp+AkVJUOGR1q/DKrA+rk7JYKlAFRN/YVsR7T77A0i89p8/DaZCJXSri7li1TAHSzx0BQ/zkkbVIL+Z1GEk2RBmqrXzXeuhmZQrvnMyvxDRZsopGyTI8VVMmnIsE7Rh3bAQD9msEpEl2EdoaK80D3R+ZE1Rs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891529; c=relaxed/simple; bh=2O7V5M5FjMyrQDxujOW4gS7uuNpfZb9PYgQvhsnEq5U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YnvXTKN3MWjlJppilacRc4t7PDOym4+QsQCAK4Qo+IExuklHhCVukmSnDukcTw7DpWiaEcUpPWyFyeIbmWavyGpwqETkB5Zf6ijIEJCELKQmvXyYbHNeu+kEl5tKx4JG+RkQPT+ygxrMfg/4oUSQFCY1NL+b4EhJk4Zi4fbSg6c= 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=Z3XQ8MxG; 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="Z3XQ8MxG" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 71B621A2714; Thu, 8 Jan 2026 16:58:44 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 35CA86072B; Thu, 8 Jan 2026 16:58:44 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5FF53103C880B; Thu, 8 Jan 2026 17:58:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891523; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=g8a/PlagiX2Mh+RpGwzeXyISQH6TyEi6QFQhZ/6T7+o=; b=Z3XQ8MxGpCox0fnOd8mSkAEiFTGG7Zwt9VOWVG/eMgs66ZDmE62SZ67bx3BNTyfeLCfX9c K9hkEIU+uzb7YcqaUwctR/mcnbCIyujSQDsOPuMo+DUIOjKz3zIo8dznQvHnDVNuhqYbGz y0usVYRdFadSGUBkAiz6cSXLW1in0zMKAngVo/eL7gAT4j3saLH+YkUUFqxiOogzVNpKT1 v1KTjSFy6IgoJK125n33Fkl3yOsW6Jj9BqKAUPIT8Z2Z+1tD16AqSTzrH2PS5vKVPtUNFD RMAzXnQWeY6LzZMXW99vOWJRG4Oky3I2J3+qto2q/4MxGLtN0E0d6nRgyLRU8w== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:34 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-1-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 077852E54CC for ; Thu, 8 Jan 2026 16:58:48 +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=1767891530; cv=none; b=VAvXxOsBQrQBi9rzerAm8CbYhui6ITPHTV0dy7zNqdT/8OiFz2deXOnT1Yl3uN8amvVQ2g9kXoq1uKXqsDVoSsR8mVSiLLu03UzN6RFl1dm5xhF/jAz7KuozHbW/JBq+qtSR72Usb3X66+6O8PeC9ZL+V0YNH5YNQFVw18dYhEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891530; c=relaxed/simple; bh=pDZb0epMDwk6MJdaiEIqcDJe8cxs9bBHkhWkqeoeHyE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YJFBeIhcG/HkHHmv3qJ9V3A1RZFRoi1dNlPilHSk70goRtHmGfyOUdUJbbsgvj3Lo6LVlzqi5Nt2MJ1DqxzEuwtbBurn1Q1BE6s3M2qJKOkQJNt9JuER1E8dUy/30Nlt3NY9c6utptlM/cTGqTx01mMpYNZ/+/3nxV0xvtVe08s= 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=gqtQnL2O; 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="gqtQnL2O" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 7428BC1C94B; Thu, 8 Jan 2026 16:58:20 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id AB1726072B; Thu, 8 Jan 2026 16:58:46 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D6CA6103C86ED; Thu, 8 Jan 2026 17:58:43 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891526; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=stZFrqO/Xzy7EKE+3DmnORMCs6+d8LeG2HLgrVddfK8=; b=gqtQnL2OsdXjNBE3M9/quf5kgyFJI+wHYRhHS4X87X5BdpzOWU2QntXQxPTTfkcgMvgPaV cR88U1jJxTHYyfS6poHH1RfMxWnDHfKPR6Mgm2lGDMbYg1vEiZizGk6JWHtCAhk0D40n4F cpEU2DRS+obfm/uqu09+mCDv8kSIMneYX+CHCXiGquQ3Nkqd5M3OUiGw6ZIoFcl9y/Naqm 1HFcuTwFrGjgVrIB+rwwXqy1LQlfCyj/yo4GgfUf6L6Wv02UwcyjQVrHfd8vYcQ9nuu9AQ hJi8oNaTUwn6kjzBPcaEQFcCXXrCmijUE0dpUpIb9FUK/HmrbyMlH27i5cj1Rw== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:35 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-2-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 AC2B52E5B1B; Thu, 8 Jan 2026 16:58:50 +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=1767891532; cv=none; b=o035POV4Pd9fXnDTP7poPYRdo7kyaddgKyFwZLIXf19dh+Hh0nb+6BHww4fLvYVvg2BlyEhzokT7GKBOxe2yGxjZPkpcYqlLaUZzQJvBtr2qGrEL5jA5oNs9AthxWv0YsW9WJn4zPuF8eqmYaHuTanHIIxpOBgPtW2JUOYaNI6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891532; c=relaxed/simple; bh=dtFRwS67sy+s/gCELFLE+7OhZ68CG7YOcN0xB6PF2IU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rSWOUvioa3ntsyEEpCUgoAJhmpFfhkgTiarY50GhQKcsPAxlneePWtxQcxgmX8VhTP9inTm02DacasxGZTER0bBcdsxCUCtrDRbEJN8v8SaXRvgEEDRTTCRGpJ5Lcy2k5BHFiHA6XnHNDXuDxKiSfgPDcXPl9eZ4iPio/gkfpm8= 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=KjP3WChm; 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="KjP3WChm" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 598871A2716; Thu, 8 Jan 2026 16:58:49 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2E09F6072B; Thu, 8 Jan 2026 16:58:49 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 75C0E103C8824; Thu, 8 Jan 2026 17:58:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891528; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=q23MpHsjNpx/31GAsCENaWRzQgCj7+jsn8PlbmxRMQo=; b=KjP3WChmpA7LT9vLlui0fjjL/T2dSN1GlXpbudSe17zO5WTgRiAYRj0GTHNyOk+dM/BpHQ OHqVC7bOBnghRybGkzK8mI5lTLIJ/jJW8HK+Xm/FuQPWEEuZgjfIAGEtKVAGtiWosKGRLn t9ZGheIGKKWVRv+x9M0v0sNiPwlFHnMoyLmw6l3cvZFBgDktOW65q291KyzlMQZwkRGSqR 6QuN0ZP1/zG5KAwlocQ6RK4oiY+3aEzkB85QMFgme+v7PVlHwFdQ5VTeXNddgqPd5+D86e 3ZYnOBIcMhbi5dvKjHgcnCLsufluke40wrX9f9WPbLSOGVlUP3wVwpJJX35rnA== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:36 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-3-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 A7F052F1FFA for ; Thu, 8 Jan 2026 16:58:53 +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=1767891535; cv=none; b=S/Gq+XTLUds+SMJ2dT5lWI6tAssjc0g+7vQ4KflyVPZwLFveJwMuflvvMK9ECI1rL2QquU/OGFfhiMaBvHO2y/z8Bx8OImwUBxK09ETsWHk4oEV7vbAhfxdu9ltruw0+zUsnJEZDO1dxwmbOuYeAJnjavbHJu6gkPXdMhPewF9c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891535; c=relaxed/simple; bh=fzE7Kbk6Kb/cBeCT1q00i3uy0oSMCu925oa9vdXVJ6o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PdiPbkiSJPsUw78u7NF/VtFbArTk2xtAFi2LO0Ca+6ls2vXj44auX3pBGNwl/SSbZB5qgblnm8i5xWj723uxtGCFPzAfGY/SsIRWhNcSq0LikBxcOs/QZMIPL1LVs9eW/xT0dAPYKsYwxgAzAzGrJ8XCg4amreMrYJI2neC9PJI= 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=0oPjzBEY; 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="0oPjzBEY" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 970021A2714; Thu, 8 Jan 2026 16:58:51 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 6C7176072B; Thu, 8 Jan 2026 16:58:51 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BBFA6103C8811; Thu, 8 Jan 2026 17:58:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891530; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=hXc+5kjs1EF92jBqcrTSRSedlWRYjsDeVRr6sDpavVg=; b=0oPjzBEYYewYJkniJdPwuCKWyuuaIrPAjnqWstVzJx6z8jS/FhpOUQYALTD/69NIvFUnYm wIVH7UkbVEWBtOV7l54/6B3UVGGLjtY7Vc9aMtNYUYJNTTC0O6xShyPgAWxpE2VY+7EBAg Rf4rYl08zaH398hbVSExB6JqkqqPbMDmXtGkcNbASFjulZy+uMfxSqdj7dbsYMydjO8taf /ftg1fCqfV+5+/6QRePKqL25cyR1Q3HJo44xCoL8vxdVpaaC2urbAE/xi8CGMum20gS164 TOr6HfqHQ7WiJx4xvGzje3ycoAdIr7QNNV5IhdHOzyXqiqqjUxLt+LTxqZZCAA== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:37 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-4-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 9437B2F6904; Thu, 8 Jan 2026 16:58: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=1767891540; cv=none; b=Z7AuY67w7/FvNCyLMLkR2H1aMLFfp0/AMCh00/5Tlrv4VxlnD37r7Mfcw9mmDi7bB1/1dBIg/K89vC5tJFWmURBK/7jbiF3UJjV9iX7n+U4kMP8PhMVVGx79nwf49C+LH5n7u6PcmN4qkTQsyX4JMxGR5W4r2ipYHQ8gYMb3AOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891540; c=relaxed/simple; bh=0srJ1s65smP4KOpLWZGyK+ITZa7dJa5sLpiyMQk/z9I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KQGG1An8p/BCvxHzeM5QGsbrsJoKwJ4UEGfH+9D8rYWrkLwu5EI/m5xaSM7vZ4GZRrXuHfxPcQ//uH1bYtMXVeTi8ACtZEFMUPbdMd1SKOwWSrDzHyH/PW6tKtiplwpYlUj8PO91WXjyikE8qHE8NGhaZogx2p0TfwyoewB7nWc= 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=q7H/PymZ; 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="q7H/PymZ" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 0C7481A2717; Thu, 8 Jan 2026 16:58:54 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D5FEA6072B; Thu, 8 Jan 2026 16:58:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2EDC0103C885C; Thu, 8 Jan 2026 17:58:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891533; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=rre/i4KjHYI+91ZaQYrTCZUTDkibP+vKxwiQw3sQxfU=; b=q7H/PymZqr9DX0coX0Laz9UCpddok1wUdbm8d2kk0H+8Wntj0sGsUJO3eXDuavtQfcI8pt z/B6Q5r+/w/2Km9D6mtYJWlxHm606DY482Etq01POMuYc/EitvyrKNuLoZuB1SprqeZRJk Hgm14sue1qle17G8kRkw5iKsieHy5K/VhMRZWtadRl27JRF31qk9nMg948T/TWtQ8q/Qfd i5uRQxuOHk7DRV+s7bVMBnloXyKaAyBTHoWCu0c4Jg04WzLnTBBlgjWYMLJSTiM6FGl/AX LYrxP6DVMvmMih+afPiVGNyrdjGHDZ6ffOp0Wuk0/rkfzJhovJeNd27fSNk/zQ== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:38 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-5-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 A3FDC2F0C78; Thu, 8 Jan 2026 16:58:58 +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=1767891541; cv=none; b=rsysUa8xfBFQ65n2HfeHnTywaHVi3PgSuVMxSreQiz1y57uXQx5xvCEvtftBsLbBnZw+loXAuTvndjJ+sn0nRnrBw0XpNws8EOeeIraY05rVxd5KIkPRXZELbmDmi8SP/YyXVwIfc7Xpmd3oZEUgiTNb4xgsreechuyitLYjwh4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891541; c=relaxed/simple; bh=1Yo/fOaQdnIL35rS5CVUoPBadwI1OnlcymoKxp3EHp0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r9MYVDfxhpHrlwWr+PFx4ObgndZlHnKRRHTgjyR1B3XTRm+BSo1ku1NhVKa5woIZ6a8BF9NOhmkukRZ/X39QEPKUkX2ZigYkMfJqZPqA0a0dnTg6OsKileABMFd9acWh6gFzDtqD6uodZ1WiZoKmFu5TWb4JrnbujOZ6aetsgTo= 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=bBcXn3k+; 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="bBcXn3k+" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 71D784E42004; Thu, 8 Jan 2026 16:58:56 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 466436072B; Thu, 8 Jan 2026 16:58:56 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9666D103C8896; Thu, 8 Jan 2026 17:58:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891535; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=ThROAC3RdaD7Vj2qP5V2r7cJLBpFb3GyBt6p16RAuXc=; b=bBcXn3k+vwgCBHh1VTMXcHLEm0ZQAoT+qBglsU85eYt3bBCeHCBFvz/mY4sx+35ktfhr2P T2jJrHwKYLoS47wWWHFMngEymhdQE+BtijG5xUhDBvX3yFUVCLcmqNGiu+P/xCEZ0pmXTt 3Kyv+D2EnRVbDXxuw/kc8NqcAgzeu1maPFKDslBcOcThPcNAjgPP+UvdknCl+G3LhpUXpX bUypQnKY8031bL2CbNFsiPJ1jAMOKWeDDWiqcDRu03LTo3kmCIf6Rzai6Hw2ijUOSg+Jb6 /toWwG368omBDUZM1uU+TXTpXuOrVznF/PLKTirFbr2W5HeKk+bhwGSjABAMqw== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:39 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-6-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 8C86B2D7DD9 for ; Thu, 8 Jan 2026 16:59:01 +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=1767891544; cv=none; b=Wbt0kPn1Zi+n0rGaHl3EkLodvYbIeSElEnJJwfE45AG1PbAyX61hdShm1W+FAJT95FGuquQpv2V3Q+nUvU4T7oGJjAw6TT8m0efbvfTH0U48qryXCiEyc42o6Zxx7wuT1ACadEkGTeGAJWBsKErEtl6fPWeamtTcNAEP+hRfMJs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891544; c=relaxed/simple; bh=m8EezPdj5/zLpTZs6LAb34kiI2GknFW1YMmMypIYx5U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H05BKQ4BrehiD6MUYI2Ql5qBccCkQSikZTtH7Gq7afvFWfxK5+j4gt4Um1rety/mwa2WHWm1fcLrcWe2YNQ2eYlhM36tkxS6agYlLBJq4eIc9yvoe3g1OkUeK1IofPh8eOPrgrxcLqh3ItFdvE+4v/b+hhJX3pNd3+ahrSvZ+pI= 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=p5TMnORk; 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="p5TMnORk" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 12A024E42000; Thu, 8 Jan 2026 16:59:00 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id DAE496072B; Thu, 8 Jan 2026 16:58:59 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 0FB31103C8826; Thu, 8 Jan 2026 17:58:55 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891539; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=uBSfAslupKiDUjYa9VdOz+tUE+1u7aYrr2OFADafudU=; b=p5TMnORkhvGqujqrzItf79wUsWyjUlCV+E+vju41eFJ++qmKaf4qaWOLk+009IVSmHZrEG L08bNaOVOOBr1e8U91J3p2l4E9+a79klICA+OMCk467mwon+9Iu5M209lRXDsYYUdLtBNh zyOnba9EqmmpCRcnGJ7OycYQL5ImNaSC1nmvKb0K2oG3BBBFKt0ss1tBKAEok/12HDjjyy oHrUMaW1Jfvd3LM7Dxu5Htba64tM0F35+B3/ub5AzJHtmmaXC2SJ4vLTL2XtcKTMvkvCqJ O+q8MHEwJfsL0pwsU8ihQ9/2FxMlOlcF6mj3LArL2zotoSgd8aHCRkQHNyZrtA== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:40 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-7-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 350542EFD81; Thu, 8 Jan 2026 16:59:04 +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=1767891549; cv=none; b=hg/tpmoqxCf624qXRh6GxxrXllu4lE1MWK5k7vFEY9uEUAsGL5e4t6US1jwymckUi3dT9y1Gqh3k22vl169RVZVun3sbojXGldJ9yfCcJDhoLOK/MmF2hKZus/sARhfuRZC5sviSna/gbRsDtOtvq46SuOpavWADww7mPeVujBY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891549; c=relaxed/simple; bh=iCfiMsUjEbvsR4lM+7YoHewMae65PTUZGwPNuWcvBuc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cTvDV97svf3A+n1rDY9B7LFOWPwoozj2qLCuaFcXRwyRXxJ36w8cfExSDubg+8PnmJA/lfz5YeDycjEbhvn3Cozm4jJzUtFfvu1QmpYk1TXow5eXJiuMizZnqgsoyMgEcwChUR2ryNrUUMXvkWS/Cs+upaAWtLM+rf901YAIXq4= 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=P4qEdUzv; 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="P4qEdUzv" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 224B2C1C3AB; Thu, 8 Jan 2026 16:58:36 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 552636072B; Thu, 8 Jan 2026 16:59:02 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 90D7F103C8889; Thu, 8 Jan 2026 17:58:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891541; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=KPr75/L7Q2MSPflmaco7Z/uPl6GqRaTpWsWBClHqZT8=; b=P4qEdUzvuKIJ0PRJ7V2UHjJD8/E5V84kSDJUDxghZ6HYawuw2pEURYRKSjdwoiAJezlNGf 8SyYLMWGKS6u98T4bJ6E+1JvTNdAR3Zx7CgBbcx6/DoUm955O8777oIYlGHoiDYZwN0Z1Z kRtY6c1pCkPv58Q/fmPcwM82DmzkDYuEGFNi0MXJuTILA9yZSTTUvLJhuS8bIVuY9ZR5Yc bwBR29LGPy3byEqNVS4ieFwLI7db7Jz5F59CpRlB65q6gEUQ0Fd0mPRYHxg5VmCC4U4K8+ 65G738nuffxu4LEqgz8M9TeLbsSSra1oZektEovdvpODfw56EDiDN9U2V0B5zQ== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:41 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-8-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 968412FDC55; Thu, 8 Jan 2026 16:59:06 +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=1767891550; cv=none; b=Fm6Rk3jyI9HE1jpFqu/jtF6txdRdA0JaYyiulW/mH6dAp/rNjKvEvRafNUwzDpNrWo1cEEIxApj/milYRjHYEmjrmT3KF6+UPWlfyckv1yCADFAs1MZEywqK9+Ns2AbrFr+mW2rCLSOnlH5PMyxc1+OM73YmrC0T9L5ypQbbXb0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891550; c=relaxed/simple; bh=m/zjBLZFf/xGAvmLJxp3+X4gdRRR5lsHphDGIp4ntMY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dsyeK7fNIbZRKGWH4u058s/0AwvJgcKXW99H7trjweAYniAK5JUaca1E1Qy/E6B9URhj4MyI1Hwf8i7Q5fTfR9KnRGtCXZe8Lr5klBUbzDmlXqg7++Q/6grEq8yFlT6IWjrSN5Vm7oz0kESaXqaCvQ6gtgurouyTBoBLKtoRw7w= 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=1yr7uOmT; 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="1yr7uOmT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 6F1264E42005; Thu, 8 Jan 2026 16:59:04 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 43A306072B; Thu, 8 Jan 2026 16:59:04 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D7E26103C8891; Thu, 8 Jan 2026 17:59:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891543; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=cLbxiL+2EHw7lYTQVAB4LC1S2WgQViU5gpSnkOCqrtA=; b=1yr7uOmTECcZPSS69EzjbsYbzodtGvbiX36sxhsHQi3CBW8Nb4efMsdPzHVQiVRoSPxmrl LstY8aN0dfVkW9VSaLSlhYSPod0T/Xq3OBKQQqQG7IBDeWqoq3akeEN1PjGHCkfikI3C9A eTcadVpTjvWgPz6OzukK/iS6qrptKjkokad3WeZn6uybRIShlad5QTs20VVAH+VRZYSkgs eL0hev+3t0I6Wb94SSUocckDrm3/+4jIDOU6x7qZLTEqVr5uTxwW+z0S7uB5KCeyYNu2XE YjJk9MBQIO2lGBeI980onvX10bTne4wYYxLyjwDO4ejEWYqaFonRisvlQcULVw== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:42 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-9-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 151E02FD1D6; Thu, 8 Jan 2026 16:59:08 +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=1767891551; cv=none; b=ls8SQ3jFkSsvrFon4+aYqjOCes+4OihxqVZt79cQS8dfzZ4uyaZXP47F1hjvHc+iCWRqVko5gwHccIIgzrlT4o6BJtjBjhQ/axTX+9Xl0qNa3q26eNFcd6DSk9omGe50+DNo5QmTUHhneHAw66MKgNP21wjGsx5GAZs36RqwetU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891551; c=relaxed/simple; bh=c3d5y3lsmdfy3rUDJHD9qOABwrEUyamDkOtvHRWb5Dw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dP21YFHZeNSEkT1HqSbomx9+RQrBSCXoQBobpllSETEwdYYEsWaeB5trOpjqJFg7cMFbZ8TOLUt2zKpWdu4ZJjnKTQ6g72isH3CE4jv4Aa4qCpfxePKBi4apQ80OMI/9oHSBofPSU8Q+tNz9ht5B0drjR8vqP5ArBX48MAEGFw0= 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=GJHV90KA; 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="GJHV90KA" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 119831A2716; Thu, 8 Jan 2026 16:59:07 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id DAED66072B; Thu, 8 Jan 2026 16:59:06 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 0A989103C8897; Thu, 8 Jan 2026 17:59:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891546; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=huIAGKBLlYy5bqenkOHYpgkreeVYU/erjhzN9EO+unQ=; b=GJHV90KAn5BplDmegOH6ZQ7at+qPro0BfkjbGBhomazuYXWs00i/7419WmJ6gHDGgev4jJ cwCQ+8yptInUmtnaam4ab4ycLj6YXhaXgRV9li1quGGh6RlvmINpvA3u6MGN/T+jSPOOyC iyT9Xy+RP7R1ewzKQ+T6JjzJP2mlqrtqIqTB6GnxIctNnVeO8iFe1x1m1W0SSyl58BWX+a r6R9vKrUzplyum+6lGGkXV8aH29v3Ix12Qr6cV5Ryu7bLY9juyxhaJyVrXjBXDfJKGYlh1 0wp1tQMu0fEpT0gbS6zqkdY3fsHVsN3mLW8/40iw4tLDdIBkW0tKDipCudOaDQ== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:43 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-10-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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 8d91052cc21e..97da30d9f6c1 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.51.1 From nobody Mon Feb 9 13:17:15 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 1A5CF2F0C78 for ; Thu, 8 Jan 2026 16:59:10 +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=1767891552; cv=none; b=pWL7SYpelx9rovbdcUcxZmCCmo1m4JMyI4T00ZF1+60NFJaOhzM1OWMocpfX7EX6eCIvzrgJpeUE3C/fj4+z5ZYBymToobTo99zMgr4eA1dwxxdq4bTxkfAPA1f4LVcsnY+ZUT9fgTkFMSNjFURFAgncHOrhC0eo2rfQdcRg0AE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891552; c=relaxed/simple; bh=GHZmXM5aeYs2tOJlVhdumoaqbQGSKeO1/pZkzO0/kP8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rKoeOXJNDtP9w0CshYTJOKhgs/zA4vPVvJ7c5aDTkT8hGKMjezFEorT+Ryoo9hVl6ShkQD2JTCqeLA1gZEKcusNq5cYumZTotcYVp1rCT256W9XzTjQpbi7ORyMVTtA/eRXmlG3VDNJCF2Am5euaYhf08IBOJzQeBCEGf8Rg1pA= 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=NWgif6BC; 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="NWgif6BC" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id BD4454E42004; Thu, 8 Jan 2026 16:59:09 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 90D746072B; Thu, 8 Jan 2026 16:59:09 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B66AE103C86ED; Thu, 8 Jan 2026 17:59:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891548; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Ec0kbPx+edwoqApwKlNsfKYC2JUdHu2CV9kwwUFOJtw=; b=NWgif6BCcS+2DSpmnKC8t2Th6/nnQxszo00/P7EgjNMLbNYR5tcfqBgJDl53TFANdnuxY/ c+a/OeopHJ5JHSegGHaTaSQ8q+c6SkAtUlifrnj8A/PZkmex0HnNuSjGvwr2Ho0HstRJo9 QkawR2hSgiewE6aic89YreHesLDp9MkcKDpqMX1wnXG5nb0E8w5dOP7Dd2NY6Hqnm3rlD/ +kjn7UaqAD+EA+xchRr5mPpycpwzB8LVmt+qhv8KK6G+GuD8qVOxBZ82lMvewKbOmMzQ4e EUNa0j6I77epOUPkoI2WakJgJb4OEKIFRc6oayn4B09qc1owJ/mK3Pu8dai9dw== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:44 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-11-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 4B8503148C2 for ; Thu, 8 Jan 2026 16:59:13 +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=1767891554; cv=none; b=npK1Pj+6drRlbo1xkRqFJLm0G7xH/5fdn+P3gu93FdX/6sV34pIgauSS2wA/jMI3EYmX6oKi+pBQdWbuYbT2nhIkHnio1GG0jcQtdlfvGz+zcbqkpaf95cCihUjVHVwNeeaMLsE43niX+vaZFvTE1vtoDAxZQ4GxDNyNg/p3s6s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891554; c=relaxed/simple; bh=wjIUXafk8VGGbnPY3Dsx9uPr5XXbqRZCmWlNeUX3WCo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pfxLjl3nEMqm42NLXT9xnOi7u4ydlQ2n657myPfwrOWIelD+wkVYl5ch9eZphsVhvjngfyvs+w+6g5L2jMchL1uPtbgqctKG1//5STUT918RyoFB88KJNltks9u0VJHurKVe3WeUjHuGr0tzV1nXaV0691zk7umAkeCD8/+Flzg= 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=S9M7Ejen; 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="S9M7Ejen" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 0F0614E42000; Thu, 8 Jan 2026 16:59:12 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D80AD6072B; Thu, 8 Jan 2026 16:59:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 58415103C8811; Thu, 8 Jan 2026 17:59:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891551; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=oqqmuaxM0JPFUFPYjxJGr40Kx4IWxVfbQQsEuyrgdv8=; b=S9M7Ejen/u7DrEf1yJnaoIpPSZJqMrkISaFjTKDPP5QFj/Sw4zggU2NptvXNDeTNf6AxYx ROZhJFHNw7g2vTX7h+LkUq4w4Bp6OTsIyvBzLbMOFipeUccHy/D1t9WQfcM0wSvnB/XSBK H2k/QIuyMcOcKAKJ64h51zPW2NzZdJUEuTjb8ovI/P/TA2Xs3hpUj2L+ybmQZlIyF1+8Jw gY3niszpu19blIgJr6igQy5YaaeKcjmt7hTQbmqu7OeX5sjak992qi7fFv4/ZKsP+9FCfW E6ZTbedF/vAcCbZeonr10vibmpWuLGqierWvIjWfW5It5kA6XfWbaT2hwmiGKQ== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:45 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-12-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 E72AD320A04 for ; Thu, 8 Jan 2026 16:59:15 +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=1767891557; cv=none; b=HgxQ6oke/fw/sg9sDW+WlEctxF336EQ/pK5WMjrHbuh3puif6wc6WNL/1IM73dgtHsIVTw5Xuv09FPvlUJMYbUmNLBZxM8+Xue+PokMPanQqkSlFkg1uv35fkIzSdtQ7z8J+Eyfd2TwYJYI7uLJR+xsY2gUdYIIQzW8L8sUgLJA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891557; c=relaxed/simple; bh=qZeCE0msR5ojlr1bTKuEzUtB7a//YcKLIUtu1EhJwhQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hcZTsc7BwFHKqF7PECPT1pHV4CdG6zel6oPkZfzqcCojrc6oLHDj+svH1i3hky2ROEfYlEUaKZGgkHyhx85RZS5jF44HnvCZVLdas1ew6dFhPflETEPIEFWv1kyD438378C+3vJd72nOOuc1FW7QUHJyBsKVWsMqsSyOn0Lpc1M= 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=Vpd6V0KS; 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="Vpd6V0KS" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id AB7671A2718; Thu, 8 Jan 2026 16:59:14 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 810E36072B; Thu, 8 Jan 2026 16:59:14 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BD9D1103C880B; Thu, 8 Jan 2026 17:59:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891553; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=D52TLeXksnZZDY4Xj5CPfUClEwfCTxQc7ZJZFYNQVjg=; b=Vpd6V0KSgKiaB7wRZK+6CylczQtWwa/XAwHnGtYdV4s52ijfCnFieU4qgWBmj82ZREquVO EENcULeUseao6AwRcaLXmuENkgn216SSyK62q5eJK8X0PA5kl8nV6NnK7O2byo1NqLa+BO 4OX50bhlGpasE+z1AMwtgfDB8eu/a18lUlA4Fe+u9Nv6mGdh6GKMVF+VHvtEX0jdZ4RUV3 9HED0wdQg/gcS+p6c11yfE1/m3Y1tAvXf8cHA+Ad26Nnox6/XWDkwMVn36FeM2yeWKt1q1 rlqOhTmf8j2dY6lsi2svpHTjuwgzydHmJfb9Uxs62K0ZqGVl5MonhHWPhJIr9Q== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:46 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-13-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 27C0B27603C for ; Thu, 8 Jan 2026 16:59:17 +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=1767891559; cv=none; b=GFlBEd/RouOhv508S7YnM9YrXvPIHLZi9QJAKgWH4S7CXZkDkgWcRkTgK7g9/JtMDYorSWcrn8SXn+4A2LWDXpkof6hZle2avQxi5dESsdvxlX2mZ3bqhmSWkXOGMfDPnDNrQJa+Gt6mn/UnjV21m6D/NE4ox6tMzyVa0jWmqBc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891559; c=relaxed/simple; bh=Csam+1hyCd0eC0C2z5CMUVnDsUYBJSzkCxmNlH5O7hI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fJBFDGxKaIX0ddEKLuuBEZnHX6sDr/Iye7HigrfmR8cBWOUBscZTs0TqaoYxw/IuatyGCIkhP5IA4kYQP8kKnAP5FzsmFMYKXxmCtgS86a5mA6hwTeYUoh8JnkmHAVXD8D4ZTYiZoXaOCY11pUs9mOz9TANuTlMIJODmZrSs5Hs= 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=crHhfhBP; 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="crHhfhBP" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 7B4C6C1F6C0; Thu, 8 Jan 2026 16:58:50 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B1E656072B; Thu, 8 Jan 2026 16:59:16 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3E345103C889E; Thu, 8 Jan 2026 17:59:14 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891555; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=cErOh0nPQq4JaUTOOkelLy8W6h1AXJeJNMbiy0SldGw=; b=crHhfhBP2/DunogaW8ivUXJKzcXKeaGQlnlYho5TAKDEVI/JFCBwmGieUXdSUCIibPllmi hLvGh7K82nDLhUkUF1LdCjkMTrmuWS1YDmyyakPR/KAhx2ku6SilWX1VR9U6Jr+h1or8G7 iWRi6MsTg2ZQBdz27xB6zxFJ5NbDaXSOvXI3RmsDoXDwCKjCDzYflJSVhdFfP03H57QjHi PJmSgpTFb05+s944CjjUffqBMQrD18DDRhcjEM3J2X4373aR1gm68dD+o/Yx69BRA4eZJA 4J+Icy5QZr/Kr1739G5JOGHSXwIvZcsa9Uj6Y8UMXRt0PDe22M+cladFR6wlXA== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:47 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-14-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 91EDD32695A for ; Thu, 8 Jan 2026 16:59:20 +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=1767891561; cv=none; b=OyvYlnpix60k+JqDQEaESwsyhewZCPrUc807Gc9X/NNen+zDPXvXvm8x2Zf1OqYNNq/OBae237Ff6i99JOy/ygUiqhnbf2yBF1I9h6aEt6Cf46fFX5TXvcI13ss6Mcw4CxrPjiaW57pZKLVm38v3qvKTLRhQaqz+Kc5CQMFPcVs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891561; c=relaxed/simple; bh=IEdX/5NoNXEojE3AbdxR2NpAU6JWoKFqu1WWGh6+dqg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VoqAczmnmmF+wMeiwMJi0HReNujCGKDuqD/a/UshVvLL9QZZS4bukUgKea0bQ96A+V2Ar6V4nunK8d5joar+a/F69Uh3dZ1vy1EmUM21hAbYrUAO/WQPJnCrdszp8ejjzCgkZkdF2Pm9neVxBNDUwMpPwD0Y9kn/5yjnIjh5Hoo= 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=vedhs7oa; 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="vedhs7oa" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 389D84E42004; Thu, 8 Jan 2026 16:59:19 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0BFB66072B; Thu, 8 Jan 2026 16:59:19 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4529E103C8824; Thu, 8 Jan 2026 17:59:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891558; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=fSGWAo4880GBGohVwH5amGuxHfsnb+vsg8Hq4o36l8E=; b=vedhs7oaEeo8qQF/37mjpjEd2q18BDFd1u019iRAUmUOZv5AosrDGwtMlNAm0qfVS7tjA+ RqJ+oZZ7A796AGr9ESZNjGjxp+ySltqe2pl6ScYqxZ4p+1n3j5sWNbir+JvpU4hzwot08N 5/LegNkULQwTtgLSf8JOV2HWsDn1oOrvdN9ExSJMDkXN6EZvCxdkvRm6ikZEgAoiOTqODP 11chydVyNQK1ks4bELJurYHMEpl1IOoRz2lAzpb7Z1/wziaHZuOS+2Nvaud+HCdI+7AK1D 12jZ3TCRh7yUHb8srDeIBuGKSA1Rm+GwMWXrIj21Tig5L7DTBzyDSRdwnzvMGA== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:48 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-15-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 CDAD5327C08; Thu, 8 Jan 2026 16:59:22 +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=1767891564; cv=none; b=lcK8wJPMm8PNFoYPS0bciuZEGv4k+VEhGBVSkN+sQX9zNUtXwTU7A3h2lvQi268oip6CsAgaBl5Erj3sTdRclRp0q0PUWiSRenhQ28BiDhdpdIFQM+jGQbX76jNRrGQHduhJV9vgjCVxyJVwjLnw4bpMGsUuIcJ3VNcrtzElc8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891564; c=relaxed/simple; bh=othZ9uEGhlxCmc6L79S7G0WimW789Md/2pzxa21duZA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q2SC+YdYkZcnZG9qKsiTRg5xzH63i8vuCZIBa2GGw/uniOtD8CBU4uwzXq9YU4NfS4T2GDbDdfOPo4wXiBUglND9I+twqxJI31TKiHq+PB6WYUSdZ8U9dIndilCFTPBP7AYaZlR/LsVdERgySxIW4aVCkWds2mq9G+87CU8rn78= 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=h9hHW9U/; 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="h9hHW9U/" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 59A17C1F6C0; Thu, 8 Jan 2026 16:58:55 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8ED976072B; Thu, 8 Jan 2026 16:59:21 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9E129103C88BD; Thu, 8 Jan 2026 17:59:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891560; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=R21unSfzXWHOBbt64HP6HkJF7cNny7UC0Q5XDAA0ecA=; b=h9hHW9U/ERTF2yyOfkmZse6gw9G0VUb8qBBTNAankEMyG8hu4Et6zLAF4tfGc37ApuSWm0 OlTKcVlfekklpwXu3g5jZ+FW7BmAl8QPtu6p+WmJHOQBdeNIi2OJWFU4XuLKtCYueZUPtV WLlD9SMEtp45N6129YjSr0aGoudCl1haQu+pTySeh3A4FAbunRqYcD9I2C3ErxfqOOEKEM B2AA4N7EI2BlyMLzn9uDTbyn78SzuSPTWNMEj703xm4X6HEIw8UwTMBggpMFWysGpTYVHP l7IRS0FWlSgW9K26CHibBG21nV1satKXGv4N4t4Os7yGW0zf84fhJbIpEYVi3g== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:49 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-16-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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 97da30d9f6c1..ca497ea2228c 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.51.1 From nobody Mon Feb 9 13:17:15 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 16BB7329E4F for ; Thu, 8 Jan 2026 16:59: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=1767891567; cv=none; b=apFR4zcXgJ5sMyBAw3GiX1oehKuiPKws8HRqXDdz+8GFxgUpJFnxLZOBry+OdmbOfWmV2qU1vHTUXrzNLSoa2gqe9DbzvnoOSzzkOP3WD/U46edJQfpqzvxJmX7/dZ8ZI2rbIXwaQaSqb/JD36qLte9V02RAI5k+BmsH4LR4SUU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891567; c=relaxed/simple; bh=ml5YxbTBgMFTzn3cVlCcnkDfoHhrfOjsIhbYyWKZ60Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=R+m3Nzfwbg9eNbEkq3ihEoFeT5fo5WouX1YkYFQI/R236n/VpWvgUd74auL6KWcqbEsjHERlQ8e3kmtgyqvAmnaHtylIyYQu09pbMbH97BjLmlZ8Mo49/R4uCYRxiL0HvM9Eu6w2ENuXjHTOuFEdVXbahIwCnD9Hh824Cha1HSk= 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=Pe8ITo45; 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="Pe8ITo45" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id BE8864E42000; Thu, 8 Jan 2026 16:59:24 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 93BCC6072B; Thu, 8 Jan 2026 16:59:24 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5488E103C885C; Thu, 8 Jan 2026 17:59:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891563; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=5c8b+vAxWRpFsI1z94Obh+lca7KIQv9tXkU1B1za+2E=; b=Pe8ITo4526+onyk7T6qdJKDt5JDKJ+mksmehdsbLjqG5WOEhSfSCKZKK2iUDcaeG/bTmZa ZXT33rR1DkwQ5TU0kJBl4j7/VoKH4o7dMpGpke+njzsDK4Da7LrTXnZCb5ld46oVYMwZxW be3fA30FI4SXs7wk3tJKh+vjGennIVYZ2rs8IToVGSeuCfmpZK6OUBqTtqUQfY6KAGWxce NUKceGz2yz7AqkUYlSsnlPVuQaGaA2iaIva1DJP2exw7N9WYkFwcEyvWgfJ7ZjHEM3aPxO EkNmZTZFmeZ44hT9qDW90f4tJEtFOYk5awWn0qGqsGkXGifirQgOAVHfbnxQ1w== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:50 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-17-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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 | 4 ++++ drivers/mtd/spi-nor/debugfs.c | 22 ++++++++++++++++++++++ drivers/mtd/spi-nor/swp.c | 11 +++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 091eb934abe4..99ed6c54b90f 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -707,6 +707,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..821fbc9587dc 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -77,10 +77,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 +161,26 @@ static int spi_nor_params_show(struct seq_file *s, voi= d *data) region[i].overlaid ? "yes" : "no"); } =20 + 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", params->size / min_prot_len); + } else if (!lock_start) { + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_length - 1, + " locked", lock_length / min_prot_len); + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_length, params->size = - 1, + "unlocked", (params->size - lock_length) / min_prot_len); + } else { + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_start - 1, + "unlocked", lock_start / min_prot_len); + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_start, params->size -= 1, + " locked", 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..8de8459e8e90 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, --=20 2.51.1 From nobody Mon Feb 9 13:17:15 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 A9EE832A3D8 for ; Thu, 8 Jan 2026 16:59:28 +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=1767891570; cv=none; b=BxdxZku36QS35XJvP7f7vhPGGPPBOSa5gNwP4/VPUSE7V/ICHKG/LAcqK4PhAFmM1aypY+MaOXxsmYrUs1FFo+bymCsAjnoVPIhCGojBRDMdZ7SkJ0xg2b7K3kmWDsYV8MwQCmDkmRlMjXppgd4nVquGdTWBWlvFgOHm8BmNHeo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891570; c=relaxed/simple; bh=Ld59UxSEo/UsBCpweXeilf08DZY2sXsNZ/uX7VY4k7Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=V6A4Ek5H4/g81P0Odqv9qhMlDYdx5GpxEMEDjbqCvKhZ4L+zz2/z3T2mp/sOmGHBdSIwXw1UdfphaeTvbsVc2QTzLcjyGrJBjCY1fdw3qh/kDIpzKVHvnld6M0BnTyNYbGUm2qH8cjr7yww26c6HrV/C84f+Pmv4QpkWY41SYcs= 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=D4K5Kg9n; 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="D4K5Kg9n" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 61AFE4E42005; Thu, 8 Jan 2026 16:59:27 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 35D556072B; Thu, 8 Jan 2026 16:59:27 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4CABC103C88BF; Thu, 8 Jan 2026 17:59:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891566; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=b9DhezCPS05cjlNZjYeTSMYdKUnSbfB8ozmwS4/HxAA=; b=D4K5Kg9nFcRvoQHcWCj5Rc7igbtF3cY+SNhf0CWjgRNGOMCcSjOmhb8i7qZhO4BU7HK1vi ZZ2r1PCXMGP46Jw+KzLbh2nFKIgE7OxI7meJqqPMnCknR+U6eY6e412YFYqrgKB1R/74++ z42tXU5otz4CUwQzKf2eXgR7bY2PSsgzocyQTs2AlUYZ+7TPpdid+9NiULzU+IIyBDl48n 6XTV397aQukNaPm5/1KaCXIuP29KXx22nFXXiYuaq9qa4rezayZ5K+E032TyXc9sleRGek MQTawVXYgqDfzSRPdxLkKbtn0JM0gG30fIelXahzcEb7UwvB7xe6EZPspHn/1Q== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:51 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-18-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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 | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index 821fbc9587dc..c290bfe20f73 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -185,6 +185,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) { @@ -270,6 +304,7 @@ 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); + debugfs_create_file("locked-sectors-map", 0444, d, nor, &spi_nor_locked_s= ectors_map_fops); } =20 void spi_nor_debugfs_shutdown(void) --=20 2.51.1 From nobody Mon Feb 9 13:17:15 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 DABE532ABF1; Thu, 8 Jan 2026 16:59:31 +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=1767891573; cv=none; b=Mx160dBGt4hQMFrLj1qhPzh/1uoRSn7Rmpd9qu79/yhkDHWRyWNPxyk6sssrF2qnSotuhLP5v+GdS7ujqrIzL5qylj4EGpSGy9QeONHa94BpCgYei0Loar0ZnmPmDh0KckvUjuRuBBcNUhQapCJ20vtKjMhW6a9GY3aKFAWdt0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891573; c=relaxed/simple; bh=CfDGuastMJOuxN8t3uMRhNG36tz6y42aN0NN4oRj03E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KEIVFFmlXyAdRJ0GA0E/Pim/R+wth2IIMA2DsqwaBZR2iUSD8cfO955iUOUSBRNO6r8ezgpF28tXYkiv9FIbagZG1mzgFaGN3/g/yxxfxK+32UViyvTNvKFPfH14QhT887bU1n6W7QSXXWPIiww2QApO8PwIQ0aidXs/lfv/CdA= 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=sEqkTjep; 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="sEqkTjep" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 869234E42000; Thu, 8 Jan 2026 16:59:30 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 5A04D6072B; Thu, 8 Jan 2026 16:59:30 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 02ABD103C86ED; Thu, 8 Jan 2026 17:59:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891569; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=hhd+i0LUsTLSToudA1/3v4V3xTFwJTwzl9JTAHOOnfs=; b=sEqkTjeph7Y/Qe6jPI1nKBuwVNtPvh6LbFDVrXuqxn7+xzZnHQeaemEyk/vJnHUeZzmkVY +bFZCH6DJaGUJGDwiBhSoyWR5H6VhNu2VQM/PynJJ0QdKOwguylqfUXN+b26+mtLrELmWG refCnaWRV9q6Dlps+dFQn6A5J5wG8LE1bNye6qWK/uEIGofOOudVVUeBNQB/D/P28qkQcE A0rhJ6LrT4hZnyUFvK+sLuPWllKRdWSyXefsA6K4bwJF7Nsc8hhbfUZdYtBQWEIepHBspu YkdJdnesBAFNxpGwq50iGlAE3fY7aodi3CllPc5G8+AXZbs1o1EMRdHW1rpavQ== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:52 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-19-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 190652F6910 for ; Thu, 8 Jan 2026 16:59:33 +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=1767891576; cv=none; b=DDON2f1OL9tDdxuOx3zYZNvXEfVf7jsgTZJ75A24A7cqRJbfsY+o6P/j50lfJw1AHCTLX2zCYbKmaJvxyCFLSy51TYSdhjnifZp3pLZUYQKqfAVtbifSri3TMu3854WhqGtEOwpAXBOSqLCN9BStkeM7rz5i63QxIteNPk34i7A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891576; c=relaxed/simple; bh=gFu9/k6icYSXldkj0RgQYbbMBRBIp6g8oiUZ/MYvuG0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eCzbVU1QvsXBBPil6cgUcRrrxM+YpiRem862NVEjFrUmC+RCuEDThX6bMJ5Q+/oH7ROkhyzROzk9ArMxAX/htjv4ADTopQyEWS8JApeXKJoyTEq5AT6gCamN+UjInGNHNDW+Sh+Qg56Na5o1Ob6Ba5kSzCC/trb1Eq9GTw4Afcg= 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=xlI1ODuw; 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="xlI1ODuw" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id C543E1A2715 for ; Thu, 8 Jan 2026 16:59:32 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 988A66072B; Thu, 8 Jan 2026 16:59:32 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E863C103C8811; Thu, 8 Jan 2026 17:59:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891571; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=lS3yKe30oPVtcVh3fJLk4kIteTtM7pxix3f8UVvRihw=; b=xlI1ODuw6wsFSj9NYO+iM203MWliHUR9aXJ58v6BlxNrYJXtdKJkULyB8xfvtxXEw3+Z4l q8BwBO7N7TQzgnGHXCOioGWxxvOeeC/Z7eRihwciHpetMiRTJXCziZfOu9WhnZgyeMRyR3 iqfxF0KQ9PQV5haPwxl0pf3SH2B+ZMN1kvjXg46ZTE29A64orZPbuK7Aj4GBSC2EPHp99e 1YeceMmw2y9ZDMj68OFq4AvyNqpNCcEAsocxeE5dA+qH4gGYoC5XNCcN9j0IS0HgrQuNjp NIa7PVezScJUBnv/zYKp0oLz5pBmvZoi8h1h/YKGLCbsddany8bdADzOH63OeA== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:53 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-20-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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 ca497ea2228c..93fd32d54c12 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 99ed6c54b90f..333786913ff1 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 c290bfe20f73..fb6240dbbfc6 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -29,6 +29,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 8de8459e8e90..ac405b1daf96 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.51.1 From nobody Mon Feb 9 13:17:15 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 E1EB732ED29 for ; Thu, 8 Jan 2026 16:59:36 +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=1767891578; cv=none; b=sgK/0opcasrVIr8Jaeii8oEA+OVo++sprYBRxDPEtoA2HTJWS7Imxhy1FAIq8uKuxiojT8KPakwClXuugSRce568qjLD8YfWFXy/eoDhdc2Vl4pdOGUq6GOLKiu+2vwmp/kvBAOiY14elJyCqbhKuQ9mjTI3ijJ2ogJuUjZe2w0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891578; c=relaxed/simple; bh=TvmwqqzUjFXwsgjs9g4DkmvOJ12nKokPN5kUqwA0B18=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Wa/CnRLiv+37SmfnhKz7mjlplK3iQOiIokcmm7eMrejLfqICm+5JzIujvcR0SGo/0kE8KyHaukPq4CrJg50yypbAKPh7QgprhZIUV3IbkWiEARyWoJsYG+mxUCQgEuqRvbrGetWOz1ZAQ9ogRmNEYvLVSdMo6pJ7OWI8qTGabi0= 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=S+00iNNj; 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="S+00iNNj" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 3BD4EC1F6C0; Thu, 8 Jan 2026 16:59:09 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7276A6072B; Thu, 8 Jan 2026 16:59:35 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 94142103C880B; Thu, 8 Jan 2026 17:59:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891574; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=7/ZShnKFDMohqlPS8rHFdEyfu+4BivJefw8T/oDlCwI=; b=S+00iNNjvgZcAfyd4V1qoR1VVqXIxXGy3x+Lqt6HWh5Wp/VMtUmQB5bL42LzyD1bbWzizB jouh6slYtIubmWH8zr5xkTJGpg6t4KUOw2zFDxhrvsivtrgB3l4MAV1dqStolnizp+Li8Q 6T6QbUCIPD6kFwwXaBFQsfkGpe6fZ+nYc6X2tCYcU7drqU7D38HZSmHa2OmXOm19AS1ame TpvnJLTbzo2cRMF72+P2f8UzS04jye6tJaM1EAr6nhNmZeuYyPLlf49/bTpU5qJDMwZ2jj IPJ0de2b1+eNTzS3SyQRRer+bpwhLkYTA75p6CZIgyVbGKx6+T12AwRGelvoPw== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:54 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-21-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 C6EB03314A4 for ; Thu, 8 Jan 2026 16:59:39 +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=1767891581; cv=none; b=OtWhDVq4a/Y2TAYNoBp5YiRHvH+FcAW2dzN/U4rDPz7Jk9/MzGvp5rK3hAQNDpcilVdzGh579tSM+G9DKWG6lOKDtPpx13vEP9W3ZCxpPw6na+7gIys0llmBGso1sEAGvSIeq2qlpfJFGueknVq8/UJTfUOwzKnaHolj1klmyzc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891581; c=relaxed/simple; bh=T+tc8hlQUoawOQ4PZOcmI6S3JEvYe1k+xqcb9/crEKw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Biyn2txUrpbTsk/gA+TBbPS/a5Hw4DHBf6b45QHsEukWM6UG036ho6FTwhr9AzpHtd1THaWLV2pmOIW8nlC7lXjxjUtzuU32lD3WdgMLOnwe/cPNTEarRkus2MCsSXUX8EBhvTBUIs19+dbcJCKIlGkuiYKZ1UNBat5v8pOrLkE= 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=Lp+DL/33; 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="Lp+DL/33" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 68E504E42007; Thu, 8 Jan 2026 16:59:38 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3DBD46072B; Thu, 8 Jan 2026 16:59:38 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 23666103C8824; Thu, 8 Jan 2026 17:59:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891577; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=3UTw9aN/2yCK3EvGO8QBuf8zar07N1b/IrNqKvh1CgE=; b=Lp+DL/33QEXrIt/JPKUVsroCGNq5iYZJQUUyT2ND2SBgJbFBtwhMrDCtQfopkVADcgdVIF baS3wb3IbYW8kehAmbz/4YD+b/Z/yjsXMEjBpKQRfLsD3pFvvokDoW+BZS14wzYl4KN538 0Je+/GH7YMk9AOQ6c6XN82a/+hoE+BpltphzS45TK65d9PKd3+Y6pL45Iy2Y4khJyG6Eoo kCOM5Vzt59v8kmAEUxsyJEIrAwrzEZ/+ZNn4LGmymhj4D1RjuQLO91zrhxleAHchMi26nF MZF2T0nFYfdqk4zfWDRPBJ9uuI3xc+uICy6tDoylR9FgwdOZlORY8fxDNcX+7g== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:55 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-22-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 34C0B331A77 for ; Thu, 8 Jan 2026 16:59: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=1767891583; cv=none; b=BDmkhWGS1Tq3UocTxe4QKHitMleIHi5KQxn1TL2WPLZ5BdrcelhSluuUj79FbnUYXrQA74/Am8j9lKItQJF6ntQHe1JbbJy7HAMVwNQ9AKyv4JGonVR1Wo2pKke0SoH2yjhjNCVyY4xzkq1drms5f4fbed0ItyGEudiVCgSA7Hg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891583; c=relaxed/simple; bh=7z+G4gGu0layZ0rMETFyDVmH3kWMlm3XiQ03nIPpW0M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=L1dGSlJVqo5U2FOrgDkxNHA7M2OOQvhsLAl0mvxEix96ImtwJ2NLfxZJ51JL81t01Km8En9jc1Iw9gshQQU1+YgMPz0bSlniIAAb20y7Jjkbw+0HJMSxNmm/4Phbq5AuMWPgAAeVmhsEHAftlpeIV57pC9bJVQeKIkaK/SzFUAc= 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=it4yGP4h; 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="it4yGP4h" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 9AFD6C1F6C6; Thu, 8 Jan 2026 16:59:14 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D22466072B; Thu, 8 Jan 2026 16:59:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DE366103C8826; Thu, 8 Jan 2026 17:59:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891579; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=MeVqIfBpy7cynYdckZP4tUPjyA2vBhyS34Ryk6tlKjQ=; b=it4yGP4hCB67VB+0pmRM8HtlWLW7mjEc6QxJxkb3RwAjGLJevPvS7Gh5qBM0+zx4PEx7zz f3RELR+N6OXRWxJEC9J7nE7vUHFw8bmBXnnSDoIq1d6wTa9FIJG9kPMIoLPx1d+bHm4/EA ra48rHbqWRWqLBuU3bwaA8dYSrKjRPjIa9NkaVIGSFWDOE/rh2gEXqvvmwyL5IWx4FaxMH q5Zzb2/iSTqldpVNTpff5ExC7M+tZNIC9Xv2/3jUAQBw6PQhexcw8FXqeDC/DAUilcLL8b Hzm849dzffm+WXc+RnSA/dyaiZdav+BSDrwEm//4VziVYvPPrq9XAgiAttOc3g== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:56 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-23-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 748A9331A76; Thu, 8 Jan 2026 16:59:44 +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=1767891586; cv=none; b=tpKdyT8+uM/8DtGcSLLIY0bJ62wGib5/EQ2h4AzAAJsJuZ9Sja9oaa90hMynbguXIX1N/ah2z2az/rgqAcaa1VvYpLe0miiZ9PRDl8KcB9LDfVyO7/Wym/WnT9dZB2sDL0yNlprLRiHVaQMDNTvUffC7euVz3b31DzB32mriPlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891586; c=relaxed/simple; bh=hPvA0tKW8ClU+nBEBmDCalBRjKUX6q96REMS9eTru9c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=D0vFK7q84ibJ6Aopz5L3UoPkUPwGzwD4yTGoG5NrMtKK01Pb3Ca/tmwSuTxWslcZsp/88BuF0nyt8hdaXaFLNKV+ZfyU3AHogee8zc75UkwV6H6KjCtNLP8YTH/QEirc27DVv32hgfLFIN7DdNerOPsTIMv7oDt/0jQC4nmR2t0= 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=OuU6d/rq; 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="OuU6d/rq" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 55BEC4E42005; Thu, 8 Jan 2026 16:59:43 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2B1E56072B; Thu, 8 Jan 2026 16:59:43 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 712A1103C8897; Thu, 8 Jan 2026 17:59:40 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891582; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xcYJgRzc5IqRAQH6jo52JPsF7X3RMUjzZg/GlVf9yBA=; b=OuU6d/rqHnFnL/dJucYXq+OFx1ZTFwmw+mz+XtdYxAeK4npMpb3E53xKYewBSkVIvqeQLZ 1nROS63axgdWrjVS66wWso266esV/87XgWhwuOZplkZxHK1GPJyyExIyzqouRL0DncXmNy UV2HeCe7WNEuqEg0jaBdvK005nnu7q4J3qm54mAmKEMvtJxpVbkIsQAybTYDwT7kDDNs/e 2AyLmXIaXX04eSxVfHvo836blGcxkr6qeMhimAjnTi+WvUxuZ1CLSdZkJ4y5Bcgj7rPInD b+DWFmdSleKzA1hrmvmIlzmfmCv+5wKEYIPd/bQ2EaZ01e+bS8Cbp5zkMgJVAg== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:57 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-24-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 4E5A63346A6 for ; Thu, 8 Jan 2026 16:59:47 +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=1767891588; cv=none; b=dFC483yroPJr8D+/Qp2fgnLEwoEQLAx5D/9HToQ+lossFLCPfx9bBSW7najqXZRkFooqxWv/FfcU7TxmG/q1WxCdnu3yK1n+NciZYxAv4XZsgr/sB00Gub3m7/C6Ptysq/P/VOs4+0tMuU6Fvh4dYSP0n+JdHwATCpB28CUHS5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891588; c=relaxed/simple; bh=Yl80iODVgcF61pX+l543yMYgtqmrTciYNzPD8N0Aq4o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=m+W8SZva79+M5JFrfpfhVIsG4Hwi2Y3IdFh5zBncPaAY1GOwyQf7CCqWgQB9JI5MGIsbOWtVotg2bbJMNE3A20K2aJwPjfHm5ss96yTYtI/vPagdFcofebUAOfT9tZTU7x22uNn5VG3DqDzjG5y/6/ZYfa5wz+Li1tlBLh1kWVo= 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=uPcQ2bLA; 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="uPcQ2bLA" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 0431F4E42004; Thu, 8 Jan 2026 16:59:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id CB5256072B; Thu, 8 Jan 2026 16:59:45 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 267B3103C8889; Thu, 8 Jan 2026 17:59:43 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891585; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=QsgGWiMFLmhabGIErgqJOAUgQ784tBeVIxY9n1SL9Sk=; b=uPcQ2bLACBAJu0oM3HVxOs5YQ/P95XBhbQZHy8NnNNiHp4xqvabeUrvNiWlbN1MTb59383 GN5bAKdjv7A8HvNeAtVsG16u4l8PDiCO3CwdQHMNUwDCE7zuI21cXlingDpwiLzUqKJblk 6u8Qs25y91JkLAcdzQuP7MfX4F1tVVB51tP2qt5qcghyUlC5f1r8snTYpZuzVfvlKUMS8u uSskmVQjHhHO0MdzKaW8P3/0Bx+WOxuhzJru/8ISL6hW1CpuWTV7NPdZVSdk1Z4Cm+QITP x+/LEkp5VKTptB54b5DjJrupbCQpm+JWQTd07hnTcc+0HWIHi5rnitf9RNHGrw== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:58 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-25-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 BA1EB334C04; Thu, 8 Jan 2026 16:59:49 +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=1767891591; cv=none; b=hDtts5cRDvOqf1hnfpLUuJmugA8PeEp028nV1aEjjdChycHdLCmy0YgW2hXnkWZvxO0B8OGG7iBBx74cDbPC+UIPfWYOOmAUU8Td2u1k5P1FvQyCUnVsBC/VP7wpxf47Y1nGcwYtcEgxvxvxeQtFHn8FqK4KjxzQOTIukPse5u4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891591; c=relaxed/simple; bh=tlvQp1bZ7+klWZfcbfGIXVjcUoWUKKWDjg3IvR83O/A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y/9xWB58nbXyRBhihZm0BCw8hc4LQ3xSSZsNaQhk/s40nZ5dG3SaL6ePtq/SRZ+02kj/bEEqPUTlP6H0QhKg4VxyQDaD1ne+M8QQ28HvLdBWgQjexKmAcqtDXWorxfGYYXbzVjWcx32d7hcUI0cGhUrAKwy/jGG/NemJG43xm94= 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=Th5tHuVk; 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="Th5tHuVk" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 8379A1A2713; Thu, 8 Jan 2026 16:59:48 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 582176072B; Thu, 8 Jan 2026 16:59:48 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 94D07103C8896; Thu, 8 Jan 2026 17:59:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891587; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=aQ47DiGaPfkMamCb+o5HDFv/4Im96jTt1ueTmPftQyY=; b=Th5tHuVkkQon4UDr24U/Nekf2iX7fIUIY7Ns1i2z26g/qD3sJKuHB7TTzYEJ1gGLW4HUz2 ZC4cA2zFYth/0f5eLqhEu9vmKaGfgOzQt9yKIWH48SO9l+qPOJwCFV7gT53xupaMaBhUl7 04GhdkfnZYNKrlIer71sk9KMfa6ng+91vVYz2asKpAJ+vqXrB0TkuwvkEGh0HG3ikpurYH M2qXqoZ0Zgb0tF45efmfIN/pHedLpvkfyxi+2Z+JvDv9gM9NWSpdavs5WigstJwzSdjNhL qiwBiF1hwR9mUHoc9RZuHCPs59eCwbT/SnN29lvSbMj2c/RXx+CUDuCGJhHEyQ== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:57:59 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-26-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1 From nobody Mon Feb 9 13:17:15 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 3D4B22FD1BF for ; Thu, 8 Jan 2026 16:59:51 +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=1767891593; cv=none; b=FOQrxz/iI7gDw9AU87dF8Bf2aqL9LCrfMczbs/yFvItshxDIQdYQB1VsBQlmMNC+hoX6uv4ECayYrvKdPgmU4dDp5OMTlHhk85ouLWF0Ju27xuNk0/ZA7O++Y0qHtWjCUenFlRiNEoXA729yulqSraxr1tF/cmMHpDrnnbmW3UY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767891593; c=relaxed/simple; bh=OAsshR8taJxBMFFyddHaDNJSHSzI1SzbRqNeGRPBYZw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ogf1ELd1CyQK2js58lrxL/Bum9Muu6X8gWflgM58cMfN/2X7xzKjYq+tadwr71CN2DhQLLviAYIo+vFBdnzi0KaawbhLB5DRaSnC8EWT4JGfe1XWl2B73rYRumtlpqc/8psrPtZipPPpRGSsgBSLb/4awBI7kDKeBD0KJd/mbH0= 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=mEJDDeqb; 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="mEJDDeqb" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id B09CB4E42007; Thu, 8 Jan 2026 16:59:50 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 85F2A6072B; Thu, 8 Jan 2026 16:59:50 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F2F64103C86ED; Thu, 8 Jan 2026 17:59:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1767891589; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=wXJyxTh9zUcQqoOPuD+RgDBVRNZuUe3FPkKCommQgVQ=; b=mEJDDeqb/jbPrF6UXkoJQOsGfgqLRBTNBmBXDtoBoIgn+4TAKsAPVsqIIcrQs7wWG8sHEK /W59zlpTdtbaJ0JdW+coJsi0k7J7Ec4zgS58AR1OqjguX+GDF8R6x8xzlaBmwwBq0uG0vS RR17Jx8Ehxhlz+d28PJ//I3hZfdx2GR4HmXBCq836bJOyTcKDf8IQyKsw9DEDczS5YS27f 7uTqtRpr7qgDUDpHFj5YX6iWwoaidrNuh1IDzQUYe2bt31NXyog/4MKD8J2S4/KzevKa7X qKINk4FELT5g38+56H3mgFYejZ5RipGLUsEob9prKdYKiEXktCej3i8GN/pljQ== From: Miquel Raynal Date: Thu, 08 Jan 2026 17:58:00 +0100 Subject: [PATCH v2 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: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-27-c462ef806130@bootlin.com> References: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> In-Reply-To: <20260108-winbond-v6-18-rc1-spi-nor-swp-v2-0-c462ef806130@bootlin.com> To: Tudor Ambarus , Pratyush Yadav , Michael Walle , 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.51.1