其实问题很简单,就是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