From nobody Tue Sep 29 08:26:17 2026 Received: from 5.mo581.mail-out.ovh.net (5.mo581.mail-out.ovh.net [178.32.120.239]) (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 033E53FC5C4 for ; Mon, 10 Aug 2026 15:11:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.32.120.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786374718; cv=none; b=PbAGzMPyUNjjQtH+B1wCbJ/gE3Fli3ETCNEfHKnrXukPz9Rq6yxFwJnlNMOEWvxtIGuJJNklbT0DaMjkNFiHuPxkri625lggj68r/5y1iy3R01PzaBbxQmm22g/BCZKJ/8CPw+mA4mILsN1T/Fs9QnT1jydjdngk6E1yD+prIag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786374718; c=relaxed/simple; bh=e4kQFCjB5LtFdJIis48BWU7f1G9ZFWIOb2b/rcrqG2s=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=kx3hbyxTmrNy5AETmXscvKReWawDoP7ra1fCkLsQ5zZxE2mpeclRjHIvElJ4and+2JpN65As1eWCTMNIDflzahsyLmtB7eOSWNxI1AeC6apb4pUKyPQPyEfzsT20yYz4oYtZN/xYBqbAZ8lAyPzm50eTM60uQb9qHQsrmO0IUX8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=m-works.net; spf=pass smtp.mailfrom=m-works.net; arc=none smtp.client-ip=178.32.120.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=m-works.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=m-works.net Received: from director7.ghost.mail-out.ovh.net (unknown [10.110.37.251]) by mo581.mail-out.ovh.net (Postfix) with ESMTP id 4hJcJT35pLz5xxC for ; Mon, 10 Aug 2026 14:16:57 +0000 (UTC) Received: from ghost-submission-7d8d68f679-7df7p (unknown [10.108.54.148]) by director7.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 5AC5EC0198; Mon, 10 Aug 2026 14:16:53 +0000 (UTC) Received: from m-works.net ([37.59.142.101]) by ghost-submission-7d8d68f679-7df7p with ESMTPSA id I14hO1TdeWq3KC0Alk6qAw (envelope-from ); Mon, 10 Aug 2026 14:16:53 +0000 Authentication-Results: garm.ovh; auth=pass (GARM-101G004796ca3e8-0880-49c0-a3d2-70d64670ab19, ED6AA3D647CD945153C5C800EF75597CE9F2D384) smtp.auth=maciej.andrzejewski@m-works.net X-OVh-ClientIp: 144.125.48.245 Date: Mon, 10 Aug 2026 16:16:52 +0200 From: Maciej Andrzejewski ICEYE To: Linus Walleij , Bartosz Golaszewski , linux-gpio@vger.kernel.org, broonie@kernel.org, linux-spi@vger.kernel.org, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, linux-mtd@lists.infradead.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, maciej.andrzejewski@m-works.net Cc: linux-gpio@vger.kernel.org, Mark Brown , linux-spi@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , linux-mtd@lists.infradead.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Maciej Andrzejewski ICEYE Subject: [PATCH 1/2] gpiolib: of: Only apply the SPI CS quirk to SPI peripherals Message-ID: <20260810141629.81650-2-maciej.andrzejewski@m-works.net> References: <20260810141629.81650-1-maciej.andrzejewski@m-works.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20260810141629.81650-1-maciej.andrzejewski@m-works.net> X-Mailer: git-send-email 2.43.0 x-ovh-tracer-id: 15949779557479752483 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: dmFkZTFkKUw8dTwvfjd4/KP70uzwoCMB5S1Nh1xoCtlKl9zTFZzwWOg+RBpw5P0civI9C611B1wrLGnfL3FNYmECOnjsVZKgynKuLG6Jhd3Uc8cbYV256q4EDW1EJopIsVe6nfKjRwsKIAKDeHxGys67ywGuGjynKrr0p4f+W1tRSR6L8yRsQUchqkYbufFkmr7AL7eeCcTKmnSxggk9Am6xY3yqfHbxzDDXnNa07eo3ri956RbXgeCfNKnKA1gany5tMxKjWt3sHbxNpzbfY66hukbKbQQTBIAx2rECu5ovgOzajdg1Fxma7zv7UmoNQovbLAGQzJu4D89RflMM5EwN9mbnZJMbB/wSzkk7zx2hKSxeF+GmGNXTHHMCkTfgBVKZHe2BfzXoyrds+PB9AlRcn8vu/HinrdIkrn34sQ4LQmT87sdNgn163E5QGGmSX1wKojbASkbCp33OUfaVK7qOSqquJYO+ebiQznia9OP+yENCLAEHhupG8zh30Mt/YT0Ym4k0qzdxtTgKjOpSCwW1HCvTwlHfJPYqcVIXTz2GFN4Uw6BjvAQt/zbztbbSOoX8evfBWBRkP34lOpxrSmtnVfpLuqQ7u3pOidtovyh49D1iMxRglJMe3cRH3uU2Pps8JDsh+zvc818Eh/vdgvsB/rQOeC7ENn79TOEnKPc0Y9t+YQ Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The legacy SPI chip-select polarity quirk in of_gpio_flags_quirks() is keyed on nothing but the property name "cs-gpios". That name is not exclusive to SPI: nand-controller.yaml documents the very same property for NAND controllers, and rawnand_dt_parse_gpio_cs() requests those lines with gpiod_count(dev, "cs"), which gpiolib expands to "cs-gpios". A NAND controller therefore has SPI chip-select semantics forced onto its chip selects, and any chip node whose first reg cell matches a GPIO index is silently flipped to active low. The NAND core requests the descriptors GPIOD_OUT_HIGH and drivers assert with a logical 0, so the inversion leaves the die permanently deselected. The example in nand-controller.yaml is itself affected: it pairs a native chip select with a GPIO one and gives the second chip a reg of 1, which trips the quirk whenever CONFIG_SPI_MASTER is enabled. In-tree the collision is real but latent. 36 board trees, all Atmel/Microchip at91, give their nand@3 controller a cs-gpios line, and they escape only because the sole child of those nodes is a partitions container with no reg for the quirk to match against. Device tree carries no bus type marker, so identify the bus from what the peripheral advertises about itself. Properties of an SPI peripheral are namespaced with "spi-" (spi-max-frequency, spi-cpol, spi-cs-high and the rest of spi-peripheral-props.yaml), whereas a NAND chip node carries only reg, nand-* and its partition table. Skip the quirk when the matched child has no "spi-" prefixed property. This is a convention rather than a guarantee: compatible and reg are the only properties spi-controller.yaml makes mandatory for a peripheral, so a minimal one may carry no "spi-" property at all. The next patch covers those by looking at the controller instead. Signed-off-by: Maciej Andrzejewski ICEYE --- drivers/gpio/gpiolib-of.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 940b566946ce..bd9a623f2ae1 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -340,6 +340,25 @@ static void of_gpio_set_polarity_by_property(const str= uct device_node *np, } } =20 +/* + * The legacy SPI chip select binding below is keyed on a property name th= at + * other subsystems reuse for the same purpose, notably NAND controllers (= see + * Documentation/devicetree/bindings/mtd/nand-controller.yaml), whose chip + * selects carry no SPI polarity semantics. Device tree has no bus type + * marker, so go by what the peripheral advertises about itself: properties + * of an SPI peripheral are namespaced with "spi-". + */ +static bool of_gpio_child_is_spi_peripheral(const struct device_node *chil= d) +{ + struct property *pp; + + for_each_property_of_node(child, pp) + if (str_has_prefix(pp->name, "spi-")) + return true; + + return false; +} + static void of_gpio_flags_quirks(const struct device_node *np, const char *propname, enum of_gpio_flags *flags, @@ -374,6 +393,11 @@ static void of_gpio_flags_quirks(const struct device_n= ode *np, if (ret) continue; if (cs =3D=3D index) { + bool active_high; + + if (!of_gpio_child_is_spi_peripheral(child)) + break; + /* * SPI children have active low chip selects * by default. This can be specified negatively @@ -386,8 +410,8 @@ static void of_gpio_flags_quirks(const struct device_no= de *np, * conflict and the "spi-cs-high" flag will * take precedence. */ - bool active_high =3D of_property_read_bool(child, - "spi-cs-high"); + active_high =3D of_property_read_bool(child, + "spi-cs-high"); of_gpio_quirk_polarity(child, active_high, flags); break; --=20 2.50.1 From nobody Tue Sep 29 08:26:17 2026 Received: from 8.mo583.mail-out.ovh.net (8.mo583.mail-out.ovh.net [178.32.116.78]) (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 9614242C4FB for ; Mon, 10 Aug 2026 18:31:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.32.116.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786386716; cv=none; b=qytqtbOlfCStDe6v8xhe+Ig7yRU0kh4rP1CtkP0MDQNS8xRcvKgSTJDMmn2EpnDeI5KrKQqG/3ij2OCxtKhlx89CguesX9m3VqZJ6nx9/PxhxPsXM9qwDQ7+Jk2fbxO+U0bVWwiJLl7UHfX1ltTH6CAPvSxrHEy3pqRHgp3W6JU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786386716; c=relaxed/simple; bh=h8JMm3lG2PkZasKfNow2aML+HILdmmApWdsNUKU/K0I=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=CvEGB+PlaEPYhk6GM0p88YDuXH3z1Dkx3Wx1rbA1Y1ycaDPwVxxAvEmHvwEzKeKAzE4VrJIA/3QbUYQlbQybE6DfAak/SK0KVF5wDVm6V821jepHjchHZXc0C+MLJXRD+eAmdyrLJ4ptlyhVFhQu/hC7Y7T3P/jCFwMpUKTOr6M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=m-works.net; spf=pass smtp.mailfrom=m-works.net; arc=none smtp.client-ip=178.32.116.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=m-works.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=m-works.net Received: from director9.ghost.mail-out.ovh.net (unknown [10.110.58.202]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4hJcJZ5Skfz5vxq for ; Mon, 10 Aug 2026 14:17:02 +0000 (UTC) Received: from ghost-submission-7d8d68f679-5z4sg (unknown [10.110.168.82]) by director9.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 44E7F80F5E; Mon, 10 Aug 2026 14:17:00 +0000 (UTC) Received: from m-works.net ([37.59.142.108]) by ghost-submission-7d8d68f679-5z4sg with ESMTPSA id 4EegBlzdeWqH/wUAQ8H/aw (envelope-from ); Mon, 10 Aug 2026 14:17:00 +0000 Authentication-Results: garm.ovh; auth=pass (GARM-108S002f1246bdd-25f1-4367-ad77-4adbbe4a8bb8, ED6AA3D647CD945153C5C800EF75597CE9F2D384) smtp.auth=maciej.andrzejewski@m-works.net X-OVh-ClientIp: 144.125.48.245 Date: Mon, 10 Aug 2026 16:16:59 +0200 From: Maciej Andrzejewski ICEYE To: Linus Walleij , Bartosz Golaszewski , linux-gpio@vger.kernel.org, broonie@kernel.org, linux-spi@vger.kernel.org, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, linux-mtd@lists.infradead.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, maciej.andrzejewski@m-works.net Cc: linux-gpio@vger.kernel.org, Mark Brown , linux-spi@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , linux-mtd@lists.infradead.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Maciej Andrzejewski ICEYE Subject: [PATCH 2/2] gpiolib: of: Identify SPI controllers by nodename Message-ID: <20260810141629.81650-3-maciej.andrzejewski@m-works.net> References: <20260810141629.81650-1-maciej.andrzejewski@m-works.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20260810141629.81650-1-maciej.andrzejewski@m-works.net> X-Mailer: git-send-email 2.43.0 x-ovh-tracer-id: 15951186934430573347 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: dmFkZTFkKUw8dTwvfjd4/KP70uzwoCMB5S1Nh1xoCtlKl9zTFZzwWOg+RBpw5P0civI9C611B1wrLGnfL3FNYmECOnjsVZKgynKuLG6Jhd3Uc8cbYV256q4EDW1EJopIsVe6nfKjRwsKIAKDeHxGys67ywGuGjynKrr0p4f+W1tRSR6L8yRsQUchqkYbufFkmr7AL7eeCcTKmnSxggk9Am6xY3yqfHbxzDDXnNa07eo3ri956RbXgeCfNKnKA1gany5tMxKjWt3sHbxNpzbfY66hukbKbQQTBIAx2rECu5ovgOzajdg1Fxma7zv7UmoNQovbLAGQzJu4D89RflMM5EwN9mbnq2fcpQwA5/FtdTHBb9i23sZrmAp8P6iy5bhR+xyGqUMbeFwRQxTVC3MHGKLtFf9SNOEHxd1sGVcXXI8Gto95X952o++h4RQ8gewNE4CrWvTLXzCb6nmguDdXJa4zjPtptE0xpFU6v+wb39OLaRNF07lJurJ8VorEoITd2aSc/Zx1F+HeNoPzUs1b/gk1lW/foiuYVQweNQQAnaEvZ4q0KLNEAe0W02cchsOsTBMLBc7cNDrSLpdtwU4aO1MjRoVYzJwM68khJzh2jXFd+Ln5bXEg2p0AVAIATw3DKC6SNoLffLHvbAe7L6sN0mZGl5LtIJ3wkMSzRl3lprqm0RdvFw Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The "spi-" property scan added by the previous patch misses SPI peripherals that declare nothing beyond compatible and reg, which are the only two properties spi-controller.yaml makes mandatory for a child node. Let the controller settle those cases: spi-controller.yaml constrains the controller nodename to ^spi(@.*|-[0-9]+)?$, so the name is the one bus marker every conforming SPI controller has to carry, and of_node_name_prefix() is the existing helper for testing it. Both tests were scored over every board device tree in the kernel, expanded with the same cpp and scripts/dtc pipeline the build uses, at v7.2-rc7. All 3620 trees under arch/*/boot/dts expand; 503 of them hold at least one GPIO chip select that can reach the quirk, 765 such chip selects in total. 761 are matched by both tests, and none are matched by neither, so no in-tree board changes behaviour. One needs the property scan on its own: psc@11400 on ac14xx, a fsl,mpc5121-psc-spi named after the hardware block rather than the bus, whose m25p128@0 child carries spi-max-frequency. Three need the nodename on its own, all peripherals with no "spi-" property of any kind: - panel@0 under the spi-gpio controller on rk3566-anbernic-rg503 - can@0, an mcp251xfd, under ecspi3 on imx8mn-vhip4-evalboard-v1 - spi@1 under ecspi1 on imx53-ppd of_gpio_spi_cs_get_count() in this file identifies SPI controllers with of_device_is_compatible() instead, but it only has to name three legacy controllers whose bindings are closed. An allow-list here would have to name every SPI controller binding in the tree, 71 distinct compatible strings among the candidates alone, and grow with every new one. Signed-off-by: Maciej Andrzejewski ICEYE --- drivers/gpio/gpiolib-of.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index bd9a623f2ae1..959b32b3bea0 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -359,6 +359,17 @@ static bool of_gpio_child_is_spi_peripheral(const stru= ct device_node *child) return false; } =20 +/* + * A minimal SPI peripheral may carry no "spi-" property at all, so also l= et + * the controller identify the bus. spi-controller.yaml constrains the + * controller nodename to ^spi(@.*|-[0-9]+)?$, which makes the name the one + * bus marker a controller is required to have. + */ +static bool of_gpio_node_is_spi_controller(const struct device_node *np) +{ + return of_node_name_prefix(np, "spi"); +} + static void of_gpio_flags_quirks(const struct device_node *np, const char *propname, enum of_gpio_flags *flags, @@ -395,7 +406,8 @@ static void of_gpio_flags_quirks(const struct device_no= de *np, if (cs =3D=3D index) { bool active_high; =20 - if (!of_gpio_child_is_spi_peripheral(child)) + if (!of_gpio_child_is_spi_peripheral(child) && + !of_gpio_node_is_spi_controller(np)) break; =20 /* --=20 2.50.1