[PATCH v4 3/4] gpio: shared-proxy: Drive the default value when no votes are cast
From: Shawn Guo
Date: Sat Oct 17 2026 - 00:37:57 EST
A consumer that requests a shared line with GPIOD_ASIS never calls
direction_output(), so def_val keeps its initial value of 0. If the
line was left high, for instance by the bootloader, a later
gpiod_set_value(0) from that consumer matches def_val and the proxy
treats it as withdrawing a vote it never cast. It returns success
without writing the hardware, and the line stays high.
The consumer has no way to tell. Its request to drive the line low is
silently ignored until it first votes for high and then withdraws
that vote.
When the requested value is the default and no votes are
outstanding, write it to the hardware instead of returning early.
For lines configured via direction_output() this is a redundant
write of the value the line already has. With votes outstanding the
request remains a no-op, as the line must stay at the voted value.
Fixes: e992d54c6f97 ("gpio: shared-proxy: implement the shared GPIO proxy driver")
Assisted-by: LLM
Signed-off-by: Shawn Guo <shengchao.guo@xxxxxxxxxxxxxxxx>
---
drivers/gpio/gpio-shared-proxy.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-shared-proxy.c b/drivers/gpio/gpio-shared-proxy.c
index 24241c981df1..456a3c3dbf71 100644
--- a/drivers/gpio/gpio-shared-proxy.c
+++ b/drivers/gpio/gpio-shared-proxy.c
@@ -81,9 +81,16 @@ gpio_shared_proxy_set_unlocked(struct gpio_shared_proxy_data *proxy, int value)
}
/* Desired value is the default. */
- if (!proxy->voted_change)
- /* We didn't vote for change previously, nothing to do. */
+ if (!proxy->voted_change) {
+ /*
+ * With no votes outstanding the line should be at the
+ * default, but a GPIOD_ASIS line may have been left at the
+ * opposite value. Drive it there.
+ */
+ if (!shared_desc->votecnt)
+ ret = gpiod_set_value_cansleep(desc, shared_desc->def_val);
goto out;
+ }
/* We previously voted for change. */
if (shared_desc->votecnt == 1) {
--
2.43.0