diff options
| -rw-r--r-- | Documentation/gpio/board.txt | 11 | ||||
| -rw-r--r-- | drivers/gpio/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/gpio/gpio-ath79.c | 1 | ||||
| -rw-r--r-- | drivers/gpio/gpio-mpc8xxx.c | 2 | ||||
| -rw-r--r-- | drivers/gpio/gpio-mxs.c | 8 | ||||
| -rw-r--r-- | drivers/gpio/gpio-stmpe.c | 2 | ||||
| -rw-r--r-- | drivers/gpio/gpio-ts4800.c | 1 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 7 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib.c | 42 |
9 files changed, 64 insertions, 12 deletions
diff --git a/Documentation/gpio/board.txt b/Documentation/gpio/board.txt index 40884c4fe40c..a0f61898d493 100644 --- a/Documentation/gpio/board.txt +++ b/Documentation/gpio/board.txt | |||
| @@ -6,7 +6,7 @@ Note that it only applies to the new descriptor-based interface. For a | |||
| 6 | description of the deprecated integer-based GPIO interface please refer to | 6 | description of the deprecated integer-based GPIO interface please refer to |
| 7 | gpio-legacy.txt (actually, there is no real mapping possible with the old | 7 | gpio-legacy.txt (actually, there is no real mapping possible with the old |
| 8 | interface; you just fetch an integer from somewhere and request the | 8 | interface; you just fetch an integer from somewhere and request the |
| 9 | corresponding GPIO. | 9 | corresponding GPIO). |
| 10 | 10 | ||
| 11 | All platforms can enable the GPIO library, but if the platform strictly | 11 | All platforms can enable the GPIO library, but if the platform strictly |
| 12 | requires GPIO functionality to be present, it needs to select GPIOLIB from its | 12 | requires GPIO functionality to be present, it needs to select GPIOLIB from its |
| @@ -162,6 +162,9 @@ The driver controlling "foo.0" will then be able to obtain its GPIOs as follows: | |||
| 162 | 162 | ||
| 163 | Since the "led" GPIOs are mapped as active-high, this example will switch their | 163 | Since the "led" GPIOs are mapped as active-high, this example will switch their |
| 164 | signals to 1, i.e. enabling the LEDs. And for the "power" GPIO, which is mapped | 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 | 165 | as active-low, its actual signal will be 0 after this code. Contrary to the |
| 166 | integer GPIO interface, the active-low property is handled during mapping and is | 166 | legacy integer GPIO interface, the active-low property is handled during |
| 167 | thus transparent to GPIO consumers. | 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. | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 26ee00f6bd58..d011cb89d25e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -284,7 +284,7 @@ config GPIO_MM_LANTIQ | |||
| 284 | 284 | ||
| 285 | config GPIO_MOCKUP | 285 | config GPIO_MOCKUP |
| 286 | tristate "GPIO Testing Driver" | 286 | tristate "GPIO Testing Driver" |
| 287 | depends on GPIOLIB | 287 | depends on GPIOLIB && SYSFS |
| 288 | select GPIO_SYSFS | 288 | select GPIO_SYSFS |
| 289 | help | 289 | help |
| 290 | This enables GPIO Testing driver, which provides a way to test GPIO | 290 | This enables GPIO Testing driver, which provides a way to test GPIO |
diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c index 9457e2022bf6..dc37dbe4b46d 100644 --- a/drivers/gpio/gpio-ath79.c +++ b/drivers/gpio/gpio-ath79.c | |||
| @@ -219,6 +219,7 @@ static const struct of_device_id ath79_gpio_of_match[] = { | |||
| 219 | { .compatible = "qca,ar9340-gpio" }, | 219 | { .compatible = "qca,ar9340-gpio" }, |
| 220 | {}, | 220 | {}, |
| 221 | }; | 221 | }; |
| 222 | MODULE_DEVICE_TABLE(of, ath79_gpio_of_match); | ||
| 222 | 223 | ||
| 223 | static int ath79_gpio_probe(struct platform_device *pdev) | 224 | static int ath79_gpio_probe(struct platform_device *pdev) |
| 224 | { | 225 | { |
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 425501c39527..793518a30afe 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c | |||
| @@ -239,7 +239,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int irq, | |||
| 239 | irq_hw_number_t hwirq) | 239 | irq_hw_number_t hwirq) |
| 240 | { | 240 | { |
| 241 | irq_set_chip_data(irq, h->host_data); | 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 | return 0; | 244 | return 0; |
| 245 | } | 245 | } |
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index b9daa0bf32a4..ee1724806f46 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c | |||
| @@ -308,8 +308,10 @@ static int mxs_gpio_probe(struct platform_device *pdev) | |||
| 308 | writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); | 308 | writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); |
| 309 | 309 | ||
| 310 | irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); | 310 | irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); |
| 311 | if (irq_base < 0) | 311 | if (irq_base < 0) { |
| 312 | return irq_base; | 312 | err = irq_base; |
| 313 | goto out_iounmap; | ||
| 314 | } | ||
| 313 | 315 | ||
| 314 | port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, | 316 | port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, |
| 315 | &irq_domain_simple_ops, NULL); | 317 | &irq_domain_simple_ops, NULL); |
| @@ -349,6 +351,8 @@ out_irqdomain_remove: | |||
| 349 | irq_domain_remove(port->domain); | 351 | irq_domain_remove(port->domain); |
| 350 | out_irqdesc_free: | 352 | out_irqdesc_free: |
| 351 | irq_free_descs(irq_base, 32); | 353 | irq_free_descs(irq_base, 32); |
| 354 | out_iounmap: | ||
| 355 | iounmap(port->base); | ||
| 352 | return err; | 356 | return err; |
| 353 | } | 357 | } |
| 354 | 358 | ||
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index e7d422a6b90b..5b0042776ec7 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c | |||
| @@ -409,7 +409,7 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
| 409 | * 801/1801/1600, bits are cleared when read. | 409 | * 801/1801/1600, bits are cleared when read. |
| 410 | * Edge detect register is not present on 801/1600/1801 | 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 | stmpe->partnum != STMPE1801) { | 413 | stmpe->partnum != STMPE1801) { |
| 414 | stmpe_reg_write(stmpe, statmsbreg + i, status[i]); | 414 | stmpe_reg_write(stmpe, statmsbreg + i, status[i]); |
| 415 | stmpe_reg_write(stmpe, | 415 | stmpe_reg_write(stmpe, |
diff --git a/drivers/gpio/gpio-ts4800.c b/drivers/gpio/gpio-ts4800.c index 99256115bea5..c2a80b4cbf32 100644 --- a/drivers/gpio/gpio-ts4800.c +++ b/drivers/gpio/gpio-ts4800.c | |||
| @@ -66,6 +66,7 @@ static const struct of_device_id ts4800_gpio_of_match[] = { | |||
| 66 | { .compatible = "technologic,ts4800-gpio", }, | 66 | { .compatible = "technologic,ts4800-gpio", }, |
| 67 | {}, | 67 | {}, |
| 68 | }; | 68 | }; |
| 69 | MODULE_DEVICE_TABLE(of, ts4800_gpio_of_match); | ||
| 69 | 70 | ||
| 70 | static struct platform_driver ts4800_gpio_driver = { | 71 | static struct platform_driver ts4800_gpio_driver = { |
| 71 | .driver = { | 72 | .driver = { |
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 58ece201b8e6..72a4b326fd0d 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
| @@ -653,14 +653,17 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) | |||
| 653 | { | 653 | { |
| 654 | int idx, i; | 654 | int idx, i; |
| 655 | unsigned int irq_flags; | 655 | unsigned int irq_flags; |
| 656 | int ret = -ENOENT; | ||
| 656 | 657 | ||
| 657 | for (i = 0, idx = 0; idx <= index; i++) { | 658 | for (i = 0, idx = 0; idx <= index; i++) { |
| 658 | struct acpi_gpio_info info; | 659 | struct acpi_gpio_info info; |
| 659 | struct gpio_desc *desc; | 660 | struct gpio_desc *desc; |
| 660 | 661 | ||
| 661 | desc = acpi_get_gpiod_by_index(adev, NULL, i, &info); | 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 | break; | 665 | break; |
| 666 | } | ||
| 664 | if (info.gpioint && idx++ == index) { | 667 | if (info.gpioint && idx++ == index) { |
| 665 | int irq = gpiod_to_irq(desc); | 668 | int irq = gpiod_to_irq(desc); |
| 666 | 669 | ||
| @@ -679,7 +682,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) | |||
| 679 | } | 682 | } |
| 680 | 683 | ||
| 681 | } | 684 | } |
| 682 | return -ENOENT; | 685 | return ret; |
| 683 | } | 686 | } |
| 684 | EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get); | 687 | EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get); |
| 685 | 688 | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f0fc3a0d37c8..20e09b7c2de3 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -333,6 +333,13 @@ struct linehandle_state { | |||
| 333 | u32 numdescs; | 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 | static long linehandle_ioctl(struct file *filep, unsigned int cmd, | 343 | static long linehandle_ioctl(struct file *filep, unsigned int cmd, |
| 337 | unsigned long arg) | 344 | unsigned long arg) |
| 338 | { | 345 | { |
| @@ -344,6 +351,8 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd, | |||
| 344 | if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { | 351 | if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { |
| 345 | int val; | 352 | int val; |
| 346 | 353 | ||
| 354 | memset(&ghd, 0, sizeof(ghd)); | ||
| 355 | |||
| 347 | /* TODO: check if descriptors are really input */ | 356 | /* TODO: check if descriptors are really input */ |
| 348 | for (i = 0; i < lh->numdescs; i++) { | 357 | for (i = 0; i < lh->numdescs; i++) { |
| 349 | val = gpiod_get_value_cansleep(lh->descs[i]); | 358 | val = gpiod_get_value_cansleep(lh->descs[i]); |
| @@ -444,6 +453,17 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) | |||
| 444 | u32 lflags = handlereq.flags; | 453 | u32 lflags = handlereq.flags; |
| 445 | struct gpio_desc *desc; | 454 | struct gpio_desc *desc; |
| 446 | 455 | ||
| 456 | if (offset >= gdev->ngpio) { | ||
| 457 | ret = -EINVAL; | ||
| 458 | goto out_free_descs; | ||
| 459 | } | ||
| 460 | |||
| 461 | /* Return an error if a unknown flag is set */ | ||
| 462 | if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) { | ||
| 463 | ret = -EINVAL; | ||
| 464 | goto out_free_descs; | ||
| 465 | } | ||
| 466 | |||
| 447 | desc = &gdev->descs[offset]; | 467 | desc = &gdev->descs[offset]; |
| 448 | ret = gpiod_request(desc, lh->label); | 468 | ret = gpiod_request(desc, lh->label); |
| 449 | if (ret) | 469 | if (ret) |
| @@ -536,6 +556,10 @@ struct lineevent_state { | |||
| 536 | struct mutex read_lock; | 556 | struct mutex read_lock; |
| 537 | }; | 557 | }; |
| 538 | 558 | ||
| 559 | #define GPIOEVENT_REQUEST_VALID_FLAGS \ | ||
| 560 | (GPIOEVENT_REQUEST_RISING_EDGE | \ | ||
| 561 | GPIOEVENT_REQUEST_FALLING_EDGE) | ||
| 562 | |||
| 539 | static unsigned int lineevent_poll(struct file *filep, | 563 | static unsigned int lineevent_poll(struct file *filep, |
| 540 | struct poll_table_struct *wait) | 564 | struct poll_table_struct *wait) |
| 541 | { | 565 | { |
| @@ -623,6 +647,8 @@ static long lineevent_ioctl(struct file *filep, unsigned int cmd, | |||
| 623 | if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { | 647 | if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { |
| 624 | int val; | 648 | int val; |
| 625 | 649 | ||
| 650 | memset(&ghd, 0, sizeof(ghd)); | ||
| 651 | |||
| 626 | val = gpiod_get_value_cansleep(le->desc); | 652 | val = gpiod_get_value_cansleep(le->desc); |
| 627 | if (val < 0) | 653 | if (val < 0) |
| 628 | return val; | 654 | return val; |
| @@ -726,6 +752,18 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) | |||
| 726 | lflags = eventreq.handleflags; | 752 | lflags = eventreq.handleflags; |
| 727 | eflags = eventreq.eventflags; | 753 | eflags = eventreq.eventflags; |
| 728 | 754 | ||
| 755 | if (offset >= gdev->ngpio) { | ||
| 756 | ret = -EINVAL; | ||
| 757 | goto out_free_label; | ||
| 758 | } | ||
| 759 | |||
| 760 | /* Return an error if a unknown flag is set */ | ||
| 761 | if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) || | ||
| 762 | (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) { | ||
| 763 | ret = -EINVAL; | ||
| 764 | goto out_free_label; | ||
| 765 | } | ||
| 766 | |||
| 729 | /* This is just wrong: we don't look for events on output lines */ | 767 | /* This is just wrong: we don't look for events on output lines */ |
| 730 | if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { | 768 | if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { |
| 731 | ret = -EINVAL; | 769 | ret = -EINVAL; |
| @@ -823,6 +861,8 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 823 | if (cmd == GPIO_GET_CHIPINFO_IOCTL) { | 861 | if (cmd == GPIO_GET_CHIPINFO_IOCTL) { |
| 824 | struct gpiochip_info chipinfo; | 862 | struct gpiochip_info chipinfo; |
| 825 | 863 | ||
| 864 | memset(&chipinfo, 0, sizeof(chipinfo)); | ||
| 865 | |||
| 826 | strncpy(chipinfo.name, dev_name(&gdev->dev), | 866 | strncpy(chipinfo.name, dev_name(&gdev->dev), |
| 827 | sizeof(chipinfo.name)); | 867 | sizeof(chipinfo.name)); |
| 828 | chipinfo.name[sizeof(chipinfo.name)-1] = '\0'; | 868 | chipinfo.name[sizeof(chipinfo.name)-1] = '\0'; |
| @@ -839,7 +879,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 839 | 879 | ||
| 840 | if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) | 880 | if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) |
| 841 | return -EFAULT; | 881 | return -EFAULT; |
| 842 | if (lineinfo.line_offset > gdev->ngpio) | 882 | if (lineinfo.line_offset >= gdev->ngpio) |
| 843 | return -EINVAL; | 883 | return -EINVAL; |
| 844 | 884 | ||
| 845 | desc = &gdev->descs[lineinfo.line_offset]; | 885 | desc = &gdev->descs[lineinfo.line_offset]; |
