diff options
-rw-r--r-- | Documentation/devicetree/bindings/input/gpio-keys.txt | 10 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 49 |
2 files changed, 33 insertions, 26 deletions
diff --git a/Documentation/devicetree/bindings/input/gpio-keys.txt b/Documentation/devicetree/bindings/input/gpio-keys.txt index a4a38fcf2ed6..44b705767aca 100644 --- a/Documentation/devicetree/bindings/input/gpio-keys.txt +++ b/Documentation/devicetree/bindings/input/gpio-keys.txt | |||
@@ -10,12 +10,13 @@ Optional properties: | |||
10 | Each button (key) is represented as a sub-node of "gpio-keys": | 10 | Each button (key) is represented as a sub-node of "gpio-keys": |
11 | Subnode properties: | 11 | Subnode properties: |
12 | 12 | ||
13 | - gpios: OF device-tree gpio specification. | ||
14 | - interrupts: the interrupt line for that input. | ||
13 | - label: Descriptive name of the key. | 15 | - label: Descriptive name of the key. |
14 | - linux,code: Keycode to emit. | 16 | - linux,code: Keycode to emit. |
15 | 17 | ||
16 | Required mutual exclusive subnode-properties: | 18 | Note that either "interrupts" or "gpios" properties can be omitted, but not |
17 | - gpios: OF device-tree gpio specification. | 19 | both at the same time. Specifying both properties is allowed. |
18 | - interrupts: the interrupt line for that input | ||
19 | 20 | ||
20 | Optional subnode-properties: | 21 | Optional subnode-properties: |
21 | - linux,input-type: Specify event type this button/key generates. | 22 | - linux,input-type: Specify event type this button/key generates. |
@@ -23,6 +24,9 @@ Optional subnode-properties: | |||
23 | - debounce-interval: Debouncing interval time in milliseconds. | 24 | - debounce-interval: Debouncing interval time in milliseconds. |
24 | If not specified defaults to 5. | 25 | If not specified defaults to 5. |
25 | - gpio-key,wakeup: Boolean, button can wake-up the system. | 26 | - gpio-key,wakeup: Boolean, button can wake-up the system. |
27 | - linux,can-disable: Boolean, indicates that button is connected | ||
28 | to dedicated (not shared) interrupt which can be disabled to | ||
29 | suppress events from the button. | ||
26 | 30 | ||
27 | Example nodes: | 31 | Example nodes: |
28 | 32 | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index f44f05b70ee0..a5ece3ff19cb 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -470,15 +470,19 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
470 | button->debounce_interval; | 470 | button->debounce_interval; |
471 | } | 471 | } |
472 | 472 | ||
473 | irq = gpio_to_irq(button->gpio); | 473 | if (button->irq) { |
474 | if (irq < 0) { | 474 | bdata->irq = button->irq; |
475 | error = irq; | 475 | } else { |
476 | dev_err(dev, | 476 | irq = gpio_to_irq(button->gpio); |
477 | "Unable to get irq number for GPIO %d, error %d\n", | 477 | if (irq < 0) { |
478 | button->gpio, error); | 478 | error = irq; |
479 | return error; | 479 | dev_err(dev, |
480 | "Unable to get irq number for GPIO %d, error %d\n", | ||
481 | button->gpio, error); | ||
482 | return error; | ||
483 | } | ||
484 | bdata->irq = irq; | ||
480 | } | 485 | } |
481 | bdata->irq = irq; | ||
482 | 486 | ||
483 | INIT_WORK(&bdata->work, gpio_keys_gpio_work_func); | 487 | INIT_WORK(&bdata->work, gpio_keys_gpio_work_func); |
484 | setup_timer(&bdata->timer, | 488 | setup_timer(&bdata->timer, |
@@ -618,33 +622,30 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
618 | 622 | ||
619 | i = 0; | 623 | i = 0; |
620 | for_each_child_of_node(node, pp) { | 624 | for_each_child_of_node(node, pp) { |
621 | int gpio = -1; | ||
622 | enum of_gpio_flags flags; | 625 | enum of_gpio_flags flags; |
623 | 626 | ||
624 | button = &pdata->buttons[i++]; | 627 | button = &pdata->buttons[i++]; |
625 | 628 | ||
626 | if (!of_find_property(pp, "gpios", NULL)) { | 629 | button->gpio = of_get_gpio_flags(pp, 0, &flags); |
627 | button->irq = irq_of_parse_and_map(pp, 0); | 630 | if (button->gpio < 0) { |
628 | if (button->irq == 0) { | 631 | error = button->gpio; |
629 | i--; | 632 | if (error != -ENOENT) { |
630 | pdata->nbuttons--; | ||
631 | dev_warn(dev, "Found button without gpios or irqs\n"); | ||
632 | continue; | ||
633 | } | ||
634 | } else { | ||
635 | gpio = of_get_gpio_flags(pp, 0, &flags); | ||
636 | if (gpio < 0) { | ||
637 | error = gpio; | ||
638 | if (error != -EPROBE_DEFER) | 633 | if (error != -EPROBE_DEFER) |
639 | dev_err(dev, | 634 | dev_err(dev, |
640 | "Failed to get gpio flags, error: %d\n", | 635 | "Failed to get gpio flags, error: %d\n", |
641 | error); | 636 | error); |
642 | return ERR_PTR(error); | 637 | return ERR_PTR(error); |
643 | } | 638 | } |
639 | } else { | ||
640 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
644 | } | 641 | } |
645 | 642 | ||
646 | button->gpio = gpio; | 643 | button->irq = irq_of_parse_and_map(pp, 0); |
647 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | 644 | |
645 | if (!gpio_is_valid(button->gpio) && !button->irq) { | ||
646 | dev_err(dev, "Found button without gpios or irqs\n"); | ||
647 | return ERR_PTR(-EINVAL); | ||
648 | } | ||
648 | 649 | ||
649 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | 650 | if (of_property_read_u32(pp, "linux,code", &button->code)) { |
650 | dev_err(dev, "Button without keycode: 0x%x\n", | 651 | dev_err(dev, "Button without keycode: 0x%x\n", |
@@ -659,6 +660,8 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
659 | 660 | ||
660 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | 661 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); |
661 | 662 | ||
663 | button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL); | ||
664 | |||
662 | if (of_property_read_u32(pp, "debounce-interval", | 665 | if (of_property_read_u32(pp, "debounce-interval", |
663 | &button->debounce_interval)) | 666 | &button->debounce_interval)) |
664 | button->debounce_interval = 5; | 667 | button->debounce_interval = 5; |