其实问题很简单,就是GPIO-Key的驱动中需要的条件IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,但是MX28并不支持.修复方法很简单,主要有以下几步:
- irqflags判断方式修改.
- 修改IRQ触发方式,当进入IRQ事件时候,因为MX28不能同时具备两个方法,所以...
- 随时随地需要修改IRQ方式,所以应该独立成一个函数.
所以,最终补丁是如此的:
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index b8213fd..9138f13 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -340,6 +340,22 @@ static void gpio_keys_timer(unsigned long _data) schedule_work(&data->work); } +static void gpio_keys_update_trigger_type(int irq, struct gpio_button_data *bdata, struct gpio_keys_button *button) +{ + bool current_level; + bool level_for_trigger; + + /* Set new IRQ trigger type. Re-check after changing it, to deal with + * race conditions, i.e. the GPIO changing while we're changing trigger + * type. */ + current_level = gpio_get_value(button->gpio); + do { + level_for_trigger = current_level; + set_irq_type(irq, level_for_trigger ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING); + current_level = gpio_get_value(button->gpio); + } while (current_level != level_for_trigger); +} + static irqreturn_t gpio_keys_isr(int irq, void *dev_id) { struct gpio_button_data *bdata = dev_id; @@ -353,6 +369,8 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) else schedule_work(&bdata->work); + gpio_keys_update_trigger_type(irq, bdata, button); + return IRQ_HANDLED; } @@ -391,7 +409,8 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, goto fail3; } - irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + irqflags = button->active_low ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; + /* * If platform has specified that the button can be disabled, * we don't want it to share the interrupt line. @@ -405,6 +424,7 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, irq, error); goto fail3; } + gpio_keys_update_trigger_type(irq, bdata, button); return 0; -- 1.8.1.2