Commit b50b5216 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: export input_reset_device() for use in KGDB

KGDB, much like the resume process, needs to be able to mark all keys that
were pressed at the time we dropped into the debuggers as "released", since
it is unlikely that the keys stay pressed for the entire duration of the
debug session.

Also we need to make sure that input_reset_device() and input_dev_suspend()
only attempt to change state of currenlt opened devices since closed devices
may not be ready to accept IO requests.
Tested-by: default avatarJason Wessel <jason.wessel@windriver.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 95716c0d
...@@ -1565,8 +1565,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) ...@@ -1565,8 +1565,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
} \ } \
} while (0) } while (0)
#ifdef CONFIG_PM static void input_dev_toggle(struct input_dev *dev, bool activate)
static void input_dev_reset(struct input_dev *dev, bool activate)
{ {
if (!dev->event) if (!dev->event)
return; return;
...@@ -1580,12 +1579,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate) ...@@ -1580,12 +1579,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
} }
} }
/**
* input_reset_device() - reset/restore the state of input device
* @dev: input device whose state needs to be reset
*
* This function tries to reset the state of an opened input device and
* bring internal state and state if the hardware in sync with each other.
* We mark all keys as released, restore LED state, repeat rate, etc.
*/
void input_reset_device(struct input_dev *dev)
{
mutex_lock(&dev->mutex);
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);
}
mutex_unlock(&dev->mutex);
}
EXPORT_SYMBOL(input_reset_device);
#ifdef CONFIG_PM
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); mutex_lock(&input_dev->mutex);
input_dev_reset(input_dev, false);
if (input_dev->users)
input_dev_toggle(input_dev, false);
mutex_unlock(&input_dev->mutex); mutex_unlock(&input_dev->mutex);
return 0; return 0;
...@@ -1595,18 +1626,7 @@ static int input_dev_resume(struct device *dev) ...@@ -1595,18 +1626,7 @@ 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);
mutex_lock(&input_dev->mutex); input_reset_device(input_dev);
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);
return 0; return 0;
} }
......
...@@ -1406,6 +1406,8 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data) ...@@ -1406,6 +1406,8 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data)
int __must_check input_register_device(struct input_dev *); int __must_check input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *); void input_unregister_device(struct input_dev *);
void input_reset_device(struct input_dev *);
int __must_check input_register_handler(struct input_handler *); int __must_check input_register_handler(struct input_handler *);
void input_unregister_handler(struct input_handler *); void input_unregister_handler(struct input_handler *);
...@@ -1421,7 +1423,7 @@ void input_release_device(struct input_handle *); ...@@ -1421,7 +1423,7 @@ void input_release_device(struct input_handle *);
int input_open_device(struct input_handle *); int input_open_device(struct input_handle *);
void input_close_device(struct input_handle *); void input_close_device(struct input_handle *);
int input_flush_device(struct input_handle* handle, struct file* file); int input_flush_device(struct input_handle *handle, struct file *file);
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value); void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
......
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