[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