aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksej Makarov <aleksej.makarov@sonymobile.com>2013-11-23 13:20:36 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-12-16 05:19:10 -0500
commit768d9aa55740754aa4efb8aca594e3841237dd88 (patch)
treed3f3206b34ce83a96318e342e3fbfa196dba44a9
parentc2729850985934a3124319f8ff1d46d8c72bb012 (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.c76
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 */
1654void input_reset_device(struct input_dev *dev) 1654void 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}
1672EXPORT_SYMBOL(input_reset_device); 1667EXPORT_SYMBOL(input_reset_device);
1673 1668
1674#ifdef CONFIG_PM 1669#ifdef CONFIG_PM_SLEEP
1675static int input_dev_suspend(struct device *dev) 1670static 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
1704static 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
1721static 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)
1698static const struct dev_pm_ops input_dev_pm_ops = { 1735static 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};