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

Input: gpio_keys - add support for interrupt only keys

Some of buttons, like power-on key or onkey, may only generate interrupts
when pressed and not actually be mapped as gpio in the system. Allow
setting gpio to invalid value and specify IRQ instead to support such
keys. The debounce timer is used not to debounce but to ignore new IRQs
coming while button is kept pressed.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Laxman Dewangan and committed by
Dmitry Torokhov
d8ee4a1c a16ca239

+152 -69
+150 -68
drivers/input/keyboard/gpio_keys.c
··· 28 28 #include <linux/gpio.h> 29 29 #include <linux/of_platform.h> 30 30 #include <linux/of_gpio.h> 31 + #include <linux/spinlock.h> 31 32 32 33 struct gpio_button_data { 33 34 const struct gpio_keys_button *button; 34 35 struct input_dev *input; 35 36 struct timer_list timer; 36 37 struct work_struct work; 37 - int timer_debounce; /* in msecs */ 38 + unsigned int timer_debounce; /* in msecs */ 39 + unsigned int irq; 40 + spinlock_t lock; 38 41 bool disabled; 42 + bool key_pressed; 39 43 }; 40 44 41 45 struct gpio_keys_drvdata { ··· 118 114 /* 119 115 * Disable IRQ and possible debouncing timer. 120 116 */ 121 - disable_irq(gpio_to_irq(bdata->button->gpio)); 117 + disable_irq(bdata->irq); 122 118 if (bdata->timer_debounce) 123 119 del_timer_sync(&bdata->timer); 124 120 ··· 139 135 static void gpio_keys_enable_button(struct gpio_button_data *bdata) 140 136 { 141 137 if (bdata->disabled) { 142 - enable_irq(gpio_to_irq(bdata->button->gpio)); 138 + enable_irq(bdata->irq); 143 139 bdata->disabled = false; 144 140 } 145 141 } ··· 324 320 .attrs = gpio_keys_attrs, 325 321 }; 326 322 327 - static void gpio_keys_report_event(struct gpio_button_data *bdata) 323 + static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) 328 324 { 329 325 const struct gpio_keys_button *button = bdata->button; 330 326 struct input_dev *input = bdata->input; ··· 340 336 input_sync(input); 341 337 } 342 338 343 - static void gpio_keys_work_func(struct work_struct *work) 339 + static void gpio_keys_gpio_work_func(struct work_struct *work) 344 340 { 345 341 struct gpio_button_data *bdata = 346 342 container_of(work, struct gpio_button_data, work); 347 343 348 - gpio_keys_report_event(bdata); 344 + gpio_keys_gpio_report_event(bdata); 349 345 } 350 346 351 - static void gpio_keys_timer(unsigned long _data) 347 + static void gpio_keys_gpio_timer(unsigned long _data) 352 348 { 353 - struct gpio_button_data *data = (struct gpio_button_data *)_data; 349 + struct gpio_button_data *bdata = (struct gpio_button_data *)_data; 354 350 355 - schedule_work(&data->work); 351 + schedule_work(&bdata->work); 356 352 } 357 353 358 - static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 354 + static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) 359 355 { 360 356 struct gpio_button_data *bdata = dev_id; 361 - const struct gpio_keys_button *button = bdata->button; 362 357 363 - BUG_ON(irq != gpio_to_irq(button->gpio)); 358 + BUG_ON(irq != bdata->irq); 364 359 365 360 if (bdata->timer_debounce) 366 361 mod_timer(&bdata->timer, ··· 370 367 return IRQ_HANDLED; 371 368 } 372 369 370 + static void gpio_keys_irq_timer(unsigned long _data) 371 + { 372 + struct gpio_button_data *bdata = (struct gpio_button_data *)_data; 373 + struct input_dev *input = bdata->input; 374 + unsigned long flags; 375 + 376 + spin_lock_irqsave(&bdata->lock, flags); 377 + if (bdata->key_pressed) { 378 + input_event(input, EV_KEY, bdata->button->code, 0); 379 + input_sync(input); 380 + bdata->key_pressed = false; 381 + } 382 + spin_unlock_irqrestore(&bdata->lock, flags); 383 + } 384 + 385 + static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) 386 + { 387 + struct gpio_button_data *bdata = dev_id; 388 + const struct gpio_keys_button *button = bdata->button; 389 + struct input_dev *input = bdata->input; 390 + unsigned long flags; 391 + 392 + BUG_ON(irq != bdata->irq); 393 + 394 + spin_lock_irqsave(&bdata->lock, flags); 395 + 396 + if (!bdata->key_pressed) { 397 + input_event(input, EV_KEY, button->code, 1); 398 + input_sync(input); 399 + 400 + if (!bdata->timer_debounce) { 401 + input_event(input, EV_KEY, button->code, 0); 402 + input_sync(input); 403 + goto out; 404 + } 405 + 406 + bdata->key_pressed = true; 407 + } 408 + 409 + if (bdata->timer_debounce) 410 + mod_timer(&bdata->timer, 411 + jiffies + msecs_to_jiffies(bdata->timer_debounce)); 412 + out: 413 + spin_unlock_irqrestore(&bdata->lock, flags); 414 + return IRQ_HANDLED; 415 + } 416 + 373 417 static int __devinit gpio_keys_setup_key(struct platform_device *pdev, 374 418 struct input_dev *input, 375 419 struct gpio_button_data *bdata, ··· 424 374 { 425 375 const char *desc = button->desc ? button->desc : "gpio_keys"; 426 376 struct device *dev = &pdev->dev; 377 + irq_handler_t isr; 427 378 unsigned long irqflags; 428 379 int irq, error; 429 380 430 - setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); 431 - INIT_WORK(&bdata->work, gpio_keys_work_func); 432 381 bdata->input = input; 433 382 bdata->button = button; 383 + spin_lock_init(&bdata->lock); 434 384 435 - error = gpio_request(button->gpio, desc); 436 - if (error < 0) { 437 - dev_err(dev, "failed to request GPIO %d, error %d\n", 438 - button->gpio, error); 439 - goto fail2; 385 + if (gpio_is_valid(button->gpio)) { 386 + 387 + error = gpio_request(button->gpio, desc); 388 + if (error < 0) { 389 + dev_err(dev, "Failed to request GPIO %d, error %d\n", 390 + button->gpio, error); 391 + return error; 392 + } 393 + 394 + error = gpio_direction_input(button->gpio); 395 + if (error < 0) { 396 + dev_err(dev, 397 + "Failed to configure direction for GPIO %d, error %d\n", 398 + button->gpio, error); 399 + goto fail; 400 + } 401 + 402 + if (button->debounce_interval) { 403 + error = gpio_set_debounce(button->gpio, 404 + button->debounce_interval * 1000); 405 + /* use timer if gpiolib doesn't provide debounce */ 406 + if (error < 0) 407 + bdata->timer_debounce = 408 + button->debounce_interval; 409 + } 410 + 411 + irq = gpio_to_irq(button->gpio); 412 + if (irq < 0) { 413 + error = irq; 414 + dev_err(dev, 415 + "Unable to get irq number for GPIO %d, error %d\n", 416 + button->gpio, error); 417 + goto fail; 418 + } 419 + bdata->irq = irq; 420 + 421 + INIT_WORK(&bdata->work, gpio_keys_gpio_work_func); 422 + setup_timer(&bdata->timer, 423 + gpio_keys_gpio_timer, (unsigned long)bdata); 424 + 425 + isr = gpio_keys_gpio_isr; 426 + irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 427 + 428 + } else { 429 + if (!button->irq) { 430 + dev_err(dev, "No IRQ specified\n"); 431 + return -EINVAL; 432 + } 433 + bdata->irq = button->irq; 434 + 435 + if (button->type && button->type != EV_KEY) { 436 + dev_err(dev, "Only EV_KEY allowed for IRQ buttons.\n"); 437 + return -EINVAL; 438 + } 439 + 440 + bdata->timer_debounce = button->debounce_interval; 441 + setup_timer(&bdata->timer, 442 + gpio_keys_irq_timer, (unsigned long)bdata); 443 + 444 + isr = gpio_keys_irq_isr; 445 + irqflags = 0; 440 446 } 441 447 442 - error = gpio_direction_input(button->gpio); 443 - if (error < 0) { 444 - dev_err(dev, "failed to configure" 445 - " direction for GPIO %d, error %d\n", 446 - button->gpio, error); 447 - goto fail3; 448 - } 448 + input_set_capability(input, button->type ?: EV_KEY, button->code); 449 449 450 - if (button->debounce_interval) { 451 - error = gpio_set_debounce(button->gpio, 452 - button->debounce_interval * 1000); 453 - /* use timer if gpiolib doesn't provide debounce */ 454 - if (error < 0) 455 - bdata->timer_debounce = button->debounce_interval; 456 - } 457 - 458 - irq = gpio_to_irq(button->gpio); 459 - if (irq < 0) { 460 - error = irq; 461 - dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", 462 - button->gpio, error); 463 - goto fail3; 464 - } 465 - 466 - irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 467 450 /* 468 451 * If platform has specified that the button can be disabled, 469 452 * we don't want it to share the interrupt line. ··· 504 421 if (!button->can_disable) 505 422 irqflags |= IRQF_SHARED; 506 423 507 - error = request_any_context_irq(irq, gpio_keys_isr, irqflags, desc, bdata); 424 + error = request_any_context_irq(bdata->irq, isr, irqflags, desc, bdata); 508 425 if (error < 0) { 509 426 dev_err(dev, "Unable to claim irq %d; error %d\n", 510 - irq, error); 511 - goto fail3; 427 + bdata->irq, error); 428 + goto fail; 512 429 } 513 430 514 - input_set_capability(input, button->type ?: EV_KEY, button->code); 515 431 return 0; 516 432 517 - fail3: 518 - gpio_free(button->gpio); 519 - fail2: 433 + fail: 434 + if (gpio_is_valid(button->gpio)) 435 + gpio_free(button->gpio); 436 + 520 437 return error; 521 438 } 522 439 ··· 636 553 637 554 static void gpio_remove_key(struct gpio_button_data *bdata) 638 555 { 639 - free_irq(gpio_to_irq(bdata->button->gpio), bdata); 556 + free_irq(bdata->irq, bdata); 640 557 if (bdata->timer_debounce) 641 558 del_timer_sync(&bdata->timer); 642 559 cancel_work_sync(&bdata->work); 643 - gpio_free(bdata->button->gpio); 560 + if (gpio_is_valid(bdata->button->gpio)) 561 + gpio_free(bdata->button->gpio); 644 562 } 645 563 646 564 static int __devinit gpio_keys_probe(struct platform_device *pdev) ··· 721 637 goto fail3; 722 638 } 723 639 724 - /* get current state of buttons */ 725 - for (i = 0; i < pdata->nbuttons; i++) 726 - gpio_keys_report_event(&ddata->data[i]); 640 + /* get current state of buttons that are connected to GPIOs */ 641 + for (i = 0; i < pdata->nbuttons; i++) { 642 + struct gpio_button_data *bdata = &ddata->data[i]; 643 + if (gpio_is_valid(bdata->button->gpio)) 644 + gpio_keys_gpio_report_event(bdata); 645 + } 727 646 input_sync(input); 728 647 729 648 device_init_wakeup(&pdev->dev, wakeup); ··· 782 695 static int gpio_keys_suspend(struct device *dev) 783 696 { 784 697 struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); 785 - const struct gpio_keys_button *button; 786 698 int i; 787 699 788 700 if (device_may_wakeup(dev)) { 789 701 for (i = 0; i < ddata->n_buttons; i++) { 790 - button = ddata->data[i].button; 791 - if (button->wakeup) { 792 - int irq = gpio_to_irq(button->gpio); 793 - enable_irq_wake(irq); 794 - } 702 + struct gpio_button_data *bdata = &ddata->data[i]; 703 + if (bdata->button->wakeup) 704 + enable_irq_wake(bdata->irq); 795 705 } 796 706 } 797 707 ··· 798 714 static int gpio_keys_resume(struct device *dev) 799 715 { 800 716 struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); 801 - const struct gpio_keys_button *button; 802 717 int i; 803 718 804 719 for (i = 0; i < ddata->n_buttons; i++) { 805 - button = ddata->data[i].button; 806 - if (button->wakeup && device_may_wakeup(dev)) { 807 - int irq = gpio_to_irq(button->gpio); 808 - disable_irq_wake(irq); 809 - } 720 + struct gpio_button_data *bdata = &ddata->data[i]; 721 + if (bdata->button->wakeup && device_may_wakeup(dev)) 722 + disable_irq_wake(bdata->irq); 810 723 811 - gpio_keys_report_event(&ddata->data[i]); 724 + if (gpio_is_valid(bdata->button->gpio)) 725 + gpio_keys_gpio_report_event(bdata); 812 726 } 813 727 input_sync(ddata->input); 814 728
+2 -1
include/linux/gpio_keys.h
··· 6 6 struct gpio_keys_button { 7 7 /* Configuration parameters */ 8 8 unsigned int code; /* input event code (KEY_*, SW_*) */ 9 - int gpio; 9 + int gpio; /* -1 if this key does not support gpio */ 10 10 int active_low; 11 11 const char *desc; 12 12 unsigned int type; /* input event type (EV_KEY, EV_SW, EV_ABS) */ ··· 14 14 int debounce_interval; /* debounce ticks interval in msecs */ 15 15 bool can_disable; 16 16 int value; /* axis value for EV_ABS */ 17 + unsigned int irq; /* Irq number in case of interrupt keys */ 17 18 }; 18 19 19 20 struct gpio_keys_platform_data {