On Thu, Mar 14, 2019 at 09:32:37PM +0900, William Breathitt Gray wrote: > Replace verbose implementation in set_multiple callback with > for_each_set_clump8 macro to simplify code and improve clarity. An > improvement in this case is that banks that are not masked will now be > skipped. > > Cc: Masahiro Yamada <yamada.masahiro@xxxxxxxxxxxxx> > Signed-off-by: William Breathitt Gray <vilhelm.gray@xxxxxxxxx> > --- > drivers/gpio/gpio-uniphier.c | 16 ++++++---------- > 1 file changed, 6 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpio/gpio-uniphier.c b/drivers/gpio/gpio-uniphier.c > index 0f662b297a95..df640cb29b9c 100644 > --- a/drivers/gpio/gpio-uniphier.c > +++ b/drivers/gpio/gpio-uniphier.c > @@ -15,9 +15,6 @@ > #include <linux/spinlock.h> > #include <dt-bindings/gpio/uniphier-gpio.h> > > -#define UNIPHIER_GPIO_BANK_MASK \ > - GENMASK((UNIPHIER_GPIO_LINES_PER_BANK) - 1, 0) > - > #define UNIPHIER_GPIO_IRQ_MAX_NUM 24 > > #define UNIPHIER_GPIO_PORT_DATA 0x0 /* data */ > @@ -147,15 +144,14 @@ static void uniphier_gpio_set(struct gpio_chip *chip, > static void uniphier_gpio_set_multiple(struct gpio_chip *chip, > unsigned long *mask, unsigned long *bits) > { > - unsigned int bank, shift, bank_mask, bank_bits; > - int i; > + unsigned int i; > + unsigned long bank_mask; > + unsigned int bank; > + unsigned int bank_bits; > > - for (i = 0; i < chip->ngpio; i += UNIPHIER_GPIO_LINES_PER_BANK) { > + for_each_set_clump8(i, bank_mask, mask, chip->ngpio) { > bank = i / UNIPHIER_GPIO_LINES_PER_BANK; > - shift = i % BITS_PER_LONG; > - bank_mask = (mask[BIT_WORD(i)] >> shift) & > - UNIPHIER_GPIO_BANK_MASK; > - bank_bits = bits[BIT_WORD(i)] >> shift; > + bank_bits = bitmap_get_value8(bits, chip->ngpio, i); > > uniphier_gpio_bank_write(chip, bank, UNIPHIER_GPIO_PORT_DATA, > bank_mask, bank_bits); > -- > 2.21.0 Masahiro, I noticed this loops per GPIO bank and uniphier_gpio_bank_write is called each time to update the respective bank. The uniphier_gpio_reg_update function however is calling writel to update the registers; yet only 8 bits (UNIPHIER_GPIO_LINES_PER_BANK) are updated at a time via the uniphier_gpio_bank_write call in the uniphier_gpio_set_multiple function. Can more than one bank be updated at a time via writel (e.g. 4 banks at 8 bits per bank via a single 32-bit writel call)? If so, instead of using the for_each_set_clump8 macro, it may be more efficient to loop through 4 banks at a time. William Breathitt Gray