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>
This commit is contained in:
Родитель
98b7fb0472
Коммит
dd219234d2
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
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);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче