]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpio: shared: undo the vote of the proxy on GPIO free
authorBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Fri, 22 May 2026 07:49:35 +0000 (09:49 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Thu, 28 May 2026 13:23:39 +0000 (15:23 +0200)
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>
drivers/gpio/gpio-shared-proxy.c

index 29d7d2e4dfc02c34fb3f2abc343ee30b61579b66..6941e4be6cf1871b134c55c05877c9793de52ac3 100644 (file)
@@ -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",