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

Commit 866d7d7b authored by Oliver Neukum's avatar Oliver Neukum Committed by Dmitry Torokhov
Browse files

Input: release pressed keys when resuming device



As the kernel has no way to know whether a key was released
while the system was asleep, keys need to be reported released
as the system is resumed, lest autorepeat set in.

Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 3eac5c7e
Loading
Loading
Loading
Loading
+29 −10
Original line number Original line Diff line number Diff line
@@ -527,13 +527,31 @@ void input_close_device(struct input_handle *handle)
}
}
EXPORT_SYMBOL(input_close_device);
EXPORT_SYMBOL(input_close_device);


/*
 * Simulate keyup events for all keys that are marked as pressed.
 * The function must be called with dev->event_lock held.
 */
static void input_dev_release_keys(struct input_dev *dev)
{
	int code;

	if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
		for (code = 0; code <= KEY_MAX; code++) {
			if (is_event_supported(code, dev->keybit, KEY_MAX) &&
			    __test_and_clear_bit(code, dev->key)) {
				input_pass_event(dev, EV_KEY, code, 0);
			}
		}
		input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
	}
}

/*
/*
 * Prepare device for unregistering
 * Prepare device for unregistering
 */
 */
static void input_disconnect_device(struct input_dev *dev)
static void input_disconnect_device(struct input_dev *dev)
{
{
	struct input_handle *handle;
	struct input_handle *handle;
	int code;


	/*
	/*
	 * Mark device as going away. Note that we take dev->mutex here
	 * Mark device as going away. Note that we take dev->mutex here
@@ -552,15 +570,7 @@ static void input_disconnect_device(struct input_dev *dev)
	 * generate events even after we done here but they will not
	 * generate events even after we done here but they will not
	 * reach any handlers.
	 * reach any handlers.
	 */
	 */
	if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
	input_dev_release_keys(dev);
		for (code = 0; code <= KEY_MAX; code++) {
			if (is_event_supported(code, dev->keybit, KEY_MAX) &&
			    __test_and_clear_bit(code, dev->key)) {
				input_pass_event(dev, EV_KEY, code, 0);
			}
		}
		input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
	}


	list_for_each_entry(handle, &dev->h_list, d_node)
	list_for_each_entry(handle, &dev->h_list, d_node)
		handle->open = 0;
		handle->open = 0;
@@ -1433,6 +1443,15 @@ static int input_dev_resume(struct device *dev)


	mutex_lock(&input_dev->mutex);
	mutex_lock(&input_dev->mutex);
	input_dev_reset(input_dev, true);
	input_dev_reset(input_dev, true);

	/*
	 * Keys that have been pressed at suspend time are unlikely
	 * to be still pressed when we resume.
	 */
	spin_lock_irq(&input_dev->event_lock);
	input_dev_release_keys(input_dev);
	spin_unlock_irq(&input_dev->event_lock);

	mutex_unlock(&input_dev->mutex);
	mutex_unlock(&input_dev->mutex);


	return 0;
	return 0;