From 79e7bf0aeed58f5e9f2674e5f7d9395267ebcd81 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 21 Feb 2024 23:31:56 +0200 Subject: [PATCH 1/2] gpiolib: Get rid of never false gpio_is_valid() calls ANBZ: #28978 commit 8a7a6103258715857310253ec2193bcc4d1d7082 upstream In the cases when gpio_is_valid() is called with unsigned parameter the result is always true in the GPIO library code, hence the check for false won't ever be true. Get rid of such calls. While at it, move GPIO device base to be unsigned to clearly show it won't ever be negative. This requires a new definition for the maximum GPIO number in the system. Signed-off-by: Andy Shevchenko Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski Signed-off-by: zhangxinghao --- drivers/gpio/gpiolib-legacy.c | 10 +++++----- drivers/gpio/gpiolib-sysfs.c | 2 +- drivers/gpio/gpiolib.c | 19 +++++++++---------- drivers/gpio/gpiolib.h | 2 +- include/linux/gpio.h | 6 ++++++ 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c index 97f4b498e343..87537657d040 100644 --- a/drivers/gpio/gpiolib-legacy.c +++ b/drivers/gpio/gpiolib-legacy.c @@ -23,10 +23,9 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) struct gpio_desc *desc; int err; - desc = gpio_to_desc(gpio); - /* Compatibility: assume unavailable "valid" GPIOs will appear later */ - if (!desc && gpio_is_valid(gpio)) + desc = gpio_to_desc(gpio); + if (!desc) return -EPROBE_DEFER; err = gpiod_request(desc, label); @@ -55,10 +54,11 @@ EXPORT_SYMBOL_GPL(gpio_request_one); int gpio_request(unsigned gpio, const char *label) { - struct gpio_desc *desc = gpio_to_desc(gpio); + struct gpio_desc *desc; /* Compatibility: assume unavailable "valid" GPIOs will appear later */ - if (!desc && gpio_is_valid(gpio)) + desc = gpio_to_desc(gpio); + if (!desc) return -EPROBE_DEFER; return gpiod_request(desc, label); diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 6c27312c6278..6eefd5895034 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -402,7 +402,7 @@ static ssize_t base_show(struct device *dev, { const struct gpio_chip *chip = dev_get_drvdata(dev); - return sysfs_emit(buf, "%d\n", chip->base); + return sysfs_emit(buf, "%u\n", chip->base); } static DEVICE_ATTR_RO(base); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index efb592b6f6aa..35b01d02008e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -140,9 +140,6 @@ struct gpio_desc *gpio_to_desc(unsigned gpio) spin_unlock_irqrestore(&gpio_lock, flags); - if (!gpio_is_valid(gpio)) - pr_warn("invalid GPIO %d\n", gpio); - return NULL; } EXPORT_SYMBOL_GPL(gpio_to_desc); @@ -199,10 +196,10 @@ struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) EXPORT_SYMBOL_GPL(gpiod_to_chip); /* dynamic allocation of GPIOs, e.g. on a hotplugged device */ -static int gpiochip_find_base(int ngpio) +static int gpiochip_find_base(u16 ngpio) { + unsigned int base = GPIO_DYNAMIC_BASE; struct gpio_device *gdev; - int base = GPIO_DYNAMIC_BASE; list_for_each_entry(gdev, &gpio_devices, list) { /* found a free space? */ @@ -212,9 +209,11 @@ static int gpiochip_find_base(int ngpio) base = gdev->base + gdev->ngpio; if (base < GPIO_DYNAMIC_BASE) base = GPIO_DYNAMIC_BASE; + if (base > GPIO_DYNAMIC_MAX - ngpio) + break; } - if (gpio_is_valid(base)) { + if (base <= GPIO_DYNAMIC_MAX - ngpio) { pr_debug("%s: found new base at %d\n", __func__, base); return base; } else { @@ -625,7 +624,7 @@ static int gpiochip_setup_dev(struct gpio_device *gdev) if (ret) goto err_remove_device; - dev_dbg(&gdev->dev, "registered GPIOs %d to %d on %s\n", gdev->base, + dev_dbg(&gdev->dev, "registered GPIOs %u to %u on %s\n", gdev->base, gdev->base + gdev->ngpio - 1, gdev->chip->label ? : "generic"); return 0; @@ -4611,14 +4610,14 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) 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", + seq_printf(s, " gpio-%-3u (%-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); + seq_printf(s, " gpio-%-3u (%-20.20s)\n", gpio, desc->name); } gpio++; @@ -4679,7 +4678,7 @@ static int gpiolib_seq_show(struct seq_file *s, void *v) return 0; } - seq_printf(s, "%s%s: GPIOs %d-%d", (char *)s->private, + seq_printf(s, "%s%s: GPIOs %u-%u", (char *)s->private, dev_name(&gdev->dev), gdev->base, gdev->base + gdev->ngpio - 1); parent = gc->parent; diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 9bbde38238d3..8cc7aab02aec 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -61,7 +61,7 @@ struct gpio_device { struct module *owner; struct gpio_chip *chip; struct gpio_desc *descs; - int base; + unsigned int base; u16 ngpio; const char *label; void *data; diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 7ecc25c543ce..f4e5406554bb 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -74,6 +74,12 @@ static inline bool gpio_is_valid(int number) * Until they are all fixed, leave 0-512 space for them. */ #define GPIO_DYNAMIC_BASE 512 +/* + * Define the maximum of the possible GPIO in the global numberspace. + * While the GPIO base and numbers are positive, we limit it with signed + * maximum as a lot of code is using negative values for special cases. + */ +#define GPIO_DYNAMIC_MAX INT_MAX /* Always use the library code for GPIO management calls, * or when sleeping may be involved. -- Gitee From bc8fbd84b1f55d467c4c359372aca3d3e4bf6dcf Mon Sep 17 00:00:00 2001 From: Devyn Liu Date: Thu, 12 Oct 2023 18:54:11 +0800 Subject: [PATCH 2/2] gpio: hisi: Fix format specifier ANBZ: #28978 commit 4f3b436eea7d7242ca5c528fca1d2d15bc242190 upstream The hisi_gpio->line is unsigned int so the format specifier should have been %u not %d. Signed-off-by: Devyn Liu Signed-off-by: Bartosz Golaszewski Signed-off-by: zhangxinghao --- drivers/gpio/gpio-hisi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-hisi.c b/drivers/gpio/gpio-hisi.c index 29a03de37fd8..ef5cc654a24e 100644 --- a/drivers/gpio/gpio-hisi.c +++ b/drivers/gpio/gpio-hisi.c @@ -255,7 +255,7 @@ static void hisi_gpio_get_pdata(struct device *dev, hisi_gpio->irq = platform_get_irq(pdev, idx); dev_info(dev, - "get hisi_gpio[%d] with %d lines\n", idx, + "get hisi_gpio[%d] with %u lines\n", idx, hisi_gpio->line_num); idx++; -- Gitee