Hi Linus, On Wed, 26 Jun 2024 at 14:06, Linus Walleij <linus.walleij@xxxxxxxxxx> wrote: > > Hi Shiji, > > thanks for your patch! > > On Tue, Jun 25, 2024 at 3:22 AM Shiji Yang <yangshiji66@xxxxxxxxxxx> wrote: > > > bgpio_bits must be aligned with the data bus width. For example, on a > > 32 bit big endian system and we only have 16 GPIOs. If we only assume > > bgpio_bits=16 we can never control the GPIO because the base address > > is the lowest address. > > > > low address high address > > ------------------------------------------------- > > | byte3 | byte2 | byte1 | byte0 | > > ------------------------------------------------- > > | NaN | NaN | gpio8-15 | gpio0-7 | > > ------------------------------------------------- > > > > Fixes: 55b2395e4e92 ("gpio: mmio: handle "ngpios" properly in bgpio_init()") > > Fixes: https://github.com/openwrt/openwrt/issues/15739 > > Reported-by: Mark Mentovai <mark@xxxxxxxxxxxx> > > Signed-off-by: Shiji Yang <yangshiji66@xxxxxxxxxxx> > > Suggested-By: Mark Mentovai <mark@xxxxxxxxxxxx> > > Reviewed-by: Jonas Gorski <jonas.gorski@xxxxxxxxx> > > Tested-by: Lóránd Horváth <lorand.horvath82@xxxxxxxxx> > > Commit 55b2395e4e92 also contains this: > > @@ -614,10 +616,15 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, > gc->parent = dev; > gc->label = dev_name(dev); > gc->base = -1; > - gc->ngpio = gc->bgpio_bits; > gc->request = bgpio_request; > > After this patch gc->ngpio will be unset for any GPIO chip that > provides a ngpios property, so restore the above line too. The patch only removes a line changing gc->bgpio_bits, not gc->ngpio. gc->ngpio is untouched. gc->ngpio will still be set by gpiochip_get_ngpios() if there is a ngpio property. See the context of the patch: > @@ -619,8 +619,6 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, > ret = gpiochip_get_ngpios(gc, dev); <-- > if (ret) > gc->ngpio = gc->bgpio_bits; <- and if it fails, fallback to bgpio_bits > > But maybe a better fix is: > > + #include <linux/types.h> > (...) > + else > + gc->bgpio_bits = round_up(gc->ngpio, sizeof(phys_addr_t) * 8); > > ? bgpio only supports a single register worth of gpios, so the limit is 1 * sizeof(phys_addr_t) * 8. So this would force force bgpio_bits to sizeof(phys_addr_t) * 8. And this will break any bgpio users where the gpio registers are less than phys_addr_t wide. Like 32 bit registers on a 64 bit system, or 16 bit registers on 32 bit. Therefore I think the most sane thing is to keep gc->bgpio_bits at sz * 8. The only potentially reasonable thing that could be added here is a check that gc->ngpio is at most bgpio_bits. But that would be an additional check, not a fix per se. Best Regards, Jonas