summaryrefslogtreecommitdiff
path: root/drivers/input/input.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-11-03 11:02:31 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-11-03 11:04:46 -0700
commitb50b521694cb7093640879d3279b88d2873f6183 (patch)
treec797834c252a2adfb3828ce4dfc91f4b49024bb8 /drivers/input/input.c
parent95716c0decb2ed3ff94998b6390cc8f8d6d1e748 (diff)
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: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r--drivers/input/input.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index d092ef9291da..75bed635b98d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1565,8 +1565,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
} \
} while (0)
-#ifdef CONFIG_PM
-static void input_dev_reset(struct input_dev *dev, bool activate)
+static void input_dev_toggle(struct input_dev *dev, bool activate)
{
if (!dev->event)
return;
@@ -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)
{
struct input_dev *input_dev = to_input_dev(dev);
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);
return 0;
@@ -1595,18 +1626,7 @@ static int input_dev_resume(struct device *dev)
{
struct input_dev *input_dev = to_input_dev(dev);
- mutex_lock(&input_dev->mutex);
- 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);
+ input_reset_device(input_dev);
return 0;
}