Skip to content

Commit

Permalink
Input: matrix-keypad - handle cases when GPIOs can't be wakeup sources
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dmitry Torokhov committed Dec 25, 2009
1 parent 98b7fb0 commit dd21923
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions drivers/input/keyboard/matrix_keypad.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/*
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);

Expand Down

0 comments on commit dd21923

Please sign in to comment.