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>
This commit is contained in:
parent
c272985098
commit
768d9aa557
1 changed files with 57 additions and 19 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
mutex_lock(&dev->mutex);
|
mutex_lock(&dev->mutex);
|
||||||
|
spin_lock_irqsave(&dev->event_lock, flags);
|
||||||
|
|
||||||
if (dev->users) {
|
|
||||||
input_dev_toggle(dev, true);
|
input_dev_toggle(dev, true);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
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)
|
/*
|
||||||
|
* Keys that are pressed now are unlikely to be
|
||||||
|
* still pressed when we resume.
|
||||||
|
*/
|
||||||
|
input_dev_release_keys(input_dev);
|
||||||
|
|
||||||
|
/* Turn off LEDs and sounds, if any are active. */
|
||||||
input_dev_toggle(input_dev, false);
|
input_dev_toggle(input_dev, false);
|
||||||
|
|
||||||
mutex_unlock(&input_dev->mutex);
|
spin_unlock_irq(&input_dev->event_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
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 = {
|
||||||
.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
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue