diff options
| author | Aleksej Makarov <aleksej.makarov@sonymobile.com> | 2013-11-23 13:20:36 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-12-16 05:19:10 -0500 |
| commit | 768d9aa55740754aa4efb8aca594e3841237dd88 (patch) | |
| tree | d3f3206b34ce83a96318e342e3fbfa196dba44a9 | |
| parent | c2729850985934a3124319f8ff1d46d8c72bb012 (diff) | |
Input: don't call input_dev_release_keys() in resume
When waking up the platform by pressing a specific key, sending a
release on that key makes it impossible to react on the event in
user-space. This is fixed by moving the input_reset_device() call to
resume instead.
[dmitry.torokhov@gmail.com: make sure we still restore LED/sound state
after resume, handle hibernation properly]
Signed-off-by: Aleksej Makarov <aleksej.makarov@sonymobile.com>
Signed-off-by: Oskar Andero <oskar.andero@sonymobile.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
| -rw-r--r-- | drivers/input/input.c | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 846ccdd905b1..692435a321af 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -1653,35 +1653,36 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) | |||
| 1653 | */ | 1653 | */ |
| 1654 | void input_reset_device(struct input_dev *dev) | 1654 | void input_reset_device(struct input_dev *dev) |
| 1655 | { | 1655 | { |
| 1656 | mutex_lock(&dev->mutex); | 1656 | unsigned long flags; |
| 1657 | 1657 | ||
| 1658 | if (dev->users) { | 1658 | mutex_lock(&dev->mutex); |
| 1659 | input_dev_toggle(dev, true); | 1659 | spin_lock_irqsave(&dev->event_lock, flags); |
| 1660 | 1660 | ||
| 1661 | /* | 1661 | input_dev_toggle(dev, true); |
| 1662 | * Keys that have been pressed at suspend time are unlikely | 1662 | input_dev_release_keys(dev); |
| 1663 | * to be still pressed when we resume. | ||
| 1664 | */ | ||
| 1665 | spin_lock_irq(&dev->event_lock); | ||
| 1666 | input_dev_release_keys(dev); | ||
| 1667 | spin_unlock_irq(&dev->event_lock); | ||
| 1668 | } | ||
| 1669 | 1663 | ||
| 1664 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 1670 | mutex_unlock(&dev->mutex); | 1665 | mutex_unlock(&dev->mutex); |
| 1671 | } | 1666 | } |
| 1672 | EXPORT_SYMBOL(input_reset_device); | 1667 | EXPORT_SYMBOL(input_reset_device); |
| 1673 | 1668 | ||
| 1674 | #ifdef CONFIG_PM | 1669 | #ifdef CONFIG_PM_SLEEP |
| 1675 | static int input_dev_suspend(struct device *dev) | 1670 | static int input_dev_suspend(struct device *dev) |
| 1676 | { | 1671 | { |
| 1677 | struct input_dev *input_dev = to_input_dev(dev); | 1672 | struct input_dev *input_dev = to_input_dev(dev); |
| 1678 | 1673 | ||
| 1679 | mutex_lock(&input_dev->mutex); | 1674 | spin_lock_irq(&input_dev->event_lock); |
| 1680 | 1675 | ||
| 1681 | if (input_dev->users) | 1676 | /* |
| 1682 | input_dev_toggle(input_dev, false); | 1677 | * Keys that are pressed now are unlikely to be |
| 1678 | * still pressed when we resume. | ||
| 1679 | */ | ||
| 1680 | input_dev_release_keys(input_dev); | ||
| 1683 | 1681 | ||
| 1684 | mutex_unlock(&input_dev->mutex); | 1682 | /* Turn off LEDs and sounds, if any are active. */ |
| 1683 | input_dev_toggle(input_dev, false); | ||
| 1684 | |||
| 1685 | spin_unlock_irq(&input_dev->event_lock); | ||
| 1685 | 1686 | ||
| 1686 | return 0; | 1687 | return 0; |
| 1687 | } | 1688 | } |
| @@ -1690,7 +1691,43 @@ static int input_dev_resume(struct device *dev) | |||
| 1690 | { | 1691 | { |
| 1691 | struct input_dev *input_dev = to_input_dev(dev); | 1692 | struct input_dev *input_dev = to_input_dev(dev); |
| 1692 | 1693 | ||
| 1693 | input_reset_device(input_dev); | 1694 | spin_lock_irq(&input_dev->event_lock); |
| 1695 | |||
| 1696 | /* Restore state of LEDs and sounds, if any were active. */ | ||
| 1697 | input_dev_toggle(input_dev, true); | ||
| 1698 | |||
| 1699 | spin_unlock_irq(&input_dev->event_lock); | ||
| 1700 | |||
| 1701 | return 0; | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | static int input_dev_freeze(struct device *dev) | ||
| 1705 | { | ||
| 1706 | struct input_dev *input_dev = to_input_dev(dev); | ||
| 1707 | |||
| 1708 | spin_lock_irq(&input_dev->event_lock); | ||
| 1709 | |||
| 1710 | /* | ||
| 1711 | * Keys that are pressed now are unlikely to be | ||
| 1712 | * still pressed when we resume. | ||
| 1713 | */ | ||
| 1714 | input_dev_release_keys(input_dev); | ||
| 1715 | |||
| 1716 | spin_unlock_irq(&input_dev->event_lock); | ||
| 1717 | |||
| 1718 | return 0; | ||
| 1719 | } | ||
| 1720 | |||
| 1721 | static int input_dev_poweroff(struct device *dev) | ||
| 1722 | { | ||
| 1723 | struct input_dev *input_dev = to_input_dev(dev); | ||
| 1724 | |||
| 1725 | spin_lock_irq(&input_dev->event_lock); | ||
| 1726 | |||
| 1727 | /* Turn off LEDs and sounds, if any are active. */ | ||
| 1728 | input_dev_toggle(input_dev, false); | ||
| 1729 | |||
| 1730 | spin_unlock_irq(&input_dev->event_lock); | ||
| 1694 | 1731 | ||
| 1695 | return 0; | 1732 | return 0; |
| 1696 | } | 1733 | } |
| @@ -1698,7 +1735,8 @@ static int input_dev_resume(struct device *dev) | |||
| 1698 | static const struct dev_pm_ops input_dev_pm_ops = { | 1735 | static const struct dev_pm_ops input_dev_pm_ops = { |
| 1699 | .suspend = input_dev_suspend, | 1736 | .suspend = input_dev_suspend, |
| 1700 | .resume = input_dev_resume, | 1737 | .resume = input_dev_resume, |
| 1701 | .poweroff = input_dev_suspend, | 1738 | .freeze = input_dev_freeze, |
| 1739 | .poweroff = input_dev_poweroff, | ||
| 1702 | .restore = input_dev_resume, | 1740 | .restore = input_dev_resume, |
| 1703 | }; | 1741 | }; |
| 1704 | #endif /* CONFIG_PM */ | 1742 | #endif /* CONFIG_PM */ |
| @@ -1707,7 +1745,7 @@ static struct device_type input_dev_type = { | |||
| 1707 | .groups = input_dev_attr_groups, | 1745 | .groups = input_dev_attr_groups, |
| 1708 | .release = input_dev_release, | 1746 | .release = input_dev_release, |
| 1709 | .uevent = input_dev_uevent, | 1747 | .uevent = input_dev_uevent, |
| 1710 | #ifdef CONFIG_PM | 1748 | #ifdef CONFIG_PM_SLEEP |
| 1711 | .pm = &input_dev_pm_ops, | 1749 | .pm = &input_dev_pm_ops, |
| 1712 | #endif | 1750 | #endif |
| 1713 | }; | 1751 | }; |
