{"id":2219643,"url":"http://patchwork.ozlabs.org/api/patches/2219643/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-mtd/patch/20260403-winbond-v6-18-rc1-spi-nor-swp-v4-13-833dab5e7288@bootlin.com/","project":{"id":3,"url":"http://patchwork.ozlabs.org/api/projects/3/?format=json","name":"Linux MTD development","link_name":"linux-mtd","list_id":"linux-mtd.lists.infradead.org","list_email":"linux-mtd@lists.infradead.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260403-winbond-v6-18-rc1-spi-nor-swp-v4-13-833dab5e7288@bootlin.com>","list_archive_url":null,"date":"2026-04-03T16:09:31","name":"[v4,13/27] mtd: spi-nor: swp: Create helpers for building the SR register","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"2f0919d680a669814d7470faab147f7ef82a331a","submitter":{"id":73368,"url":"http://patchwork.ozlabs.org/api/people/73368/?format=json","name":"Miquel Raynal","email":"miquel.raynal@bootlin.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-mtd/patch/20260403-winbond-v6-18-rc1-spi-nor-swp-v4-13-833dab5e7288@bootlin.com/mbox/","series":[{"id":498652,"url":"http://patchwork.ozlabs.org/api/series/498652/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-mtd/list/?series=498652","date":"2026-04-03T16:09:18","name":"mtd: spi-nor: Enhance software protection","version":4,"mbox":"http://patchwork.ozlabs.org/series/498652/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2219643/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2219643/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=IPagMqsK;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256\n header.s=casper.20170209 header.b=KEnwPFjK;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=bootlin.com header.i=@bootlin.com header.a=rsa-sha256\n header.s=dkim header.b=LUXasgoY;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fnNxF0Vj2z1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 04 Apr 2026 03:10:41 +1100 (AEDT)","from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1w8h6M-00000002HfS-25Zh;\n\tFri, 03 Apr 2026 16:10:30 +0000","from casper.infradead.org ([2001:8b0:10b:1236::1])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1w8h6I-00000002HYB-1eqK\n\tfor linux-mtd@bombadil.infradead.org;\n\tFri, 03 Apr 2026 16:10:26 +0000","from smtpout-04.galae.net ([185.171.202.116])\n\tby casper.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1w8h6A-0000000EgaO-2JwI\n\tfor linux-mtd@lists.infradead.org;\n\tFri, 03 Apr 2026 16:10:24 +0000","from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233])\n\tby smtpout-04.galae.net (Postfix) with ESMTPS id 8A260C59F65;\n\tFri,  3 Apr 2026 16:10:40 +0000 (UTC)","from mail.galae.net (mail.galae.net [212.83.136.155])\n\tby smtpout-01.galae.net (Postfix) with ESMTPS id 8BF11603C1;\n\tFri,  3 Apr 2026 16:10:08 +0000 (UTC)","from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon)\n with ESMTPSA id EE5CA104500F6;\n\tFri,  3 Apr 2026 18:10:04 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id\n\t:MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=Adk8VpQWzgZzGmyFJxmXdCOWq10GWyJCLwKFRGXEieU=; b=IPagMqsKQ5mwT7\n\tKM36UQrF2LlJP12cYW4EveEs5gpqwNnyHVAesmefeNyY9ChXSHqKdkQv+cOfF5uL/e7OVOl7nQp5C\n\tzvKVg1c208rNM981pxvJaW8m8KmXklbQqHgq4ByOUIqsSyoe74Lt0DsjfGhYg0NZR8W6R6S9hqwKE\n\tTq9+kW4Kft/d4JbXwP8kB/9iOUZXbKZnkR3i6au1sshNFnCCPKG7COWWs29Qib0NEEag65YoMgoSy\n\tI4jtVKMjFwFeblWKzn0j+Oju+ZLD+483nTaSgxwZ3k22O7qJsx2k6N4MTBvuo5RrwcMfMpcOcnbc1\n\tYG4W6DyN1lIxZhaAb+IA==;","v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=infradead.org; s=casper.20170209; h=Cc:To:In-Reply-To:References:Message-Id\n\t:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender\n\t:Reply-To:Content-ID:Content-Description;\n\tbh=xzSy+EhNI9t9zTqMF1NixCi1hFBNiZkvrrCmxjn6Qww=; b=KEnwPFjKUo2nJnTpOjEK4wKVoa\n\tUJr6+7juki0EqmNNQLP7ySY6PNjkTBApS2iZR/XCK1zDkkEad1ar+sQDcnXWR9YL7BmfmM/1rjOk8\n\tsPPKrvrORnspW4ur6KMUtcqmgRVSRp8VVcogkDau4eP2LG5zEL9kbyVVpMkHyYnnyO5reC5BFYsjt\n\teTCkSyZho/eEJ9dn07bVjvrvbd7t4TZQPFxdn2HOhx/wDXcrAcW0OcplYlYkI/jZN4dV0Fz35X7bI\n\tarVcA4N/SeSKYk2Wtc7UV3vX1Ncu31rYbTx7f9SBakKZXBEQ6wHmsUFiECZAi8Ovn6/3CVxXmbRmA\n\tJe/njzgw==;","v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim;\n\tt=1775232607; h=from:subject:date:message-id:to:cc:mime-version:content-type:\n\t content-transfer-encoding:in-reply-to:references;\n\tbh=xzSy+EhNI9t9zTqMF1NixCi1hFBNiZkvrrCmxjn6Qww=;\n\tb=LUXasgoYgUxnSYaqKpNjymZ/Qvv340Urc9Z5AxflgEzL0mlHnOmx6ujlAOqq8HMTe4RnKl\n\tSqWLHFfhrDHx0Jp89i1tlZ52r2t5gkEnWBCJ/HR6dAZailfXtM/CXeibU+TJz/xNvDFmuP\n\ttBJthi+c4CQUWGOyXv9KKXt8PEQ6G/OFY5niqOnyn3bGp3JFoLke9oQprxN8WA9auU1M34\n\taa077vkc3vZVDiBF22ZZH9Db51bP0uqyS3sA3+L/Hj910K6OlS4zRwaNfMgpmDdd2ZS0nt\n\tCAr7ryl50sDv8YyimqmbKU8MARmDz0mnrHk0ZFHeWxgC/LSo87ber6jHXSw2ag=="],"From":"Miquel Raynal <miquel.raynal@bootlin.com>","Date":"Fri, 03 Apr 2026 18:09:31 +0200","Subject":"[PATCH v4 13/27] mtd: spi-nor: swp: Create helpers for building\n the SR register","MIME-Version":"1.0","Message-Id":"\n <20260403-winbond-v6-18-rc1-spi-nor-swp-v4-13-833dab5e7288@bootlin.com>","References":"\n <20260403-winbond-v6-18-rc1-spi-nor-swp-v4-0-833dab5e7288@bootlin.com>","In-Reply-To":"\n <20260403-winbond-v6-18-rc1-spi-nor-swp-v4-0-833dab5e7288@bootlin.com>","To":"Pratyush Yadav <pratyush@kernel.org>, Michael Walle <mwalle@kernel.org>,\n Takahiro Kuwano <takahiro.kuwano@infineon.com>,\n Richard Weinberger <richard@nod.at>, Vignesh Raghavendra <vigneshr@ti.com>,\n Jonathan Corbet <corbet@lwn.net>","Cc":"Sean Anderson <sean.anderson@linux.dev>,\n Thomas Petazzoni <thomas.petazzoni@bootlin.com>,\n Steam Lin <STLin2@winbond.com>, linux-mtd@lists.infradead.org,\n linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,\n Miquel Raynal <miquel.raynal@bootlin.com>","X-Mailer":"b4 0.14.3","X-Last-TLS-Session-Version":"TLSv1.3","X-CRM114-Version":"20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ","X-CRM114-CacheID":"sfid-20260403_171018_673001_AE52DF1D ","X-CRM114-Status":"GOOD (  13.77  )","X-Spam-Score":"-2.1 (--)","X-Spam-Report":"SpamAssassin version 4.0.1 on casper.infradead.org summary:\n Content analysis details:   (-2.1 points, 5.0 required)\n  pts rule name              description\n ---- ----------------------\n --------------------------------------------------\n  0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The\n                             query to Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                        [185.171.202.116 listed in\n sa-trusted.bondedsender.org]\n  0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                             [185.171.202.116 listed in\n sa-accredit.habeas.com]\n -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record\n -0.0 SPF_PASS               SPF: sender matches SPF record\n  0.1 DKIM_SIGNED            Message has a DKIM or DK signature,\n not necessarily valid\n -0.1 DKIM_VALID             Message has at least one valid DKIM or DK\n signature\n -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\n -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from\n author's\n                             domain\n -1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n                             [score: 0.0000]\n  0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                           [185.171.202.116 listed in\n bl.score.senderscore.com]","X-BeenThere":"linux-mtd@lists.infradead.org","X-Mailman-Version":"2.1.34","Precedence":"list","List-Id":"Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>","List-Unsubscribe":"<http://lists.infradead.org/mailman/options/linux-mtd>,\n <mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>","List-Archive":"<http://lists.infradead.org/pipermail/linux-mtd/>","List-Post":"<mailto:linux-mtd@lists.infradead.org>","List-Help":"<mailto:linux-mtd-request@lists.infradead.org?subject=help>","List-Subscribe":"<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"\"linux-mtd\" <linux-mtd-bounces@lists.infradead.org>","Errors-To":"linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org"},"content":"The status register contains 3 or 4 BP (Block Protect) bits, 0 or 1\nTB (Top/Bottom) bit, soon 0 or 1 CMP (Complement) bit. The last BP bit\nand the TB bit locations change between vendors. The whole logic of\nbuildling the content of the status register based on some input\nconditions is used two times and soon will be used 4 times.\n\nCreate dedicated helpers for these steps.\n\nSigned-off-by: Miquel Raynal <miquel.raynal@bootlin.com>\n---\n drivers/mtd/spi-nor/swp.c | 83 +++++++++++++++++++++++++++++------------------\n 1 file changed, 51 insertions(+), 32 deletions(-)","diff":"diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c\nindex f068cb9c8f6d..e2e423b20989 100644\n--- a/drivers/mtd/spi-nor/swp.c\n+++ b/drivers/mtd/spi-nor/swp.c\n@@ -123,6 +123,43 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, u64 len,\n \treturn spi_nor_check_lock_status_sr(nor, ofs, len, sr, false);\n }\n \n+static int spi_nor_sr_set_bp_mask(struct spi_nor *nor, u8 *sr, u8 pow)\n+{\n+\tu8 mask = spi_nor_get_sr_bp_mask(nor);\n+\tu8 val = pow << SR_BP_SHIFT;\n+\n+\tif (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3)\n+\t\tval = (val & ~SR_BP3) | SR_BP3_BIT6;\n+\n+\tif (val & ~mask)\n+\t\treturn -EINVAL;\n+\n+\tsr[0] = val;\n+\n+\treturn 0;\n+}\n+\n+static int spi_nor_build_sr(struct spi_nor *nor, const u8 *old_sr, u8 *new_sr,\n+\t\t\t    u8 pow, bool use_top)\n+{\n+\tu8 bp_mask = spi_nor_get_sr_bp_mask(nor);\n+\tu8 tb_mask = spi_nor_get_sr_tb_mask(nor);\n+\tint ret;\n+\n+\tnew_sr[0] = old_sr[0] & ~bp_mask & ~tb_mask;\n+\n+\t/* Build BP field */\n+\tret = spi_nor_sr_set_bp_mask(nor, &new_sr[0], pow);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Build TB field */\n+\tif (!use_top)\n+\t\tnew_sr[0] |= tb_mask;\n+\n+\treturn 0;\n+}\n+\n /*\n  * Lock a region of the flash. Compatible with ST Micro and similar flash.\n  * Supports the block protection bits BP{0,1,2}/BP{0,1,2,3} in the status\n@@ -162,11 +199,10 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)\n \tint ret;\n \tu8 status_old[1] = {}, status_new[1] = {};\n \tu8 bp_mask = spi_nor_get_sr_bp_mask(nor);\n-\tu8 tb_mask = spi_nor_get_sr_tb_mask(nor);\n-\tu8 pow, val;\n \tloff_t lock_len;\n \tbool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;\n \tbool use_top;\n+\tu8 pow;\n \n \tret = spi_nor_read_sr(nor, nor->bouncebuf);\n \tif (ret)\n@@ -200,24 +236,19 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)\n \t\tlock_len = ofs + len;\n \n \tif (lock_len == nor->params->size) {\n-\t\tval = bp_mask;\n+\t\tpow = (nor->flags & SNOR_F_HAS_4BIT_BP) ? GENMASK(3, 0) : GENMASK(2, 0);\n \t} else {\n \t\tmin_prot_len = spi_nor_get_min_prot_length_sr(nor);\n \t\tpow = ilog2(lock_len) - ilog2(min_prot_len) + 1;\n-\t\tval = pow << SR_BP_SHIFT;\n-\n-\t\tif (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3)\n-\t\t\tval = (val & ~SR_BP3) | SR_BP3_BIT6;\n-\n-\t\tif (val & ~bp_mask)\n-\t\t\treturn -EINVAL;\n-\n-\t\t/* Don't \"lock\" with no region! */\n-\t\tif (!(val & bp_mask))\n-\t\t\treturn -EINVAL;\n \t}\n \n-\tstatus_new[0] = (status_old[0] & ~bp_mask & ~tb_mask) | val;\n+\tret = spi_nor_build_sr(nor, status_old, status_new, pow, use_top);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Don't \"lock\" with no region! */\n+\tif (!(status_new[0] & bp_mask))\n+\t\treturn -EINVAL;\n \n \t/*\n \t * Disallow further writes if WP# pin is neither left floating nor\n@@ -227,9 +258,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len)\n \tif (!(nor->flags & SNOR_F_NO_WP))\n \t\tstatus_new[0] |= SR_SRWD;\n \n-\tif (!use_top)\n-\t\tstatus_new[0] |= tb_mask;\n-\n \t/* Don't bother if they're the same */\n \tif (status_new[0] == status_old[0])\n \t\treturn 0;\n@@ -252,11 +280,10 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)\n \tint ret;\n \tu8 status_old[1], status_new[1];\n \tu8 bp_mask = spi_nor_get_sr_bp_mask(nor);\n-\tu8 tb_mask = spi_nor_get_sr_tb_mask(nor);\n-\tu8 pow, val;\n \tloff_t lock_len;\n \tbool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;\n \tbool use_top;\n+\tu8 pow;\n \n \tret = spi_nor_read_sr(nor, nor->bouncebuf);\n \tif (ret)\n@@ -297,29 +324,21 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)\n \t\tlock_len = ofs;\n \n \tif (lock_len == 0) {\n-\t\tval = 0; /* fully unlocked */\n+\t\tpow = 0; /* fully unlocked */\n \t} else {\n \t\tmin_prot_len = spi_nor_get_min_prot_length_sr(nor);\n \t\tpow = ilog2(lock_len) - ilog2(min_prot_len) + 1;\n-\t\tval = pow << SR_BP_SHIFT;\n \n-\t\tif (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3)\n-\t\t\tval = (val & ~SR_BP3) | SR_BP3_BIT6;\n-\n-\t\t/* Some power-of-two sizes may not be supported */\n-\t\tif (val & ~bp_mask)\n-\t\t\treturn -EINVAL;\n \t}\n \n-\tstatus_new[0] = (status_old[0] & ~bp_mask & ~tb_mask) | val;\n+\tret = spi_nor_build_sr(nor, status_old, status_new, pow, use_top);\n+\tif (ret)\n+\t\treturn ret;\n \n \t/* Don't protect status register if we're fully unlocked */\n \tif (lock_len == 0)\n \t\tstatus_new[0] &= ~SR_SRWD;\n \n-\tif (!use_top)\n-\t\tstatus_new[0] |= tb_mask;\n-\n \t/* Don't bother if they're the same */\n \tif (status_new[0] == status_old[0])\n \t\treturn 0;\n","prefixes":["v4","13/27"]}