diff --git a/drivers/gpio/gpio-hisi.c b/drivers/gpio/gpio-hisi.c index 29a03de37fd861300cb8e1a5b249c53f13a0f5ca..ef5cc654a24e2327510b872563e68fb0b9aaef71 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++; diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c index 97f4b498e343d1c9f6fdffb026dc5a3ede6075c7..87537657d040d8baab48cd8dbc835383681fa4b4 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 6c27312c6278835ffe9cf6aa529127b156ad5b39..6eefd5895034f2eb5b3b0c283364c423be5cd98e 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 efb592b6f6aa7a74d9089b7784d5d7e229fddef7..35b01d02008ef63569a5fdde1971a7ce4b66288d 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 9bbde38238d33ab3b37211abd1c20f303e7e71e0..8cc7aab02aece1b56441ccf08b4c053218d08f37 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 7ecc25c543cef36b24425b479492dc366a7003da..f4e5406554bb9b033a6c6ce16d123d8e6245cef7 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.