[PATCH] gpiolib: return quietly from gpiod_get_direction() without .get_direction()

Mehmet Fide <[email protected]>
Newsgroups org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Mehmet Fide <[email protected]>

Since commit 471e998c0e31 ("gpiolib: remove redundant callback check")
gpiod_get_direction() lets gpiochip_get_direction() WARN when the
controller does not implement .get_direction(). Callers of the public
API have no way to check for the callback themselves, so any of them
hitting such a controller now produces a backtrace.

One reachable case is the i2c generic GPIO bus recovery:
i2c_register_adapter() calls gpiod_get_direction() on the SDA line,
and on a Vybrid VF500 (gpio-vf610 has no .get_direction(), the pad
direction lives in the iomuxc, not in the GPIO block) every i2c
adapter probe logs

  WARNING: drivers/gpio/gpiolib.c:431 at gpiod_get_direction+0x16c/0x19c
  ...
  gpiod_get_direction from i2c_register_adapter+0x5bc/0x7f4
  i2c_register_adapter from i2c_imx_probe+0x3fc/0x6a0

Commit d761c7e38a00 ("gpiolib: Check gc->get_direction() before
calling gpiod_get_direction()") already shields the debugfs dump the
same way. Do it once inside gpiod_get_direction() instead, and return
-EOPNOTSUPP quietly, which restores the pre-471e998c0e31 behavior for
external callers.

Tested on a Colibri VF50: the boot log goes from 21 identical
backtraces to none, and the i2c recovery init degrades exactly as
before, by skipping set_sda.

Fixes: 471e998c0e31 ("gpiolib: remove redundant callback check")
Signed-off-by: Mehmet Fide <[email protected]>
---
 drivers/gpio/gpiolib.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index c433a095907f..ad9740a3b42d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -464,6 +464,14 @@ int gpiod_get_direction(struct gpio_desc *desc)
 	if (!guard.gc)
 		return -ENODEV;
 
+	/*
+	 * Callers of the public API cannot know whether the controller
+	 * implements .get_direction(), so bail out quietly instead of
+	 * letting gpiochip_get_direction() WARN on them.
+	 */
+	if (!guard.gc->get_direction)
+		return -EOPNOTSUPP;
+
 	offset = gpiod_hwgpio(desc);
 	flags = READ_ONCE(desc->flags);
 
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.