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 | }; |