gpiolib: Get rid of never false gpio_is_valid() calls
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Wed, 21 Feb 2024 21:31:56 +0000 (23:31 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Wed, 17 Apr 2024 20:46:44 +0000 (22:46 +0200)
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 <andriy.shevchenko@linux.intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
drivers/gpio/gpiolib-legacy.c
drivers/gpio/gpiolib-sysfs.c
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.h
include/linux/gpio.h

index 616d60187f85885869b4d812eafb087bf8f2fe7c..5a9911ae912509c978e800731871ab671a713fbd 100644 (file)
@@ -28,10 +28,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);
@@ -63,10 +62,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);
index 6853ecd98bcb8c5e4a8e3ebaa9448684b0057ad2..26202586fd39dea51c8b1f34643132094cc2fec2 100644 (file)
@@ -412,7 +412,7 @@ static ssize_t base_show(struct device *dev,
 {
        const struct gpio_device *gdev = dev_get_drvdata(dev);
 
-       return sysfs_emit(buf, "%d\n", gdev->base);
+       return sysfs_emit(buf, "%u\n", gdev->base);
 }
 static DEVICE_ATTR_RO(base);
 
index f20367b1ea8eee51f845b4a19b0df8c6644a3524..f749ece2d3cd1d5286fdf86bb05fc186bfee81e6 100644 (file)
@@ -150,9 +150,6 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
                }
        }
 
-       if (!gpio_is_valid(gpio))
-               pr_warn("invalid GPIO %d\n", gpio);
-
        return NULL;
 }
 EXPORT_SYMBOL_GPL(gpio_to_desc);
@@ -297,10 +294,10 @@ struct gpio_chip *gpio_device_get_chip(struct gpio_device *gdev)
 EXPORT_SYMBOL_GPL(gpio_device_get_chip);
 
 /* dynamic allocation of GPIOs, e.g. on a hotplugged device */
-static int gpiochip_find_base_unlocked(int ngpio)
+static int gpiochip_find_base_unlocked(u16 ngpio)
 {
+       unsigned int base = GPIO_DYNAMIC_BASE;
        struct gpio_device *gdev;
-       int base = GPIO_DYNAMIC_BASE;
 
        list_for_each_entry_srcu(gdev, &gpio_devices, list,
                                 lockdep_is_held(&gpio_devices_lock)) {
@@ -311,9 +308,11 @@ static int gpiochip_find_base_unlocked(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 {
@@ -749,7 +748,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->label);
 
        return 0;
@@ -4788,14 +4787,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 ?: "", gpiod_get_label(desc),
                                   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++;
@@ -4867,7 +4866,7 @@ static int gpiolib_seq_show(struct seq_file *s, void *v)
                return 0;
        }
 
-       seq_printf(s, "%s%s: GPIOs %d-%d", priv->newline ? "\n" : "",
+       seq_printf(s, "%s%s: GPIOs %u-%u", priv->newline ? "\n" : "",
                   dev_name(&gdev->dev),
                   gdev->base, gdev->base + gdev->ngpio - 1);
        parent = gc->parent;
index f67d5991ab1c7a58d375b2f6bd3275b41adb8ade..7f94580efdbca29a05f03a53e8305838d63b2f63 100644 (file)
@@ -61,7 +61,7 @@ struct gpio_device {
        struct module           *owner;
        struct gpio_chip __rcu  *chip;
        struct gpio_desc        *descs;
-       int                     base;
+       unsigned int            base;
        u16                     ngpio;
        bool                    can_sleep;
        const char              *label;
index 4aaedcf424ce61582b1b3e0c029115d6f4f0e669..56ac7e7a288903fd39c2567f98ff2987ba022b18 100644 (file)
@@ -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.