* [PATCH v11 3/4] gpio: thunderx: Utilize for_each_set_clump macro
2020-10-06 9:20 [PATCH v11 0/4] Introduce the for_each_set_clump macro Syed Nayyar Waris
@ 2020-10-06 9:24 ` Syed Nayyar Waris
2020-10-06 9:26 ` [PATCH v11 4/4] gpio: xilinx: Utilize generic bitmap_get_value and _set_value Syed Nayyar Waris
2020-10-07 8:38 ` [PATCH v11 0/4] Introduce the for_each_set_clump macro Linus Walleij
2 siblings, 0 replies; 5+ messages in thread
From: Syed Nayyar Waris @ 2020-10-06 9:24 UTC (permalink / raw)
To: linus.walleij, akpm
Cc: andriy.shevchenko, vilhelm.gray, rrichter, bgolaszewski,
linux-gpio, linux-kernel
This patch reimplements the thunderx_gpio_set_multiple function in
drivers/gpio/gpio-thunderx.c to use the new for_each_set_clump macro.
Instead of looping for each bank in thunderx_gpio_set_multiple
function, now we can skip bank which is not set and save cycles.
Cc: Robert Richter <rrichter@marvell.com>
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
---
Changes in v11:
- No change.
Changes in v10:
- No change.
Changes in v9:
- No change.
Changes in v8:
- No change.
Changes in v7:
- No change.
Changes in v6:
- No change.
Changes in v5:
- No change.
Changes in v4:
- Minor change: Inline value '64' in code for better code readability.
Changes in v3:
- Change datatype of some variables from u64 to unsigned long
in function thunderx_gpio_set_multiple.
Changes in v2:
- No change.
drivers/gpio/gpio-thunderx.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/gpio/gpio-thunderx.c b/drivers/gpio/gpio-thunderx.c
index 9f66deab46ea..58c9bb25a377 100644
--- a/drivers/gpio/gpio-thunderx.c
+++ b/drivers/gpio/gpio-thunderx.c
@@ -275,12 +275,15 @@ static void thunderx_gpio_set_multiple(struct gpio_chip *chip,
unsigned long *bits)
{
int bank;
- u64 set_bits, clear_bits;
+ unsigned long set_bits, clear_bits, gpio_mask;
+ unsigned long offset;
+
struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
- for (bank = 0; bank <= chip->ngpio / 64; bank++) {
- set_bits = bits[bank] & mask[bank];
- clear_bits = ~bits[bank] & mask[bank];
+ for_each_set_clump(offset, gpio_mask, mask, chip->ngpio, 64) {
+ bank = offset / 64;
+ set_bits = bits[bank] & gpio_mask;
+ clear_bits = ~bits[bank] & gpio_mask;
writeq(set_bits, txgpio->register_base + (bank * GPIO_2ND_BANK) + GPIO_TX_SET);
writeq(clear_bits, txgpio->register_base + (bank * GPIO_2ND_BANK) + GPIO_TX_CLR);
}
--
2.26.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v11 4/4] gpio: xilinx: Utilize generic bitmap_get_value and _set_value
2020-10-06 9:20 [PATCH v11 0/4] Introduce the for_each_set_clump macro Syed Nayyar Waris
2020-10-06 9:24 ` [PATCH v11 3/4] gpio: thunderx: Utilize " Syed Nayyar Waris
@ 2020-10-06 9:26 ` Syed Nayyar Waris
2020-10-07 8:38 ` [PATCH v11 0/4] Introduce the for_each_set_clump macro Linus Walleij
2 siblings, 0 replies; 5+ messages in thread
From: Syed Nayyar Waris @ 2020-10-06 9:26 UTC (permalink / raw)
To: linus.walleij, akpm
Cc: andriy.shevchenko, vilhelm.gray, bgolaszewski, michal.simek,
linux-gpio, linux-arm-kernel, linux-kernel
This patch reimplements the xgpio_set_multiple function in
drivers/gpio/gpio-xilinx.c to use the new generic functions:
bitmap_get_value and bitmap_set_value. The code is now simpler
to read and understand. Moreover, instead of looping for each bit
in xgpio_set_multiple function, now we can check each channel at
a time and save cycles.
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Syed Nayyar Waris <syednwaris@gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
---
Changes in v11:
- Change variable name 'flag' to 'flags'.
Changes in v10:
- No change.
Changes in v9:
- Remove looping of 'for_each_set_clump' and instead process two
halves of a 64-bit bitmap separately or individually. Use normal spin_lock
call for second inner lock. And take the spin_lock_init call outside the 'if'
condition in the 'probe' function of driver.
Changes in v8:
- No change.
Changes in v7:
- No change.
Changes in v6:
- No change.
Changes in v5:
- Minor change: Inline values '32' and '64' in code for better
code readability.
Changes in v4:
- Minor change: Inline values '32' and '64' in code for better
code readability.
Changes in v3:
- No change.
Changes in v2:
- No change
drivers/gpio/gpio-xilinx.c | 64 +++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 32 deletions(-)
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 67f9f82e0db0..f86bee271246 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -138,37 +138,37 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
{
unsigned long flags;
struct xgpio_instance *chip = gpiochip_get_data(gc);
- int index = xgpio_index(chip, 0);
- int offset, i;
-
- spin_lock_irqsave(&chip->gpio_lock[index], flags);
-
- /* Write to GPIO signals */
- for (i = 0; i < gc->ngpio; i++) {
- if (*mask == 0)
- break;
- /* Once finished with an index write it out to the register */
- if (index != xgpio_index(chip, i)) {
- xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
- index * XGPIO_CHANNEL_OFFSET,
- chip->gpio_state[index]);
- spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
- index = xgpio_index(chip, i);
- spin_lock_irqsave(&chip->gpio_lock[index], flags);
- }
- if (__test_and_clear_bit(i, mask)) {
- offset = xgpio_offset(chip, i);
- if (test_bit(i, bits))
- chip->gpio_state[index] |= BIT(offset);
- else
- chip->gpio_state[index] &= ~BIT(offset);
- }
- }
-
- xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
- index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]);
-
- spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
+ u32 *const state = chip->gpio_state;
+ unsigned int *const width = chip->gpio_width;
+
+ DECLARE_BITMAP(old, 64);
+ DECLARE_BITMAP(new, 64);
+ DECLARE_BITMAP(changed, 64);
+
+ spin_lock_irqsave(&chip->gpio_lock[0], flags);
+ spin_lock(&chip->gpio_lock[1]);
+
+ bitmap_set_value(old, state[0], 0, width[0]);
+ bitmap_set_value(old, state[1], width[0], width[1]);
+ bitmap_replace(new, old, bits, mask, gc->ngpio);
+
+ bitmap_set_value(old, state[0], 0, 32);
+ bitmap_set_value(old, state[1], 32, 32);
+ state[0] = bitmap_get_value(new, 0, width[0]);
+ state[1] = bitmap_get_value(new, width[0], width[1]);
+ bitmap_set_value(new, state[0], 0, 32);
+ bitmap_set_value(new, state[1], 32, 32);
+ bitmap_xor(changed, old, new, 64);
+
+ if (((u32 *)changed)[0])
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET,
+ state[0]);
+ if (((u32 *)changed)[1])
+ xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
+ XGPIO_CHANNEL_OFFSET, state[1]);
+
+ spin_unlock(&chip->gpio_lock[1]);
+ spin_unlock_irqrestore(&chip->gpio_lock[0], flags);
}
/**
@@ -292,6 +292,7 @@ static int xgpio_probe(struct platform_device *pdev)
chip->gpio_width[0] = 32;
spin_lock_init(&chip->gpio_lock[0]);
+ spin_lock_init(&chip->gpio_lock[1]);
if (of_property_read_u32(np, "xlnx,is-dual", &is_dual))
is_dual = 0;
@@ -314,7 +315,6 @@ static int xgpio_probe(struct platform_device *pdev)
&chip->gpio_width[1]))
chip->gpio_width[1] = 32;
- spin_lock_init(&chip->gpio_lock[1]);
}
chip->gc.base = -1;
--
2.26.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v11 0/4] Introduce the for_each_set_clump macro
2020-10-06 9:20 [PATCH v11 0/4] Introduce the for_each_set_clump macro Syed Nayyar Waris
2020-10-06 9:24 ` [PATCH v11 3/4] gpio: thunderx: Utilize " Syed Nayyar Waris
2020-10-06 9:26 ` [PATCH v11 4/4] gpio: xilinx: Utilize generic bitmap_get_value and _set_value Syed Nayyar Waris
@ 2020-10-07 8:38 ` Linus Walleij
2020-10-23 13:20 ` Syed Nayyar Waris
2 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2020-10-07 8:38 UTC (permalink / raw)
To: Syed Nayyar Waris
Cc: Andrew Morton, Andy Shevchenko, William Breathitt Gray,
Michal Simek, Arnd Bergmann, Robert Richter, Bartosz Golaszewski,
Masahiro Yamada, Zhang Rui, Daniel Lezcano,
(Exiting) Amit Kucheria, Linux-Arch, open list:GPIO SUBSYSTEM,
linux-kernel@vger.kernel.org, Linux ARM, Linux PM list
On Tue, Oct 6, 2020 at 11:20 AM Syed Nayyar Waris <syednwaris@gmail.com> wrote:
> Since this patchset primarily affects GPIO drivers, would you like
> to pick it up through your GPIO tree?
Definitely will, once we are finished!
I see Andy still has comments and we need more iterations.
That is fine, because we are not in any hurry. Just keep posting
it!
Let's merge this for v5.11 when we are finished with it.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 5+ messages in thread