From: Darius Augulis <augulis.darius@xxxxxxxxx> Support for such GPIO controllers, which can't trigger on both edges at once. Signed-off-by: Darius Augulis <augulis.darius@xxxxxxxxx> Index: linux-2.6.29-rc5/drivers/input/keyboard/gpio_keys.c =================================================================== --- linux-2.6.29-rc5.orig/drivers/input/keyboard/gpio_keys.c +++ linux-2.6.29-rc5/drivers/input/keyboard/gpio_keys.c @@ -43,8 +43,15 @@ static void gpio_keys_report_event(struc unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; + printk("GPIO=%d\n", state); + input_event(input, type, button->code, !!state); input_sync(input); + + if (button->single_edge) { + input_event(input, type, button->code, !state); + input_sync(input); + } } static void gpio_check_button(unsigned long _data) @@ -77,6 +84,7 @@ static int __devinit gpio_keys_probe(str struct input_dev *input; int i, error; int wakeup = 0; + unsigned long irq_flags; ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + pdata->nbuttons * sizeof(struct gpio_button_data), @@ -141,9 +149,13 @@ static int __devinit gpio_keys_probe(str goto fail2; } - error = request_irq(irq, gpio_keys_isr, - IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, + irq_flags = IRQF_SAMPLE_RANDOM; + if (button->single_edge) + irq_flags |= (button->active_low ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING); + else + irq_flags |= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + + error = request_irq(irq, gpio_keys_isr, irq_flags, button->desc ? button->desc : "gpio_keys", bdata); if (error) { Index: linux-2.6.29-rc5/include/linux/gpio_keys.h =================================================================== --- linux-2.6.29-rc5.orig/include/linux/gpio_keys.h +++ linux-2.6.29-rc5/include/linux/gpio_keys.h @@ -6,6 +6,7 @@ struct gpio_keys_button { int code; /* input event code (KEY_*, SW_*) */ int gpio; int active_low; + int single_edge; /* Trigger only single egde (0-no, 1-yes) */ char *desc; int type; /* input event type (EV_KEY, EV_SW) */ int wakeup; /* configure the button as a wake-up source */