Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'gpio-v4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO fixes from Linus Walleij:
"Here is a set of GPIO fixes for the v4.9 kernel series:

- Fix up off-by one and line offset validation, info leak to
userspace, and reject invalid flags. Those are especially valuable
hardening patches from Lars-Peter Clausen, all tagged for stable.

- Fix module autoload for TS4800 and ATH79.

- Correct the IRQ handler for MPC8xxx to use handle_level_irq() as it
(a) reacts to edges not levels and (b) even implements .irq_ack().
We were missing IRQs here.

- Fix the error path for acpi_dev_gpio_irq_get()

- Fix a memory leak in the MXS driver.

- Fix an annoying typo in the STMPE driver.

- Put a dependency on sysfs to the mockup driver"

* tag 'gpio-v4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
gpio: mpc8xxx: Correct irq handler function
gpio: ath79: Fix module autoload
gpio: ts4800: Fix module autoload
gpio: GPIO_GET_LINEEVENT_IOCTL: Reject invalid line and event flags
gpio: GPIO_GET_LINEHANDLE_IOCTL: Reject invalid line flags
gpio: GPIOHANDLE_GET_LINE_VALUES_IOCTL: Fix information leak
gpio: GPIO_GET_LINEEVENT_IOCTL: Validate line offset
gpio: GPIOHANDLE_GET_LINE_VALUES_IOCTL: Fix information leak
gpio: GPIO_GET_LINEHANDLE_IOCTL: Validate line offset
gpio: GPIO_GET_CHIPINFO_IOCTL: Fix information leak
gpio: GPIO_GET_CHIPINFO_IOCTL: Fix line offset validation
gpio / ACPI: fix returned error from acpi_dev_gpio_irq_get()
gpio: mockup: add sysfs dependency
gpio: stmpe: || vs && typo
gpio: mxs: Unmap region obtained by of_iomap
gpio/board.txt: point to gpiod_set_value

