[PATCH v4 2/4] gpio: shared-proxy: Drop the vote of a released proxy on write failure

From: Shawn Guo

Date: Sat Oct 17 2026 - 00:37:24 EST


When a proxy that voted for a value change frees the line, it calls
gpio_shared_proxy_set_unlocked() to withdraw its vote. If it is the
last voter and restoring the default value fails, that function
returns early, leaving votecnt incremented and voted_change set.

The consumer is gone, but its vote is not. The line is held at the
non-default value for all remaining users, since votecnt can never
drop to zero again. And the proxy data outlives the request, so
voted_change is still set when the line is requested again. If
another user has reinitialized the line in between, resetting
votecnt to 0, the stale proxy's next vote for the default value
decrements votecnt from 0 and underflows it.

Drop the vote unconditionally on release, after reporting the
failure, since the consumer is going away regardless.

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 | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-shared-proxy.c b/drivers/gpio/gpio-shared-proxy.c
index 0d1d724a6a37..24241c981df1 100644
--- a/drivers/gpio/gpio-shared-proxy.c
+++ b/drivers/gpio/gpio-shared-proxy.c
@@ -134,9 +134,13 @@ static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset)

if (proxy->voted_change) {
ret = gpio_shared_proxy_set_unlocked(proxy, shared_desc->def_val);
- if (ret)
+ if (ret) {
dev_err(proxy->dev,
"Failed to unset the shared GPIO value on release: %d\n", ret);
+ /* The consumer is going away regardless, drop its vote */
+ shared_desc->votecnt--;
+ proxy->voted_change = false;
+ }
}

proxy->shared_desc->usecnt--;
--
2.43.0