Commit 768d9aa5 authored by Aleksej Makarov's avatar Aleksej Makarov Committed by Dmitry Torokhov

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: default avatarAleksej Makarov <aleksej.makarov@sonymobile.com>
Signed-off-by: default avatarOskar Andero <oskar.andero@sonymobile.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent c2729850
...@@ -1653,35 +1653,36 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) ...@@ -1653,35 +1653,36 @@ static void input_dev_toggle(struct input_dev *dev, bool activate)
*/ */
void input_reset_device(struct input_dev *dev) void input_reset_device(struct input_dev *dev)
{ {
mutex_lock(&dev->mutex); unsigned long flags;
if (dev->users) { mutex_lock(&dev->mutex);
input_dev_toggle(dev, true); spin_lock_irqsave(&dev->event_lock, flags);
/* input_dev_toggle(dev, true);
* Keys that have been pressed at suspend time are unlikely input_dev_release_keys(dev);
* to be still pressed when we resume.
*/
spin_lock_irq(&dev->event_lock);
input_dev_release_keys(dev);
spin_unlock_irq(&dev->event_lock);
}
spin_unlock_irqrestore(&dev->event_lock, flags);
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
} }
EXPORT_SYMBOL(input_reset_device); EXPORT_SYMBOL(input_reset_device);
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int input_dev_suspend(struct device *dev) static int input_dev_suspend(struct device *dev)
{ {
struct input_dev *input_dev = to_input_dev(dev); struct input_dev *input_dev = to_input_dev(dev);
mutex_lock(&input_dev->mutex); spin_lock_irq(&input_dev->event_lock);
if (input_dev->users) /*
input_dev_toggle(input_dev, false); * Keys that are pressed now are unlikely to be
* still pressed when we resume.
*/
input_dev_release_keys(input_dev);
mutex_unlock(&input_dev->mutex); /* Turn off LEDs and sounds, if any are active. */
input_dev_toggle(input_dev, false);
spin_unlock_irq(&input_dev->event_lock);
return 0; return 0;
} }
...@@ -1690,7 +1691,43 @@ static int input_dev_resume(struct device *dev) ...@@ -1690,7 +1691,43 @@ static int input_dev_resume(struct device *dev)
{ {
struct input_dev *input_dev = to_input_dev(dev); struct input_dev *input_dev = to_input_dev(dev);
input_reset_device(input_dev); spin_lock_irq(&input_dev->event_lock);
/* Restore state of LEDs and sounds, if any were active. */
input_dev_toggle(input_dev, true);
spin_unlock_irq(&input_dev->event_lock);
return 0;
}
static int input_dev_freeze(struct device *dev)
{
struct input_dev *input_dev = to_input_dev(dev);
spin_lock_irq(&input_dev->event_lock);
/*
* Keys that are pressed now are unlikely to be
* still pressed when we resume.
*/
input_dev_release_keys(input_dev);
spin_unlock_irq(&input_dev->event_lock);
return 0;
}
static int input_dev_poweroff(struct device *dev)
{
struct input_dev *input_dev = to_input_dev(dev);
spin_lock_irq(&input_dev->event_lock);
/* Turn off LEDs and sounds, if any are active. */
input_dev_toggle(input_dev, false);
spin_unlock_irq(&input_dev->event_lock);
return 0; return 0;
} }
...@@ -1698,7 +1735,8 @@ static int input_dev_resume(struct device *dev) ...@@ -1698,7 +1735,8 @@ static int input_dev_resume(struct device *dev)
static const struct dev_pm_ops input_dev_pm_ops = { static const struct dev_pm_ops input_dev_pm_ops = {
.suspend = input_dev_suspend, .suspend = input_dev_suspend,
.resume = input_dev_resume, .resume = input_dev_resume,
.poweroff = input_dev_suspend, .freeze = input_dev_freeze,
.poweroff = input_dev_poweroff,
.restore = input_dev_resume, .restore = input_dev_resume,
}; };
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
...@@ -1707,7 +1745,7 @@ static struct device_type input_dev_type = { ...@@ -1707,7 +1745,7 @@ static struct device_type input_dev_type = {
.groups = input_dev_attr_groups, .groups = input_dev_attr_groups,
.release = input_dev_release, .release = input_dev_release,
.uevent = input_dev_uevent, .uevent = input_dev_uevent,
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
.pm = &input_dev_pm_ops, .pm = &input_dev_pm_ops,
#endif #endif
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment