diff options
-rw-r--r-- | Documentation/gpio/board.txt | 11 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 4 | ||||
-rw-r--r-- | drivers/gpio/gpio-moxart.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-pisosr.c | 4 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-sysfs.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 73 | ||||
-rw-r--r-- | include/uapi/linux/gpio.h | 22 | ||||
-rw-r--r-- | tools/gpio/lsgpio.c | 6 |
8 files changed, 64 insertions, 71 deletions
diff --git a/Documentation/gpio/board.txt b/Documentation/gpio/board.txt index 3092178628c4..86d3fa95fd12 100644 --- a/Documentation/gpio/board.txt +++ b/Documentation/gpio/board.txt @@ -111,16 +111,13 @@ files that desire to do so need to include the following header: GPIOs are mapped by the means of tables of lookups, containing instances of the gpiod_lookup structure. Two macros are defined to help declaring such mappings: - GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags) - GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags) + GPIO_LOOKUP(chip_label, chip_hwnum, con_id, flags) + GPIO_LOOKUP_IDX(chip_label, chip_hwnum, con_id, idx, flags) where - chip_label is the label of the gpiod_chip instance providing the GPIO - chip_hwnum is the hardware number of the GPIO within the chip - - dev_id is the identifier of the device that will make use of this GPIO. It - can be NULL, in which case it will be matched for calls to gpiod_get() - with a NULL device. - con_id is the name of the GPIO function from the device point of view. It can be NULL, in which case it will match any function. - idx is the index of the GPIO within the function. @@ -134,7 +131,9 @@ In the future, these flags might be extended to support more properties. Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0. A lookup table can then be defined as follows, with an empty entry defining its -end: +end. The 'dev_id' field of the table is the identifier of the device that will +make use of these GPIOs. It can be NULL, in which case it will be matched for +calls to gpiod_get() with a NULL device. struct gpiod_lookup_table gpios_table = { .dev_id = "foo.0", diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 5584ba457161..96ad29de3a3e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -266,7 +266,7 @@ config GPIO_LYNXPOINT config GPIO_MB86S7X bool "GPIO support for Fujitsu MB86S7x Platforms" - depends on ARCH_MB86S7X + depends on ARCH_MB86S7X || COMPILE_TEST help Say yes here to support the GPIO controller in Fujitsu MB86S70 SoCs. @@ -280,7 +280,7 @@ config GPIO_MM_LANTIQ config GPIO_MOXART bool "MOXART GPIO support" - depends on ARCH_MOXART + depends on ARCH_MOXART || COMPILE_TEST select GPIO_GENERIC help Select this option to enable GPIO driver for diff --git a/drivers/gpio/gpio-moxart.c b/drivers/gpio/gpio-moxart.c index 869002b7a571..f02d0b490978 100644 --- a/drivers/gpio/gpio-moxart.c +++ b/drivers/gpio/gpio-moxart.c @@ -57,10 +57,7 @@ static int moxart_gpio_probe(struct platform_device *pdev) gc->label = "moxart-gpio"; gc->request = gpiochip_generic_request; gc->free = gpiochip_generic_free; - gc->bgpio_data = gc->read_reg(gc->reg_set); gc->base = 0; - gc->ngpio = 32; - gc->parent = dev; gc->owner = THIS_MODULE; ret = devm_gpiochip_add_data(dev, gc, NULL); diff --git a/drivers/gpio/gpio-pisosr.c b/drivers/gpio/gpio-pisosr.c index 8b8bf8f9de6a..cb14b8d1d512 100644 --- a/drivers/gpio/gpio-pisosr.c +++ b/drivers/gpio/gpio-pisosr.c @@ -46,9 +46,9 @@ static int pisosr_gpio_refresh(struct pisosr_gpio *gpio) mutex_lock(&gpio->lock); if (gpio->load_gpio) { - gpiod_set_value(gpio->load_gpio, 1); + gpiod_set_value_cansleep(gpio->load_gpio, 1); udelay(1); /* registers load time (~10ns) */ - gpiod_set_value(gpio->load_gpio, 0); + gpiod_set_value_cansleep(gpio->load_gpio, 0); udelay(1); /* registers recovery time (~5ns) */ } diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index c56309491e8b..932e510aec50 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -721,6 +721,7 @@ EXPORT_SYMBOL_GPL(gpiod_unexport); int gpiochip_sysfs_register(struct gpio_device *gdev) { struct device *dev; + struct device *parent; struct gpio_chip *chip = gdev->chip; /* @@ -732,8 +733,17 @@ int gpiochip_sysfs_register(struct gpio_device *gdev) if (!gpio_class.p) return 0; + /* + * For sysfs backward compatibility we need to preserve this + * preferred parenting to the gpio_chip parent field, if set. + */ + if (chip->parent) + parent = chip->parent; + else + parent = &gdev->dev; + /* use chip->base for the ID; it's already known to be unique */ - dev = device_create_with_groups(&gpio_class, &gdev->dev, + dev = device_create_with_groups(&gpio_class, parent, MKDEV(0, 0), chip, gpiochip_groups, "gpiochip%d", chip->base); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e31d0a1e6f7c..1741ef4d2aaa 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -206,58 +206,43 @@ EXPORT_SYMBOL_GPL(gpiod_get_direction); */ static int gpiodev_add_to_list(struct gpio_device *gdev) { - struct gpio_device *iterator; - struct gpio_device *previous = NULL; - - if (!gdev->chip) - return -EINVAL; + struct gpio_device *prev, *next; if (list_empty(&gpio_devices)) { + /* initial entry in list */ list_add_tail(&gdev->list, &gpio_devices); return 0; } - list_for_each_entry(iterator, &gpio_devices, list) { - if (iterator->base >= gdev->base + gdev->ngpio) { - /* - * Iterator is the first GPIO chip so there is no - * previous one - */ - if (!previous) { - goto found; - } else { - /* - * We found a valid range(means - * [base, base + ngpio - 1]) between previous - * and iterator chip. - */ - if (previous->base + previous->ngpio - <= gdev->base) - goto found; - } - } - previous = iterator; + next = list_entry(gpio_devices.next, struct gpio_device, list); + if (gdev->base + gdev->ngpio <= next->base) { + /* add before first entry */ + list_add(&gdev->list, &gpio_devices); + return 0; } - /* - * We are beyond the last chip in the list and iterator now - * points to the head. - * Let iterator point to the last chip in the list. - */ - - iterator = list_last_entry(&gpio_devices, struct gpio_device, list); - if (iterator->base + iterator->ngpio <= gdev->base) { - list_add(&gdev->list, &iterator->list); + prev = list_entry(gpio_devices.prev, struct gpio_device, list); + if (prev->base + prev->ngpio <= gdev->base) { + /* add behind last entry */ + list_add_tail(&gdev->list, &gpio_devices); return 0; } - dev_err(&gdev->dev, - "GPIO integer space overlap, cannot add chip\n"); - return -EBUSY; + list_for_each_entry_safe(prev, next, &gpio_devices, list) { + /* at the end of the list */ + if (&next->list == &gpio_devices) + break; -found: - list_add_tail(&gdev->list, &iterator->list); - return 0; + /* add between prev and next */ + if (prev->base + prev->ngpio <= gdev->base + && gdev->base + gdev->ngpio <= next->base) { + list_add(&gdev->list, &prev->list); + return 0; + } + } + + dev_err(&gdev->dev, "GPIO integer space overlap, cannot add chip\n"); + return -EBUSY; } /** @@ -368,11 +353,11 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) lineinfo.name[0] = '\0'; } if (desc->label) { - strncpy(lineinfo.label, desc->label, - sizeof(lineinfo.label)); - lineinfo.label[sizeof(lineinfo.label)-1] = '\0'; + strncpy(lineinfo.consumer, desc->label, + sizeof(lineinfo.consumer)); + lineinfo.consumer[sizeof(lineinfo.consumer)-1] = '\0'; } else { - lineinfo.label[0] = '\0'; + lineinfo.consumer[0] = '\0'; } /* diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h index 416ce47f2291..dfe8ade2742d 100644 --- a/include/uapi/linux/gpio.h +++ b/include/uapi/linux/gpio.h @@ -15,8 +15,9 @@ /** * struct gpiochip_info - Information about a certain GPIO chip - * @name: the name of this GPIO chip - * @label: a functional name for this GPIO chip + * @name: the Linux kernel name of this GPIO chip + * @label: a functional name for this GPIO chip, such as a product + * number, may be NULL * @lines: number of GPIO lines on this chip */ struct gpiochip_info { @@ -34,20 +35,21 @@ struct gpiochip_info { /** * struct gpioline_info - Information about a certain GPIO line - * @line_offset: the local offset on this GPIO device, fill in when - * requesting information from the kernel + * @line_offset: the local offset on this GPIO device, fill this in when + * requesting the line information from the kernel * @flags: various flags for this line - * @name: the name of this GPIO line - * @label: a functional name for this GPIO line - * @kernel: this GPIO is in use by the kernel - * @out: this GPIO is an output line (false means it is an input) - * @active_low: this GPIO is active low + * @name: the name of this GPIO line, such as the output pin of the line on the + * chip, a rail or a pin header name on a board, as specified by the gpio + * chip, may be NULL + * @consumer: a functional name for the consumer of this GPIO line as set by + * whatever is using it, will be NULL if there is no current user but may + * also be NULL if the consumer doesn't set this up */ struct gpioline_info { __u32 line_offset; __u32 flags; char name[32]; - char label[32]; + char consumer[32]; }; #define GPIO_GET_CHIPINFO_IOCTL _IOR('o', 0x01, struct gpiochip_info) diff --git a/tools/gpio/lsgpio.c b/tools/gpio/lsgpio.c index 6af118cc7efb..1124da375942 100644 --- a/tools/gpio/lsgpio.c +++ b/tools/gpio/lsgpio.c @@ -116,10 +116,10 @@ int list_device(const char *device_name) fprintf(stdout, " \"%s\"", linfo.name); else fprintf(stdout, " unnamed"); - if (linfo.label[0]) - fprintf(stdout, " \"%s\"", linfo.label); + if (linfo.consumer[0]) + fprintf(stdout, " \"%s\"", linfo.consumer); else - fprintf(stdout, " unlabeled"); + fprintf(stdout, " unused"); if (linfo.flags) { fprintf(stdout, " ["); print_flags(linfo.flags); |