Commit dd219234 authored by Dmitry Torokhov's avatar Dmitry Torokhov

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: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 98b7fb04
...@@ -29,11 +29,13 @@ struct matrix_keypad { ...@@ -29,11 +29,13 @@ struct matrix_keypad {
unsigned short *keycodes; unsigned short *keycodes;
unsigned int row_shift; unsigned int row_shift;
DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
uint32_t last_key_state[MATRIX_MAX_COLS]; uint32_t last_key_state[MATRIX_MAX_COLS];
struct delayed_work work; struct delayed_work work;
spinlock_t lock;
bool scan_pending; bool scan_pending;
bool stopped; bool stopped;
spinlock_t lock;
}; };
/* /*
...@@ -222,9 +224,16 @@ static int matrix_keypad_suspend(struct device *dev) ...@@ -222,9 +224,16 @@ static int matrix_keypad_suspend(struct device *dev)
matrix_keypad_stop(keypad->input_dev); matrix_keypad_stop(keypad->input_dev);
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->num_row_gpios; i++) for (i = 0; i < pdata->num_row_gpios; i++) {
enable_irq_wake(gpio_to_irq(pdata->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; return 0;
} }
...@@ -236,9 +245,15 @@ static int matrix_keypad_resume(struct device *dev) ...@@ -236,9 +245,15 @@ static int matrix_keypad_resume(struct device *dev)
const struct matrix_keypad_platform_data *pdata = keypad->pdata; const struct matrix_keypad_platform_data *pdata = keypad->pdata;
int i; int i;
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->num_row_gpios; i++) for (i = 0; i < pdata->num_row_gpios; i++) {
disable_irq_wake(gpio_to_irq(pdata->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); matrix_keypad_start(keypad->input_dev);
......
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