+64 -12
+7 -4
Documentation/gpio/board.txt
··· 6 6 description of the deprecated integer-based GPIO interface please refer to 7 7 gpio-legacy.txt (actually, there is no real mapping possible with the old 8 8 interface; you just fetch an integer from somewhere and request the 9 - corresponding GPIO. 9 + corresponding GPIO). 10 10 11 11 All platforms can enable the GPIO library, but if the platform strictly 12 12 requires GPIO functionality to be present, it needs to select GPIOLIB from its ··· 162 162 163 163 Since the "led" GPIOs are mapped as active-high, this example will switch their 164 164 signals to 1, i.e. enabling the LEDs. And for the "power" GPIO, which is mapped 165 - as active-low, its actual signal will be 0 after this code. Contrary to the legacy 166 - integer GPIO interface, the active-low property is handled during mapping and is 167 - thus transparent to GPIO consumers. 165 + as active-low, its actual signal will be 0 after this code. Contrary to the 166 + legacy integer GPIO interface, the active-low property is handled during 167 + mapping and is thus transparent to GPIO consumers. 168 + 169 + A set of functions such as gpiod_set_value() is available to work with 170 + the new descriptor-oriented interface.
+1 -1
drivers/gpio/Kconfig
··· 284 284 285 285 config GPIO_MOCKUP 286 286 tristate "GPIO Testing Driver" 287 - depends on GPIOLIB 287 + depends on GPIOLIB && SYSFS 288 288 select GPIO_SYSFS 289 289 help 290 290 This enables GPIO Testing driver, which provides a way to test GPIO
+1
drivers/gpio/gpio-ath79.c
··· 219 219 { .compatible = "qca,ar9340-gpio" }, 220 220 {}, 221 221 }; 222 + MODULE_DEVICE_TABLE(of, ath79_gpio_of_match); 222 223 223 224 static int ath79_gpio_probe(struct platform_device *pdev) 224 225 {
+1 -1
drivers/gpio/gpio-mpc8xxx.c
··· 239 239 irq_hw_number_t hwirq) 240 240 { 241 241 irq_set_chip_data(irq, h->host_data); 242 - irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_level_irq); 242 + irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_edge_irq); 243 243 244 244 return 0; 245 245 }
+6 -2
drivers/gpio/gpio-mxs.c
··· 308 308 writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); 309 309 310 310 irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); 311 - if (irq_base < 0) 312 - return irq_base; 311 + if (irq_base < 0) { 312 + err = irq_base; 313 + goto out_iounmap; 314 + } 313 315 314 316 port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, 315 317 &irq_domain_simple_ops, NULL); ··· 351 349 irq_domain_remove(port->domain); 352 350 out_irqdesc_free: 353 351 irq_free_descs(irq_base, 32); 352 + out_iounmap: 353 + iounmap(port->base); 354 354 return err; 355 355 } 356 356
+1 -1
drivers/gpio/gpio-stmpe.c
··· 409 409 * 801/1801/1600, bits are cleared when read. 410 410 * Edge detect register is not present on 801/1600/1801 411 411 */ 412 - if (stmpe->partnum != STMPE801 || stmpe->partnum != STMPE1600 || 412 + if (stmpe->partnum != STMPE801 && stmpe->partnum != STMPE1600 && 413 413 stmpe->partnum != STMPE1801) { 414 414 stmpe_reg_write(stmpe, statmsbreg + i, status[i]); 415 415 stmpe_reg_write(stmpe,
+1
drivers/gpio/gpio-ts4800.c
··· 66 66 { .compatible = "technologic,ts4800-gpio", }, 67 67 {}, 68 68 }; 69 + MODULE_DEVICE_TABLE(of, ts4800_gpio_of_match); 69 70 70 71 static struct platform_driver ts4800_gpio_driver = { 71 72 .driver = {
+5 -2
drivers/gpio/gpiolib-acpi.c
··· 653 653 { 654 654 int idx, i; 655 655 unsigned int irq_flags; 656 + int ret = -ENOENT; 656 657 657 658 for (i = 0, idx = 0; idx <= index; i++) { 658 659 struct acpi_gpio_info info; 659 660 struct gpio_desc *desc; 660 661 661 662 desc = acpi_get_gpiod_by_index(adev, NULL, i, &info); 662 - if (IS_ERR(desc)) 663 + if (IS_ERR(desc)) { 664 + ret = PTR_ERR(desc); 663 665 break; 666 + } 664 667 if (info.gpioint && idx++ == index) { 665 668 int irq = gpiod_to_irq(desc); 666 669 ··· 682 679 } 683 680 684 681 } 685 - return -ENOENT; 682 + return ret; 686 683 } 687 684 EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get); 688 685
+41 -1
drivers/gpio/gpiolib.c
··· 333 333 u32 numdescs; 334 334 }; 335 335 336 + #define GPIOHANDLE_REQUEST_VALID_FLAGS \ 337 + (GPIOHANDLE_REQUEST_INPUT | \ 338 + GPIOHANDLE_REQUEST_OUTPUT | \ 339 + GPIOHANDLE_REQUEST_ACTIVE_LOW | \ 340 + GPIOHANDLE_REQUEST_OPEN_DRAIN | \ 341 + GPIOHANDLE_REQUEST_OPEN_SOURCE) 342 + 336 343 static long linehandle_ioctl(struct file *filep, unsigned int cmd, 337 344 unsigned long arg) 338 345 { ··· 350 343 351 344 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { 352 345 int val; 346 + 347 + memset(&ghd, 0, sizeof(ghd)); 353 348 354 349 /* TODO: check if descriptors are really input */ 355 350 for (i = 0; i < lh->numdescs; i++) { ··· 453 444 u32 lflags = handlereq.flags; 454 445 struct gpio_desc *desc; 455 446 447 + if (offset >= gdev->ngpio) { 448 + ret = -EINVAL; 449 + goto out_free_descs; 450 + } 451 + 452 + /* Return an error if a unknown flag is set */ 453 + if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) { 454 + ret = -EINVAL; 455 + goto out_free_descs; 456 + } 457 + 456 458 desc = &gdev->descs[offset]; 457 459 ret = gpiod_request(desc, lh->label); 458 460 if (ret) ··· 556 536 struct mutex read_lock; 557 537 }; 558 538 539 + #define GPIOEVENT_REQUEST_VALID_FLAGS \ 540 + (GPIOEVENT_REQUEST_RISING_EDGE | \ 541 + GPIOEVENT_REQUEST_FALLING_EDGE) 542 + 559 543 static unsigned int lineevent_poll(struct file *filep, 560 544 struct poll_table_struct *wait) 561 545 { ··· 646 622 */ 647 623 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { 648 624 int val; 625 + 626 + memset(&ghd, 0, sizeof(ghd)); 649 627 650 628 val = gpiod_get_value_cansleep(le->desc); 651 629 if (val < 0) ··· 752 726 lflags = eventreq.handleflags; 753 727 eflags = eventreq.eventflags; 754 728 729 + if (offset >= gdev->ngpio) { 730 + ret = -EINVAL; 731 + goto out_free_label; 732 + } 733 + 734 + /* Return an error if a unknown flag is set */ 735 + if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) || 736 + (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) { 737 + ret = -EINVAL; 738 + goto out_free_label; 739 + } 740 + 755 741 /* This is just wrong: we don't look for events on output lines */ 756 742 if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { 757 743 ret = -EINVAL; ··· 861 823 if (cmd == GPIO_GET_CHIPINFO_IOCTL) { 862 824 struct gpiochip_info chipinfo; 863 825 826 + memset(&chipinfo, 0, sizeof(chipinfo)); 827 + 864 828 strncpy(chipinfo.name, dev_name(&gdev->dev), 865 829 sizeof(chipinfo.name)); 866 830 chipinfo.name[sizeof(chipinfo.name)-1] = '\0'; ··· 879 839 880 840 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) 881 841 return -EFAULT; 882 - if (lineinfo.line_offset > gdev->ngpio) 842 + if (lineinfo.line_offset >= gdev->ngpio) 883 843 return -EINVAL; 884 844 885 845 desc = &gdev->descs[lineinfo.line_offset];