gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag()
PATCH v2 1/5 gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag()
The iterator loop is used exclusively to get a descriptor, which in its turn is what is being used by the caller. Embed the iterator variable into the loop in the for_each_gpio_desc_with_flag() macro helper.
---
v2: new patch
drivers/gpio/gpiolib-of.c | 3 +-- drivers/gpio/gpiolib-sysfs.c | 3 +-- drivers/gpio/gpiolib.c | 3 +-- drivers/gpio/gpiolib.h | 8 ++++---- 4 files changed, 7 insertions(+), 10 deletions(-)
drivers/gpio/gpiolib-of.c +1 -2
@@ -712,9 +712,8 @@ static void of_gpiochip_remove_hog(struct gpio_chip *chip, struct device_node *hog) {struct gpio_desc *desc; -unsigned int i; -for_each_gpio_desc_with_flag (i, chip, desc,FLAG_IS_HOGGED ) +for_each_gpio_desc_with_flag (chip, desc,FLAG_IS_HOGGED )if (desc->hog == hog)gpiochip_free_own_desc (desc); }
drivers/gpio/gpiolib-sysfs.c +1 -2
@@ -760,7 +760,6 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev) {struct gpio_desc *desc;struct gpio_chip *chip = gdev->chip; -unsigned int i;if (!gdev->mockdev)return ;
@@ -773,7 +772,7 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)mutex_unlock (&sysfs_lock);/* unregister gpiod class devices owned by sysfs */ -for_each_gpio_desc_with_flag (i, chip, desc,FLAG_SYSFS ) +for_each_gpio_desc_with_flag (chip, desc,FLAG_SYSFS )gpiod_free (desc); }
drivers/gpio/gpiolib.c +1 -2
@@ -4138,9 +4138,8 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,static void gpiochip_free_hogs (struct gpio_chip *gc) {struct gpio_desc *desc; -int id; -for_each_gpio_desc_with_flag (id, gc, desc,FLAG_IS_HOGGED ) +for_each_gpio_desc_with_flag (gc, desc,FLAG_IS_HOGGED )gpiochip_free_own_desc (desc); }
drivers/gpio/gpiolib.h +4 -4
@@ -100,10 +100,10 @@ struct gpio_array {struct gpio_desc *gpiochip_get_desc (struct gpio_chip *gc,unsigned int hwnum); -#define for_each_gpio_desc_with_flag (i, gc, desc, flag) \ - for (i = 0, desc = gpiochip_get_desc(gc, i); \ - i < gc->ngpio; \ - i++, desc = gpiochip_get_desc(gc, i)) \ +#define for_each_gpio_desc_with_flag (gc, desc, flag) \ + for (unsigned int __i = 0; \ + __i < gc->ngpio && (desc = gpiochip_get_desc(gc, __i)); \ + __i++) \ if (!test_bit(flag, &desc->flags)) {} else int gpiod_get_array_value_complex(bool raw, bool can_sleep,
Signature · 1 line
2.35.1
PATCH v2 2/5 gpiolib: Split out for_each_gpio_desc() macro
In some cases we want to traverse all GPIO descriptors for given chip, let's split out for_each_gpio_desc() macro for such cases.
---
v2: rebased on patch 1
drivers/gpio/gpiolib.c | 11 +++-------- drivers/gpio/gpiolib.h | 5 ++++- 2 files changed, 7 insertions(+), 9 deletions(-)
drivers/gpio/gpiolib.c +3 -8
@@ -309,15 +309,10 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)spin_lock_irqsave (&gpio_lock, flags);list_for_each_entry (gdev, &gpio_devices, list) { -int i; - -for (i =0 ; i != gdev->ngpio; ++i) { -struct gpio_desc *desc = &gdev->descs[i]; - -if (!desc->name) -continue ; +struct gpio_desc *desc; -if (!strcmp (desc->name, name)) { +for_each_gpio_desc (gdev->chip, desc) { +if (desc->name && !strcmp (desc->name, name)) {spin_unlock_irqrestore (&gpio_lock, flags);return desc; }
drivers/gpio/gpiolib.h +4 -1
@@ -100,10 +100,13 @@ struct gpio_array {struct gpio_desc *gpiochip_get_desc (struct gpio_chip *gc,unsigned int hwnum); -#define for_each_gpio_desc_with_flag (gc, desc, flag) \ +#define for_each_gpio_desc (gc, desc) \ for (unsigned int __i = 0; \ __i < gc->ngpio && (desc = gpiochip_get_desc(gc, __i)); \ __i++) \ + +#define for_each_gpio_desc_with_flag (gc, desc, flag) \ + for_each_gpio_desc(gc, desc) \ if (!test_bit(flag, &desc->flags)) {} else int gpiod_get_array_value_complex(bool raw, bool can_sleep,
Signature · 1 line
2.35.1
PATCH v2 3/5 gpiolib: Refactor gpiolib_dbg_show() with help of for_each_gpio_desc()
In reply to Andy ShevchenkoUse for_each_gpio_desc() and since we would need to touch the entire conditionals, do the following:
- rename last occurrence of gdesc to desc
- use short ternary operator ?:
- join two seq_printf() calls into single one
- fix indentation of the seq_printf() parameters
---
v2: rebased on patch 1
drivers/gpio/gpiolib.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-)
drivers/gpio/gpiolib.c +18 -20
@@ -4394,34 +4394,32 @@ core_initcall(gpiolib_dev_init);static void gpiolib_dbg_show (struct seq_file *s,struct gpio_device *gdev) { -unsigned i;struct gpio_chip *gc = gdev->chip; +struct gpio_desc *desc;unsigned gpio = gdev->base; -struct gpio_desc *gdesc = &gdev->descs[0 ]; +int value;bool is_out;bool is_irq;bool active_low; -for (i =0 ; i < gdev->ngpio; i++, gpio++, gdesc++) { -if (!test_bit (FLAG_REQUESTED , &gdesc->flags)) { -if (gdesc->name) { -seq_printf (s," gpio-%-3d (%-20.20s)\n" , - gpio, gdesc->name); - } -continue ; +for_each_gpio_desc (gc, desc) { +if (test_bit (FLAG_REQUESTED , &desc->flags)) { +gpiod_get_direction (desc); + is_out =test_bit (FLAG_IS_OUT , &desc->flags); + value = gc->get ? gc->get (gc,gpio_chip_hwgpio (desc)) : -EIO ; + is_irq =test_bit (FLAG_USED_AS_IRQ , &desc->flags); + active_low =test_bit (FLAG_ACTIVE_LOW , &desc->flags); +seq_printf (s," gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s\n" , + gpio, desc->name ?:"" , desc->label, + is_out ?"out" :"in " , + value >=0 ? (value ?"hi" :"lo" ) :"? " , + is_irq ?"IRQ " :"" , + active_low ?"ACTIVE LOW" :"" ); + }else if (desc->name) { +seq_printf (s," gpio-%-3d (%-20.20s)\n" , gpio, desc->name); } -gpiod_get_direction (gdesc); - is_out =test_bit (FLAG_IS_OUT , &gdesc->flags); - is_irq =test_bit (FLAG_USED_AS_IRQ , &gdesc->flags); - active_low =test_bit (FLAG_ACTIVE_LOW , &gdesc->flags); -seq_printf (s," gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s" , - gpio, gdesc->name ? gdesc->name :"" , gdesc->label, - is_out ?"out" :"in " , - gc->get ? (gc->get (gc, i) ?"hi" :"lo" ) :"? " , - is_irq ?"IRQ " :"" , - active_low ?"ACTIVE LOW" :"" ); -seq_printf (s,"\n" ); + gpio++; } }
Signature · 1 line
2.35.1
PATCH v2 4/5 gpiolib: Extract gpio_chip_get_value() wrapper
In reply to Andy ShevchenkoIn couple of cases we are using the same code to wrap ->get() callback. Extract that code into a helper for the sake of better maintenance.
---
v2: new patch
drivers/gpio/gpiolib.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/gpio/gpiolib.c +7 -4
@@ -2532,6 +2532,11 @@ void gpiod_toggle_active_low(struct gpio_desc *desc) }EXPORT_SYMBOL_GPL (gpiod_toggle_active_low); +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 ; +} +/* I/O calls are only valid after configuration completed; the relevant * "is this a valid GPIO" error checks should already have been done. *
@@ -2557,12 +2562,10 @@ EXPORT_SYMBOL_GPL(gpiod_toggle_active_low);static int gpiod_get_raw_value_commit (const struct gpio_desc *desc) {struct gpio_chip *gc; -int offset;int value; gc = desc->gdev->chip; - offset =gpio_chip_hwgpio (desc); - value = gc->get ? gc->get (gc, offset) : -EIO ; + value =gpio_chip_get_value (gc, desc); value = value <0 ? value : !!value;trace_gpio_value (desc_to_gpio (desc),1 , value);return value;
@@ -4406,7 +4409,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)if (test_bit (FLAG_REQUESTED , &desc->flags)) {gpiod_get_direction (desc); is_out =test_bit (FLAG_IS_OUT , &desc->flags); - value = gc->get ? gc->get (gc,gpio_chip_hwgpio (desc)) : -EIO ; + value =gpio_chip_get_value (gc, desc); is_irq =test_bit (FLAG_USED_AS_IRQ , &desc->flags); active_low =test_bit (FLAG_ACTIVE_LOW , &desc->flags); seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s\n",
Signature · 1 line
2.35.1
PATCH v2 5/5 gpiolib: Move error message out of a spinlock
In reply to Andy ShevchenkoAn error path is a slow path, no need to block other CPUs when printing error messages.
---
v2: no changes
drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpiolib.c +1 -1
@@ -288,7 +288,6 @@ static int gpiodev_add_to_list(struct gpio_device *gdev) } } -dev_err (&gdev->dev,"GPIO integer space overlap, cannot add chip\n" );return -EBUSY ; }
@@ -722,6 +721,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ret =gpiodev_add_to_list (gdev);if (ret) {spin_unlock_irqrestore (&gpio_lock, flags); +chip_err (gc,"GPIO integer space overlap, cannot add chip\n" ); goto err_free_label; }
Signature · 1 line
2.35.1
Bartosz Golaszewski
AppliedQuoted 7 lines · Andy Shevchenko
The iterator loop is used exclusively to get a descriptor, which in its turn is what is being used by the caller. Embed the iterator variable into the loop in the
for_each_gpio_desc_with_flag()macro helper.Suggested-by Bartosz Golaszewski <[email protected]>Signed-off-by Andy Shevchenko <[email protected]>
Applied, this entire series, thanks!
Bart