On Mon, Feb 10, 2025 at 11:51:58AM +0100, Bartosz Golaszewski wrote: > From: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> > > As per the API contract, the get() callback is only allowed to return 0, > 1 or a negative error number. Add a wrapper around the callback calls > that filters out anything else. ... > +static int gpiochip_get(struct gpio_chip *gc, unsigned int offset) > +{ > + int ret; > + > + lockdep_assert_held(&gc->gpiodev->srcu); > + > + if (!gc->get) > + return -EIO; > + > + ret = gc->get(gc, offset); > + if (ret > 1) Perhaps use the respective GPIO macro instead? Otherwise it's not clear what the meaning of 1 is. > + ret = -EBADE; > + > + return ret; > +} > + > static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *desc) > { > - return gc->get ? gc->get(gc, gpio_chip_hwgpio(desc)) : -EIO; > + return gpiochip_get(gc, gpio_chip_hwgpio(desc)); > } ... > for_each_set_bit(i, mask, gc->ngpio) { > - value = gc->get(gc, i); > + value = gpiochip_get(gc, i); This will delay the function for checking every time if the get() exists. Which must be here. > if (value < 0) > return value; > __assign_bit(i, bits, value); What I would expect here is something like this: static int gpio_chip_get_value_nocheck(struct gpio_chip *gc, unsigned int offset) { int ret; lockdep_assert_held(&gc->gpiodev->srcu); ret = gc->get(gc, offset); if (ret > GPIO_LINE_DIRECTION_IN) ret = -EBADE; return ret; } static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *desc) { return gc->get ? gpio_chip_get_value_nocheck(gc, gpio_chip_hwgpio(desc)) : -EIO; } But I see the downside of it as it might lurk without RCU lock if get is not defined. So, up to you. -- With Best Regards, Andy Shevchenko