summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>2026-05-22 09:49:35 +0200
committerBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>2026-05-28 15:23:39 +0200
commitbbec30f7e19d9a1c604da7164b8057ccee590e72 (patch)
tree01dabc0c8d4a742a7d9a0266579dc91cd1e3eec7
parentdac917ed5aead741004db8d0d5151dd577802df8 (diff)
gpio: shared: undo the vote of the proxy on GPIO free
When the user of a shared GPIO managed by gpio-shared-proxy calls gpiod_put() to release it, we never undo the potential "vote" for driving the shared line "high". In the free() callback, check if this proxy voted for "high" and - if so - decrease the number of votes and potentially revert the value to low if this is the last user. Cc: stable@vger.kernel.org Fixes: e992d54c6f97 ("gpio: shared-proxy: implement the shared GPIO proxy driver") Closes: https://sashiko.dev/#/patchset/20260513-gpio-shared-dynamic-voting-v1-1-8e1c49961b7d%40oss.qualcomm.com Reviewed-by: Linus Walleij <linusw@kernel.org> Link: https://patch.msgid.link/20260522-gpio-shared-free-vote-v3-1-8a4fddc6bedb@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
-rw-r--r--drivers/gpio/gpio-shared-proxy.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-shared-proxy.c b/drivers/gpio/gpio-shared-proxy.c
index 29d7d2e4dfc0..6941e4be6cf1 100644
--- a/drivers/gpio/gpio-shared-proxy.c
+++ b/drivers/gpio/gpio-shared-proxy.c
@@ -103,9 +103,18 @@ static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset)
{
struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
struct gpio_shared_desc *shared_desc = proxy->shared_desc;
+ int ret;
guard(gpio_shared_desc_lock)(shared_desc);
+ if (proxy->voted_high) {
+ ret = gpio_shared_proxy_set_unlocked(proxy,
+ shared_desc->can_sleep ? gpiod_set_value_cansleep : gpiod_set_value, 0);
+ if (ret)
+ dev_err(proxy->dev,
+ "Failed to unset the shared GPIO value on release: %d\n", ret);
+ }
+
proxy->shared_desc->usecnt--;
dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n",