aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-12-25 01:50:23 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-12-25 01:50:55 -0500
commitdd219234d201431d0fc56a74e3a4a97ca3eb4589 (patch)
treefa35dc4e073a027c97e18bc8463037d63f1fc2a3
parent98b7fb0472f828536a7786df6bd517322c0c17dc (diff)
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 <pavel@ucw.cz> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/keyboard/matrix_keypad.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 34f4a29d4973..d3c8b61a941d 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -29,11 +29,13 @@ struct matrix_keypad {
29 unsigned short *keycodes; 29 unsigned short *keycodes;
30 unsigned int row_shift; 30 unsigned int row_shift;
31 31
32 DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
33
32 uint32_t last_key_state[MATRIX_MAX_COLS]; 34 uint32_t last_key_state[MATRIX_MAX_COLS];
33 struct delayed_work work; 35 struct delayed_work work;
36 spinlock_t lock;
34 bool scan_pending; 37 bool scan_pending;
35 bool stopped; 38 bool stopped;
36 spinlock_t lock;
37}; 39};
38 40
39/* 41/*
@@ -222,9 +224,16 @@ static int matrix_keypad_suspend(struct device *dev)
222 224
223 matrix_keypad_stop(keypad->input_dev); 225 matrix_keypad_stop(keypad->input_dev);
224 226
225 if (device_may_wakeup(&pdev->dev)) 227 if (device_may_wakeup(&pdev->dev)) {
226 for (i = 0; i < pdata->num_row_gpios; i++) 228 for (i = 0; i < pdata->num_row_gpios; i++) {
227 enable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); 229 if (!test_bit(i, keypad->disabled_gpios)) {
230 unsigned int gpio = pdata->row_gpios[i];
231
232 if (enable_irq_wake(gpio_to_irq(gpio)) == 0)
233 __set_bit(i, keypad->disabled_gpios);
234 }
235 }
236 }
228 237
229 return 0; 238 return 0;
230} 239}
@@ -236,9 +245,15 @@ static int matrix_keypad_resume(struct device *dev)
236 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 245 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
237 int i; 246 int i;
238 247
239 if (device_may_wakeup(&pdev->dev)) 248 if (device_may_wakeup(&pdev->dev)) {
240 for (i = 0; i < pdata->num_row_gpios; i++) 249 for (i = 0; i < pdata->num_row_gpios; i++) {
241 disable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); 250 if (test_and_clear_bit(i, keypad->disabled_gpios)) {
251 unsigned int gpio = pdata->row_gpios[i];
252
253 disable_irq_wake(gpio_to_irq(gpio));
254 }
255 }
256 }
242 257
243 matrix_keypad_start(keypad->input_dev); 258 matrix_keypad_start(keypad->input_dev);
244 259