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)
*/
void input_reset_device(struct input_dev *dev)
{
mutex_lock(&dev->mutex);
unsigned long flags;
if (dev->users) {
input_dev_toggle(dev, true);
mutex_lock(&dev->mutex);
spin_lock_irqsave(&dev->event_lock, flags);
/*
* Keys that have been pressed at suspend time are unlikely
* to be still pressed when we resume.
*/
spin_lock_irq(&dev->event_lock);
input_dev_release_keys(dev);
spin_unlock_irq(&dev->event_lock);
}
input_dev_toggle(dev, true);
input_dev_release_keys(dev);
spin_unlock_irqrestore(&dev->event_lock, flags);
mutex_unlock(&dev->mutex);
}
EXPORT_SYMBOL(input_reset_device);
#ifdef CONFIG_PM
#ifdef CONFIG_PM_SLEEP
static int input_dev_suspend(struct device *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;
}
......@@ -1690,7 +1691,43 @@ static int input_dev_resume(struct device *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;
}
......@@ -1698,7 +1735,8 @@ static int input_dev_resume(struct device *dev)
static const struct dev_pm_ops input_dev_pm_ops = {
.suspend = input_dev_suspend,
.resume = input_dev_resume,
.poweroff = input_dev_suspend,
.freeze = input_dev_freeze,
.poweroff = input_dev_poweroff,
.restore = input_dev_resume,
};
#endif /* CONFIG_PM */
......@@ -1707,7 +1745,7 @@ static struct device_type input_dev_type = {
.groups = input_dev_attr_groups,
.release = input_dev_release,
.uevent = input_dev_uevent,
#ifdef CONFIG_PM
#ifdef CONFIG_PM_SLEEP
.pm = &input_dev_pm_ops,
#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