On Mon, Feb 24, 2025 at 5:30 PM Andy Shevchenko <andriy.shevchenko@xxxxxxxxx> wrote: > > 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. > We don't have one for GPIO values. > > + 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. > Makes sense, gpiochip_get() is only called in gpio_chip_get_value() and gpiochip_get_multiple() where gc->get is already checked. Bart