Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+57 −19
Original line number Diff line number Diff line
@@ -1653,35 +1653,36 @@ static void input_dev_toggle(struct input_dev *dev, bool activate)
 */
void input_reset_device(struct input_dev *dev)
{
	unsigned long flags;

	mutex_lock(&dev->mutex);
	spin_lock_irqsave(&dev->event_lock, flags);

	if (dev->users) {
	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);
		spin_unlock_irq(&dev->event_lock);
	}

	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)
	/*
	 * 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);

	mutex_unlock(&input_dev->mutex);
	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
};