lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20251105-add-external-mux-enable-gpio-v1-2-e59cba6f9e47@vaisala.com>
Date: Wed, 05 Nov 2025 14:49:13 +0000
From: Tapio Reijonen <tapio.reijonen@...sala.com>
To: Peter Rosin <peda@...ntia.se>, Rob Herring <robh@...nel.org>, 
 Krzysztof Kozlowski <krzk+dt@...nel.org>, 
 Conor Dooley <conor+dt@...nel.org>
Cc: devicetree@...r.kernel.org, linux-kernel@...r.kernel.org, 
 Tapio Reijonen <tapio.reijonen@...sala.com>
Subject: [PATCH 2/2] mux: gpio: Add external mux enable gpio

Add optional gpio to control gpio-controlled multiplexer
gpio pins, according to the state of the mux.

When the gpio mux controller transitions state,
it first configures all required gpio mux pins,
and then sets optional enable gpio pin to logic high.

When gpio mux controller sets "MUX_IDLE_DISCONNECT",
the optional enable gpio pin is set low.

Signed-off-by: Tapio Reijonen <tapio.reijonen@...sala.com>
---
 drivers/mux/gpio.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/mux/gpio.c b/drivers/mux/gpio.c
index 4cc3202c58f364e80ad9f632763f568d184d4173..ee2bca1214d67feb3031fe60556b68b59293f0e3 100644
--- a/drivers/mux/gpio.c
+++ b/drivers/mux/gpio.c
@@ -19,6 +19,7 @@
 
 struct mux_gpio {
 	struct gpio_descs *gpios;
+	struct gpio_desc *enable_gpio;
 };
 
 static int mux_gpio_set(struct mux_control *mux, int state)
@@ -27,10 +28,18 @@ static int mux_gpio_set(struct mux_control *mux, int state)
 	DECLARE_BITMAP(values, BITS_PER_TYPE(state));
 	u32 value = state;
 
+	if (mux_gpio->enable_gpio && state == MUX_IDLE_DISCONNECT) {
+		gpiod_set_value_cansleep(mux_gpio->enable_gpio, 0);
+		return 0;
+	}
+
 	bitmap_from_arr32(values, &value, BITS_PER_TYPE(value));
 
 	gpiod_multi_set_value_cansleep(mux_gpio->gpios, values);
 
+	if (mux_gpio->enable_gpio)
+		gpiod_set_value_cansleep(mux_gpio->enable_gpio, 1);
+
 	return 0;
 }
 
@@ -71,14 +80,23 @@ static int mux_gpio_probe(struct platform_device *pdev)
 	WARN_ON(pins != mux_gpio->gpios->ndescs);
 	mux_chip->mux->states = BIT(pins);
 
+	mux_gpio->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
+	if (IS_ERR(mux_gpio->enable_gpio))
+		return dev_err_probe(dev, PTR_ERR(mux_gpio->enable_gpio),
+				     "failed to get optional enable gpio\n");
+
 	ret = device_property_read_u32(dev, "idle-state", (u32 *)&idle_state);
-	if (ret >= 0 && idle_state != MUX_IDLE_AS_IS) {
-		if (idle_state < 0 || idle_state >= mux_chip->mux->states) {
-			dev_err(dev, "invalid idle-state %u\n", idle_state);
-			return -EINVAL;
+	if (ret >= 0) {
+		if (idle_state == MUX_IDLE_DISCONNECT)
+			mux_chip->mux->idle_state = MUX_IDLE_DISCONNECT;
+		else if (idle_state != MUX_IDLE_AS_IS) {
+			if (idle_state < 0 || idle_state >= mux_chip->mux->states) {
+				return dev_err_probe(dev, -EINVAL,
+						     "invalid idle-state %d\n",
+						     idle_state);
+			}
+			mux_chip->mux->idle_state = idle_state;
 		}
-
-		mux_chip->mux->idle_state = idle_state;
 	}
 
 	ret = devm_regulator_get_enable_optional(dev, "mux");

-- 
2.47.3


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