Tested on Ka-Ro TX28 SOC Signed-off-by: Peter Rusko <rusko.peter@xxxxxxxxx> --- drivers/input/keyboard/matrix_keypad.c | 58 +++++++++---------------------- 1 files changed, 17 insertions(+), 41 deletions(-) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index e2ae657..c3d3532 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -33,7 +33,6 @@ struct matrix_keypad { 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; @@ -112,15 +111,16 @@ static void disable_row_irqs(struct matrix_keypad *keypad) /* * This gets the keys from keyboard and reports it to input subsystem */ -static void matrix_keypad_scan(struct work_struct *work) +static irqreturn_t matrix_keypad_scan(int irq, void *id) { - struct matrix_keypad *keypad = - container_of(work, struct matrix_keypad, work.work); + struct matrix_keypad *keypad = id; struct input_dev *input_dev = keypad->input_dev; const struct matrix_keypad_platform_data *pdata = keypad->pdata; uint32_t new_state[MATRIX_MAX_COLS]; int row, col, code; + msleep(keypad->pdata->debounce_ms); + /* de-activate all columns for scanning */ activate_all_cols(pdata, false); @@ -165,32 +165,8 @@ static void matrix_keypad_scan(struct work_struct *work) /* Enable IRQs again */ spin_lock_irq(&keypad->lock); keypad->scan_pending = false; - enable_row_irqs(keypad); spin_unlock_irq(&keypad->lock); -} - -static irqreturn_t matrix_keypad_interrupt(int irq, void *id) -{ - struct matrix_keypad *keypad = id; - unsigned long flags; - - spin_lock_irqsave(&keypad->lock, flags); - /* - * See if another IRQ beaten us to it and scheduled the - * scan already. In that case we should not try to - * disable IRQs again. - */ - if (unlikely(keypad->scan_pending || keypad->stopped)) - goto out; - - disable_row_irqs(keypad); - keypad->scan_pending = true; - schedule_delayed_work(&keypad->work, - msecs_to_jiffies(keypad->pdata->debounce_ms)); - -out: - spin_unlock_irqrestore(&keypad->lock, flags); return IRQ_HANDLED; } @@ -201,11 +177,8 @@ static int matrix_keypad_start(struct input_dev *dev) keypad->stopped = false; mb(); - /* - * Schedule an immediate key scan to capture current key state; - * columns will be activated and IRQs be enabled after the scan. - */ - schedule_delayed_work(&keypad->work, 0); + matrix_keypad_scan(0, keypad); + enable_row_irqs(keypad); return 0; } @@ -216,7 +189,6 @@ static void matrix_keypad_stop(struct input_dev *dev) keypad->stopped = true; mb(); - flush_work(&keypad->work.work); /* * matrix_keypad_scan() will leave IRQs enabled; * we should disable them now. @@ -330,9 +302,11 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev, } if (pdata->clustered_irq > 0) { - err = request_irq(pdata->clustered_irq, - matrix_keypad_interrupt, - pdata->clustered_irq_flags, + err = request_threaded_irq(pdata->clustered_irq, + NULL, + matrix_keypad_scan, + pdata->clustered_irq_flags | + IRQF_ONESHOT, "matrix-keypad", keypad); if (err) { dev_err(&pdev->dev, @@ -341,10 +315,13 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev, } } else { for (i = 0; i < pdata->num_row_gpios; i++) { - err = request_irq(gpio_to_irq(pdata->row_gpios[i]), - matrix_keypad_interrupt, + err = request_threaded_irq( + gpio_to_irq(pdata->row_gpios[i]), + NULL, + matrix_keypad_scan, IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, "matrix-keypad", keypad); if (err) { dev_err(&pdev->dev, @@ -414,7 +391,6 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) keypad->keycodes = keycodes; keypad->row_shift = row_shift; keypad->stopped = true; - INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); spin_lock_init(&keypad->lock); input_dev->name = pdev->name; -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html