Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: nomadik-ske-keypad - get rid of multiple interrupts

The keypad could cause multiple interrupts to be fired in succession
since we weren't waiting for the IRQs to clear properly in the
interrupt handler. We wait for a number of bus iterations (the
readl():s from the peripheral bus will stall, so these are quite
long) before giving up on getting keys ready to read, then we
sleep until the IRQ is deasserted (this is OK since the interrupt
is threaded). Also use the debounce platform data for another
hardcoded wait loop.

Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
Reviewed-by: Rikard Olsson <rikard.p.olsson@stericsson.com>
Reviewed-by: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Naveen Kumar Gaddipati and committed by
Dmitry Torokhov
84b63ad8 af77c88b

+8 -3
+8 -3
drivers/input/keyboard/nomadik-ske-keypad.c
··· 49 49 #define SKE_ASR3 0x2C 50 50 51 51 #define SKE_NUM_ASRX_REGISTERS (4) 52 + #define KEY_PRESSED_DELAY 10 52 53 53 54 /** 54 55 * struct ske_keypad - data structure used by keypad driver ··· 93 92 static int __init ske_keypad_chip_init(struct ske_keypad *keypad) 94 93 { 95 94 u32 value; 96 - int timeout = 50; 95 + int timeout = keypad->board->debounce_ms; 97 96 98 97 /* check SKE_RIS to be 0 */ 99 98 while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--) ··· 197 196 static irqreturn_t ske_keypad_irq(int irq, void *dev_id) 198 197 { 199 198 struct ske_keypad *keypad = dev_id; 200 - int retries = 20; 199 + int timeout = keypad->board->debounce_ms; 201 200 202 201 /* disable auto scan interrupt; mask the interrupt generated */ 203 202 ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); 204 203 ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); 205 204 206 - while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) 205 + while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --timeout) 207 206 cpu_relax(); 208 207 209 208 /* SKEx registers are stable and can be read */ 210 209 ske_keypad_read_data(keypad); 210 + 211 + /* wait until raw interrupt is clear */ 212 + while ((readl(keypad->reg_base + SKE_RIS)) && --timeout) 213 + msleep(KEY_PRESSED_DELAY); 211 214 212 215 /* enable auto scan interrupts */ 213 216 ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);