From 4a299bf591bc5bef3bde8316e603b9eaec5a7696 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 21:40:24 -0800 Subject: Input: speed up suspend/shutdown for PS/2 mice and keyboards Instead of doing full-blown reset while suspending or shutting down the box use lighter form of reset that should take less time. Tested-by: Alan Stern Tested-by: Rafael J. Wysocki Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index a3573570c52..1f5e2ce327d 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -134,7 +134,8 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_CMD_GETID 0x02f2 #define ATKBD_CMD_SETREP 0x10f3 #define ATKBD_CMD_ENABLE 0x00f4 -#define ATKBD_CMD_RESET_DIS 0x00f5 +#define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ +#define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ #define ATKBD_CMD_SETALL_MBR 0x00fa #define ATKBD_CMD_RESET_BAT 0x02ff #define ATKBD_CMD_RESEND 0x00fe @@ -836,7 +837,7 @@ static void atkbd_cleanup(struct serio *serio) struct atkbd *atkbd = serio_get_drvdata(serio); atkbd_disable(atkbd); - ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT); + ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF); } -- cgit v1.2.3 From dd219234d201431d0fc56a74e3a4a97ca3eb4589 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 22:50:23 -0800 Subject: Input: matrix-keypad - handle cases when GPIOs can't be wakeup sources On certain boards not all GPIOs may be used as wakeup sources, in which case some of enable_irq_wake() calls will fail. On resume calling disable_irq_wake() will warn about unbalanced IRQ wake disable. Solve this by checking whether enable_irq_wake() succeeded or not and no not call disable_irq_wake() for these GPIOs/IRQs that have not been enabled. Reported-by: Pavel Machek Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/matrix_keypad.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 34f4a29d497..d3c8b61a941 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -29,11 +29,13 @@ struct matrix_keypad { unsigned short *keycodes; unsigned int row_shift; + DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); + uint32_t last_key_state[MATRIX_MAX_COLS]; struct delayed_work work; + spinlock_t lock; bool scan_pending; bool stopped; - spinlock_t lock; }; /* @@ -222,9 +224,16 @@ static int matrix_keypad_suspend(struct device *dev) matrix_keypad_stop(keypad->input_dev); - if (device_may_wakeup(&pdev->dev)) - for (i = 0; i < pdata->num_row_gpios; i++) - enable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); + if (device_may_wakeup(&pdev->dev)) { + for (i = 0; i < pdata->num_row_gpios; i++) { + if (!test_bit(i, keypad->disabled_gpios)) { + unsigned int gpio = pdata->row_gpios[i]; + + if (enable_irq_wake(gpio_to_irq(gpio)) == 0) + __set_bit(i, keypad->disabled_gpios); + } + } + } return 0; } @@ -236,9 +245,15 @@ static int matrix_keypad_resume(struct device *dev) const struct matrix_keypad_platform_data *pdata = keypad->pdata; int i; - if (device_may_wakeup(&pdev->dev)) - for (i = 0; i < pdata->num_row_gpios; i++) - disable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); + if (device_may_wakeup(&pdev->dev)) { + for (i = 0; i < pdata->num_row_gpios; i++) { + if (test_and_clear_bit(i, keypad->disabled_gpios)) { + unsigned int gpio = pdata->row_gpios[i]; + + disable_irq_wake(gpio_to_irq(gpio)); + } + } + } matrix_keypad_start(keypad->input_dev); -- cgit v1.2.3 From 3f58061d0160424d244e3a72258a1366ab4a8547 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 29 Dec 2009 23:15:51 -0800 Subject: Input: twl4030_keypad - switch to using threaded IRQ Signed-off-by: Felipe Balbi Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/twl4030_keypad.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index eeaa7acb9cf..21d6184efa9 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -253,14 +253,6 @@ static irqreturn_t do_kp_irq(int irq, void *_kp) u8 reg; int ret; -#ifdef CONFIG_LOCKDEP - /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which - * we don't want and can't tolerate. Although it might be - * friendlier not to borrow this thread context... - */ - local_irq_enable(); -#endif - /* Read & Clear TWL4030 pending interrupt */ ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); @@ -403,7 +395,8 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) * * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... */ - error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp); + error = request_threaded_irq(kp->irq, NULL, do_kp_irq, + 0, pdev->name, kp); if (error) { dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", kp->irq); -- cgit v1.2.3