diff options
| author | Hui Wang <jason77.wang@gmail.com> | 2011-10-13 00:11:16 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-10-13 00:13:16 -0400 |
| commit | 81e8f2bc82cd591a749c0cc5694f57676db749ae (patch) | |
| tree | 1b1939b610b9c65638cb9092dda8f1597ab64cba /drivers/input | |
| parent | 05be8b81aafd4f95106a91ff3fd8581fa984fad9 (diff) | |
Input: imx_keypad - add pm suspend and resume support
The imx_keypad driver was indicating that it was wakeup capable in
imx_keypad_probe(), but it didn't implement suspend or resume methods.
According to the i.MX series MCU Reference Manual, the kpp (keypad
port) is a major wake up source which can detect any key press even
in low power mode and even when there is no clock.
Signed-off-by: Hui Wang <jason77.wang@gmail.com>
Reviewed-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/keyboard/imx_keypad.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 4b093faf5786..ccebd2d09151 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
| @@ -567,10 +567,54 @@ static int __devexit imx_keypad_remove(struct platform_device *pdev) | |||
| 567 | return 0; | 567 | return 0; |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | #ifdef CONFIG_PM_SLEEP | ||
| 571 | static int imx_kbd_suspend(struct device *dev) | ||
| 572 | { | ||
| 573 | struct platform_device *pdev = to_platform_device(dev); | ||
| 574 | struct imx_keypad *kbd = platform_get_drvdata(pdev); | ||
| 575 | struct input_dev *input_dev = kbd->input_dev; | ||
| 576 | |||
| 577 | /* imx kbd can wake up system even clock is disabled */ | ||
| 578 | mutex_lock(&input_dev->mutex); | ||
| 579 | |||
| 580 | if (input_dev->users) | ||
| 581 | clk_disable(kbd->clk); | ||
| 582 | |||
| 583 | mutex_unlock(&input_dev->mutex); | ||
| 584 | |||
| 585 | if (device_may_wakeup(&pdev->dev)) | ||
| 586 | enable_irq_wake(kbd->irq); | ||
| 587 | |||
| 588 | return 0; | ||
| 589 | } | ||
| 590 | |||
| 591 | static int imx_kbd_resume(struct device *dev) | ||
| 592 | { | ||
| 593 | struct platform_device *pdev = to_platform_device(dev); | ||
| 594 | struct imx_keypad *kbd = platform_get_drvdata(pdev); | ||
| 595 | struct input_dev *input_dev = kbd->input_dev; | ||
| 596 | |||
| 597 | if (device_may_wakeup(&pdev->dev)) | ||
| 598 | disable_irq_wake(kbd->irq); | ||
| 599 | |||
| 600 | mutex_lock(&input_dev->mutex); | ||
| 601 | |||
| 602 | if (input_dev->users) | ||
| 603 | clk_enable(kbd->clk); | ||
| 604 | |||
| 605 | mutex_unlock(&input_dev->mutex); | ||
| 606 | |||
| 607 | return 0; | ||
| 608 | } | ||
| 609 | #endif | ||
| 610 | |||
| 611 | static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume); | ||
| 612 | |||
| 570 | static struct platform_driver imx_keypad_driver = { | 613 | static struct platform_driver imx_keypad_driver = { |
| 571 | .driver = { | 614 | .driver = { |
| 572 | .name = "imx-keypad", | 615 | .name = "imx-keypad", |
| 573 | .owner = THIS_MODULE, | 616 | .owner = THIS_MODULE, |
| 617 | .pm = &imx_kbd_pm_ops, | ||
| 574 | }, | 618 | }, |
| 575 | .probe = imx_keypad_probe, | 619 | .probe = imx_keypad_probe, |
| 576 | .remove = __devexit_p(imx_keypad_remove), | 620 | .remove = __devexit_p(imx_keypad_remove), |
