aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-11-03 14:02:31 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-11-03 14:04:46 -0400
commitb50b521694cb7093640879d3279b88d2873f6183 (patch)
treec797834c252a2adfb3828ce4dfc91f4b49024bb8 /drivers/input
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')
-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)
1565 } \ 1565 } \
1566 } while (0) 1566 } while (0)
1567 1567
1568#ifdef CONFIG_PM 1568static void input_dev_toggle(struct input_dev *dev, bool activate)
1569static void input_dev_reset(struct input_dev *dev, bool activate)
1570{ 1569{
1571 if (!dev->event) 1570 if (!dev->event)
1572 return; 1571 return;
@@ -1580,12 +1579,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
1580 } 1579 }
1581} 1580}
1582 1581
1582/**
1583 * input_reset_device() - reset/restore the state of input device
1584 * @dev: input device whose state needs to be reset
1585 *
1586 * This function tries to reset the state of an opened input device and
1587 * bring internal state and state if the hardware in sync with each other.
1588 * We mark all keys as released, restore LED state, repeat rate, etc.
1589 */
1590void input_reset_device(struct input_dev *dev)
1591{
1592 mutex_lock(&dev->mutex);
1593
1594 if (dev->users) {
1595 input_dev_toggle(dev, true);
1596
1597 /*
1598 * Keys that have been pressed at suspend time are unlikely
1599 * to be still pressed when we resume.
1600 */
1601 spin_lock_irq(&dev->event_lock);
1602 input_dev_release_keys(dev);
1603 spin_unlock_irq(&dev->event_lock);
1604 }
1605
1606 mutex_unlock(&dev->mutex);
1607}
1608EXPORT_SYMBOL(input_reset_device);
1609
1610#ifdef CONFIG_PM
1583static int input_dev_suspend(struct device *dev) 1611static int input_dev_suspend(struct device *dev)
1584{ 1612{
1585 struct input_dev *input_dev = to_input_dev(dev); 1613 struct input_dev *input_dev = to_input_dev(dev);
1586 1614
1587 mutex_lock(&input_dev->mutex); 1615 mutex_lock(&input_dev->mutex);
1588 input_dev_reset(input_dev, false); 1616
1617 if (input_dev->users)
1618 input_dev_toggle(input_dev, false);
1619
1589 mutex_unlock(&input_dev->mutex); 1620 mutex_unlock(&input_dev->mutex);
1590 1621
1591 return 0; 1622 return 0;
@@ -1595,18 +1626,7 @@ static int input_dev_resume(struct device *dev)
1595{ 1626{
1596 struct input_dev *input_dev = to_input_dev(dev); 1627 struct input_dev *input_dev = to_input_dev(dev);
1597 1628
1598 mutex_lock(&input_dev->mutex); 1629 input_reset_device(input_dev);
1599 input_dev_reset(input_dev, true);
1600
1601 /*
1602 * Keys that have been pressed at suspend time are unlikely
1603 * to be still pressed when we resume.
1604 */
1605 spin_lock_irq(&input_dev->event_lock);
1606 input_dev_release_keys(input_dev);
1607 spin_unlock_irq(&input_dev->event_lock);
1608
1609 mutex_unlock(&input_dev->mutex);
1610 1630
1611 return 0; 1631 return 0;
1612} 1632}