From nobody Thu Apr 9 09:10:03 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 D34853B2FD9; Tue, 17 Mar 2026 10:24:55 +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=1773743097; cv=none; b=pq6JI4nnYFTc5XbbENsphg0gJv8LRXOqOaobdYK3HI0fpAH5LZKDJDJaNHPDNFWYW3gjQMwUrq0ii2QJhoTB9Alhav7KWCwElYfD2fuIs06POmCJMr6A1OYiwcJ8twC15XiI/6IVUhj/kroxwuv5XviNPkRhSBwm9Jc9hZ/j8/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773743097; c=relaxed/simple; bh=hPvA0tKW8ClU+nBEBmDCalBRjKUX6q96REMS9eTru9c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IZE3MaUPRI3x+7pqQFLb3p5vUbogTuwKOgjbNNx6Unvf/ONhQPNGS2KV5DlbDh8oCbtbfzvdcTnVR6CKmfhMX3kOqtvjGa/sJB/au9Cs85/oGBF/J/ZneKNKwzVef8LreWUXcdmeOMQI10Mn3DIulAWovqjYUy3reaUATU6dkMg= 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=zsTXqiQt; 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="zsTXqiQt" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id B9D911A2E8A; Tue, 17 Mar 2026 10:24:54 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8FBA95FC9A; Tue, 17 Mar 2026 10:24:54 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9E6B91045044E; Tue, 17 Mar 2026 11:24:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1773743093; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xcYJgRzc5IqRAQH6jo52JPsF7X3RMUjzZg/GlVf9yBA=; b=zsTXqiQtHZcs9t5+zl3QvTEc+PAi40iPT9o2CqO2e12C1/oVzWUxgnFBFzrCbfNEbMjZbE f3KEI/c3g8KqJJpnhDFyPD5n2YNKoRerCEBFUUfEESWvCoHrWfuGmT9KouGBlJZdDL+Yd5 Uup43kKZxM7B0r6vTcops4yuKg/Diel3theJkyWaEE8YZKoinCwtVozVTQbfPmEzr/9DSE XDQ/7yeIifYIdLQdBWfxW39Uj4ViOQ8OYLMrfG56zgdU5tg54hL7/pZqW3SdRM+2PBvjHf bzpGlaFv8r6viVoyhQVK/DvwzPD13n/22Uih+gjY8TsEoSWI03UqgJNKjmjd5A== From: Miquel Raynal Date: Tue, 17 Mar 2026 11:24:27 +0100 Subject: [PATCH v3 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: <20260317-winbond-v6-18-rc1-spi-nor-swp-v3-24-2ca9ea4e7b9b@bootlin.com> References: <20260317-winbond-v6-18-rc1-spi-nor-swp-v3-0-2ca9ea4e7b9b@bootlin.com> In-Reply-To: <20260317-winbond-v6-18-rc1-spi-nor-swp-v3-0-2ca9ea4e7b9b@bootlin.com> To: Pratyush Yadav , Michael Walle , Takahiro Kuwano , Richard Weinberger , Vignesh Raghavendra , Jonathan Corbet Cc: Tudor Ambarus , 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