linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag()
@ 2022-04-08 18:18 Andy Shevchenko
  2022-04-08 18:18 ` [PATCH v2 2/5] gpiolib: Split out for_each_gpio_desc() macro Andy Shevchenko
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Andy Shevchenko @ 2022-04-08 18:18 UTC (permalink / raw)
  To: Bartosz Golaszewski, Andy Shevchenko, linux-gpio, linux-kernel
  Cc: Linus Walleij

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 <brgl@bgdev.pl>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
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(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index ae1ce319cd78..47c0e07802d6 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -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);
 }
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index d44ffea038f5..cd27bf173dec 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -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);
 }
 
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index a199d2ff7689..96b5da6a8c3b 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -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);
 }
 
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 06f3faa9fbef..7bac62d36f0c 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -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,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/5] gpiolib: Split out for_each_gpio_desc() macro
  2022-04-08 18:18 [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Andy Shevchenko
@ 2022-04-08 18:18 ` Andy Shevchenko
  2022-04-08 18:18 ` [PATCH v2 3/5] gpiolib: Refactor gpiolib_dbg_show() with help of for_each_gpio_desc() Andy Shevchenko
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2022-04-08 18:18 UTC (permalink / raw)
  To: Bartosz Golaszewski, Andy Shevchenko, linux-gpio, linux-kernel
  Cc: Linus Walleij

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.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v2: rebased on patch 1
 drivers/gpio/gpiolib.c | 11 +++--------
 drivers/gpio/gpiolib.h |  5 ++++-
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 96b5da6a8c3b..58a57540b834 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -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;
 			}
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 7bac62d36f0c..eef3ec073d9e 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -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,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/5] gpiolib: Refactor gpiolib_dbg_show() with help of for_each_gpio_desc()
  2022-04-08 18:18 [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Andy Shevchenko
  2022-04-08 18:18 ` [PATCH v2 2/5] gpiolib: Split out for_each_gpio_desc() macro Andy Shevchenko
@ 2022-04-08 18:18 ` Andy Shevchenko
  2022-04-08 18:18 ` [PATCH v2 4/5] gpiolib: Extract gpio_chip_get_value() wrapper Andy Shevchenko
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2022-04-08 18:18 UTC (permalink / raw)
  To: Bartosz Golaszewski, Andy Shevchenko, linux-gpio, linux-kernel
  Cc: Linus Walleij

Use 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

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v2: rebased on patch 1
 drivers/gpio/gpiolib.c | 38 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 58a57540b834..43b0cae69bcd 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -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++;
 	}
 }
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/5] gpiolib: Extract gpio_chip_get_value() wrapper
  2022-04-08 18:18 [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Andy Shevchenko
  2022-04-08 18:18 ` [PATCH v2 2/5] gpiolib: Split out for_each_gpio_desc() macro Andy Shevchenko
  2022-04-08 18:18 ` [PATCH v2 3/5] gpiolib: Refactor gpiolib_dbg_show() with help of for_each_gpio_desc() Andy Shevchenko
@ 2022-04-08 18:18 ` Andy Shevchenko
  2022-04-08 18:18 ` [PATCH v2 5/5] gpiolib: Move error message out of a spinlock Andy Shevchenko
  2022-04-09 20:39 ` [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Bartosz Golaszewski
  4 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2022-04-08 18:18 UTC (permalink / raw)
  To: Bartosz Golaszewski, Andy Shevchenko, linux-gpio, linux-kernel
  Cc: Linus Walleij

In 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.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v2: new patch
 drivers/gpio/gpiolib.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 43b0cae69bcd..f537597838bb 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -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",
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 5/5] gpiolib: Move error message out of a spinlock
  2022-04-08 18:18 [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Andy Shevchenko
                   ` (2 preceding siblings ...)
  2022-04-08 18:18 ` [PATCH v2 4/5] gpiolib: Extract gpio_chip_get_value() wrapper Andy Shevchenko
@ 2022-04-08 18:18 ` Andy Shevchenko
  2022-04-09 20:39 ` [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Bartosz Golaszewski
  4 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2022-04-08 18:18 UTC (permalink / raw)
  To: Bartosz Golaszewski, Andy Shevchenko, linux-gpio, linux-kernel
  Cc: Linus Walleij

An error path is a slow path, no need to block other CPUs
when printing error messages.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
v2: no changes
 drivers/gpio/gpiolib.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f537597838bb..6af9cd4566fb 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -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;
 	}
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag()
  2022-04-08 18:18 [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Andy Shevchenko
                   ` (3 preceding siblings ...)
  2022-04-08 18:18 ` [PATCH v2 5/5] gpiolib: Move error message out of a spinlock Andy Shevchenko
@ 2022-04-09 20:39 ` Bartosz Golaszewski
  4 siblings, 0 replies; 6+ messages in thread
From: Bartosz Golaszewski @ 2022-04-09 20:39 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: open list:GPIO SUBSYSTEM, Linux Kernel Mailing List,
	Linus Walleij

On Fri, Apr 8, 2022 at 8:19 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> 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 <brgl@bgdev.pl>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Applied, this entire series, thanks!

Bart

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-04-09 20:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-04-08 18:18 [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Andy Shevchenko
2022-04-08 18:18 ` [PATCH v2 2/5] gpiolib: Split out for_each_gpio_desc() macro Andy Shevchenko
2022-04-08 18:18 ` [PATCH v2 3/5] gpiolib: Refactor gpiolib_dbg_show() with help of for_each_gpio_desc() Andy Shevchenko
2022-04-08 18:18 ` [PATCH v2 4/5] gpiolib: Extract gpio_chip_get_value() wrapper Andy Shevchenko
2022-04-08 18:18 ` [PATCH v2 5/5] gpiolib: Move error message out of a spinlock Andy Shevchenko
2022-04-09 20:39 ` [PATCH v2 1/5] gpiolib: Embed iterator variable into for_each_gpio_desc_with_flag() Bartosz Golaszewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).