* [PATCH v1] gpio: mmio: restroe get multiple gpio mask
@ 2023-04-23 9:06 Yan Wang
2023-04-24 6:56 ` Linus Walleij
2023-04-24 13:31 ` Andy Shevchenko
0 siblings, 2 replies; 5+ messages in thread
From: Yan Wang @ 2023-04-23 9:06 UTC (permalink / raw)
To: linus.walleij, brgl
Cc: Yan Wang, Andy Shevchenko, open list:GPIO SUBSYSTEM, open list
Simplify the code,should not modify its logic.
Fixes: 761b5c30c206 ("gpio: mmio: replace open-coded for_each_set_bit()")
Signed-off-by: Yan Wang <rk.code@outlook.com>
---
drivers/gpio/gpio-mmio.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index d9dff3dc92ae..c2347ef3a4df 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c
@@ -271,10 +271,14 @@ static void bgpio_multiple_get_masks(struct gpio_chip *gc,
*clear_mask = 0;
for_each_set_bit(i, mask, gc->bgpio_bits) {
- if (test_bit(i, bits))
- *set_mask |= bgpio_line2mask(gc, i);
- else
- *clear_mask |= bgpio_line2mask(gc, i);
+ if (*mask == 0)
+ break;
+ if (__test_and_clear_bit(i, mask)) {
+ if (test_bit(i, bits))
+ *set_mask |= bgpio_line2mask(gc, i);
+ else
+ *clear_mask |= bgpio_line2mask(gc, i);
+ }
}
}
--
2.17.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v1] gpio: mmio: restroe get multiple gpio mask 2023-04-23 9:06 [PATCH v1] gpio: mmio: restroe get multiple gpio mask Yan Wang @ 2023-04-24 6:56 ` Linus Walleij 2023-04-24 9:03 ` Yan Wang 2023-04-24 13:31 ` Andy Shevchenko 1 sibling, 1 reply; 5+ messages in thread From: Linus Walleij @ 2023-04-24 6:56 UTC (permalink / raw) To: Yan Wang; +Cc: brgl, Andy Shevchenko, open list:GPIO SUBSYSTEM, open list Hi Yan, thanks for your patch! On Sun, Apr 23, 2023 at 11:07 AM Yan Wang <rk.code@outlook.com> wrote: > Simplify the code,should not modify its logic. I don't see how it simplifies the code, it seems to me that it is making it more complex? > Fixes: 761b5c30c206 ("gpio: mmio: replace open-coded for_each_set_bit()") > Signed-off-by: Yan Wang <rk.code@outlook.com> > --- > drivers/gpio/gpio-mmio.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c > index d9dff3dc92ae..c2347ef3a4df 100644 > --- a/drivers/gpio/gpio-mmio.c > +++ b/drivers/gpio/gpio-mmio.c > @@ -271,10 +271,14 @@ static void bgpio_multiple_get_masks(struct gpio_chip *gc, > *clear_mask = 0; > > for_each_set_bit(i, mask, gc->bgpio_bits) { > - if (test_bit(i, bits)) > - *set_mask |= bgpio_line2mask(gc, i); > - else > - *clear_mask |= bgpio_line2mask(gc, i); > + if (*mask == 0) > + break; > + if (__test_and_clear_bit(i, mask)) { > + if (test_bit(i, bits)) > + *set_mask |= bgpio_line2mask(gc, i); > + else > + *clear_mask |= bgpio_line2mask(gc, i); > + } The intention of the change seems to be to break out of the loop when all set bits are handled, by successively masking off one bit at a time from mask. So this is intended as an optimization, not a simplification. I think for_each_set_bit() is already skipping over every bit that is zero, see include/linux/find.h. So this optimization gains us nothing. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1] gpio: mmio: restroe get multiple gpio mask 2023-04-24 6:56 ` Linus Walleij @ 2023-04-24 9:03 ` Yan Wang 0 siblings, 0 replies; 5+ messages in thread From: Yan Wang @ 2023-04-24 9:03 UTC (permalink / raw) To: Linus Walleij; +Cc: brgl, Andy Shevchenko, open list:GPIO SUBSYSTEM, open list On 4/24/2023 2:56 PM, Linus Walleij wrote: > Hi Yan, > > thanks for your patch! > > On Sun, Apr 23, 2023 at 11:07 AM Yan Wang <rk.code@outlook.com> wrote: > >> Simplify the code,should not modify its logic. > I don't see how it simplifies the code, it seems to me that it is > making it more complex? yes ,it is . The description is wrong. >> Fixes: 761b5c30c206 ("gpio: mmio: replace open-coded for_each_set_bit()") >> Signed-off-by: Yan Wang <rk.code@outlook.com> >> --- >> drivers/gpio/gpio-mmio.c | 12 ++++++++---- >> 1 file changed, 8 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c >> index d9dff3dc92ae..c2347ef3a4df 100644 >> --- a/drivers/gpio/gpio-mmio.c >> +++ b/drivers/gpio/gpio-mmio.c >> @@ -271,10 +271,14 @@ static void bgpio_multiple_get_masks(struct gpio_chip *gc, >> *clear_mask = 0; >> >> for_each_set_bit(i, mask, gc->bgpio_bits) { >> - if (test_bit(i, bits)) >> - *set_mask |= bgpio_line2mask(gc, i); >> - else >> - *clear_mask |= bgpio_line2mask(gc, i); >> + if (*mask == 0) >> + break; >> + if (__test_and_clear_bit(i, mask)) { >> + if (test_bit(i, bits)) >> + *set_mask |= bgpio_line2mask(gc, i); >> + else >> + *clear_mask |= bgpio_line2mask(gc, i); >> + } > The intention of the change seems to be to break out of the loop > when all set bits are handled, by successively masking off one > bit at a time from mask. So this is intended as an optimization, > not a simplification. Because my description is wrong and there is a difference in understanding between us. I think using for_each_set_bit() , but the __test_and_clear_bit() should not remove. > I think for_each_set_bit() is already skipping over every bit > that is zero, see include/linux/find.h. > > So this optimization gains us nothing. this a patch that only restores to original logic.the __test_and_clear_bit() clear mask then get a new set_mask. this logic can affect functions of gpiod_set_raw_array_value (). The effect of this patch is as follows: gpiod_set_raw_array_value-> gpiod_set_array_value_complex-> { .. if (array_info && array_info->desc == desc_array && array_size <= array_info->size && (void *)array_info == desc_array + array_info->size) { if (!can_sleep) WARN_ON(array_info->chip->can_sleep); if (!raw && !bitmap_empty(array_info->invert_mask, array_size)) bitmap_xor(value_bitmap, value_bitmap, array_info->invert_mask, array_size); gpio_chip_set_multiple(array_info->chip, array_info->set_mask, value_bitmap); i = find_first_zero_bit(array_info->set_mask, array_size); if (i == array_size) return 0; } else { array_info = NULL; } -> while (i < array_size) { struct gpio_chip *gc = desc_array[i]->gdev->chip; DECLARE_BITMAP(fastpath_mask, FASTPATH_NGPIO); DECLARE_BITMAP(fastpath_bits, FASTPATH_NGPIO); unsigned long *mask, *bits; int count = 0; .............. if (count != 0) gpio_chip_set_multiple(gc, mask, bits); .............. } return 0; } Due to __test_and_clear_bit() clear array_info->set_mask,the i < array_size condition holds. then calculate a new mask based on the GPIO number of the hardware. I reconfirmed it,Although it works, it should not be modified in the place. I think have a wrong of gpiod_get_array() and not bgpio_multiple_get_masks(). Link: https://lore.kernel.org/linux-gpio/KL1PR01MB5448327326B6EDA8001AF714E6669@KL1PR01MB5448.apcprd01.prod.exchangelabs.com/ this is a new patch. can you take a look ? Thank you. > Yours, > Linus Walleij ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1] gpio: mmio: restroe get multiple gpio mask 2023-04-23 9:06 [PATCH v1] gpio: mmio: restroe get multiple gpio mask Yan Wang 2023-04-24 6:56 ` Linus Walleij @ 2023-04-24 13:31 ` Andy Shevchenko 2023-04-24 14:21 ` Yan Wang 1 sibling, 1 reply; 5+ messages in thread From: Andy Shevchenko @ 2023-04-24 13:31 UTC (permalink / raw) To: Yan Wang; +Cc: linus.walleij, brgl, open list:GPIO SUBSYSTEM, open list On Sun, Apr 23, 2023 at 05:06:48PM +0800, Yan Wang wrote: > Simplify the code,should not modify its logic. > Fixes: 761b5c30c206 ("gpio: mmio: replace open-coded for_each_set_bit()") What does it fix? ... > for_each_set_bit(i, mask, gc->bgpio_bits) { > - if (test_bit(i, bits)) > - *set_mask |= bgpio_line2mask(gc, i); > - else > - *clear_mask |= bgpio_line2mask(gc, i); > + if (*mask == 0) > + break; Huh?! We never enter here if mask is 0. So, do not add a dead code, please. Moreover, in principle mask can be longer than 1 long, this code simply wrong. NAK > + if (__test_and_clear_bit(i, mask)) { > + if (test_bit(i, bits)) > + *set_mask |= bgpio_line2mask(gc, i); > + else > + *clear_mask |= bgpio_line2mask(gc, i); > + } > } -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1] gpio: mmio: restroe get multiple gpio mask 2023-04-24 13:31 ` Andy Shevchenko @ 2023-04-24 14:21 ` Yan Wang 0 siblings, 0 replies; 5+ messages in thread From: Yan Wang @ 2023-04-24 14:21 UTC (permalink / raw) To: Andy Shevchenko; +Cc: linus.walleij, brgl, open list:GPIO SUBSYSTEM, open list > On Apr 24, 2023, at 21:31, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote: > > On Sun, Apr 23, 2023 at 05:06:48PM +0800, Yan Wang wrote: >> Simplify the code,should not modify its logic. > >> Fixes: 761b5c30c206 ("gpio: mmio: replace open-coded for_each_set_bit()") > > What does it fix? > > ... > >> for_each_set_bit(i, mask, gc->bgpio_bits) { >> - if (test_bit(i, bits)) >> - *set_mask |= bgpio_line2mask(gc, i); >> - else >> - *clear_mask |= bgpio_line2mask(gc, i); >> + if (*mask == 0) >> + break; > > Huh?! > > We never enter here if mask is 0. So, do not add a dead code, please. > > Moreover, in principle mask can be longer than 1 long, this code simply wrong. You are right. Because I use gpiod_set_array_value_cansleep() to set multiple gpios occur wrong . I restored logic of the original code and found it to be effective. So,I try to modify it. I recheck logic of this position that it’s correct. I think there should be a error in Gpiolib. > NAK > >> + if (__test_and_clear_bit(i, mask)) { >> + if (test_bit(i, bits)) >> + *set_mask |= bgpio_line2mask(gc, i); >> + else >> + *clear_mask |= bgpio_line2mask(gc, i); >> + } >> } > > -- > With Best Regards, > Andy Shevchenko > > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-04-24 14:22 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-04-23 9:06 [PATCH v1] gpio: mmio: restroe get multiple gpio mask Yan Wang 2023-04-24 6:56 ` Linus Walleij 2023-04-24 9:03 ` Yan Wang 2023-04-24 13:31 ` Andy Shevchenko 2023-04-24 14:21 ` Yan Wang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox