aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/gpio_keys.c
diff options
context:
space:
mode:
authorJani Nikula <ext-jani.1.nikula@nokia.com>2009-06-29 01:38:44 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-06-29 02:58:17 -0400
commitca865a77b5949f5c403e0f13de5a5a9cd499a11e (patch)
tree567ebe13fe9800a4a7d6584af4ba012e9472bb91 /drivers/input/keyboard/gpio_keys.c
parent00b8ac409cad653137f087e3ff69c020174cbc15 (diff)
Input: gpio-keys - revert 'change timer to workqueue'
This reverts commit 0b346838c5862bfe911432956a106d602535d030. This commit breaks GPIO debouncing by replacing the original mod_timer with schedule_delayed_work in the interrupt handler. The latter does not kick the timer further on GPIO line changes as it should to perform debouncing. Signed-off-by: Jani Nikula <ext-jani.1.nikula@nokia.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard/gpio_keys.c')
-rw-r--r--drivers/input/keyboard/gpio_keys.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 2157cd7de00c..9767213b6c8f 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -22,14 +22,13 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/input.h> 23#include <linux/input.h>
24#include <linux/gpio_keys.h> 24#include <linux/gpio_keys.h>
25#include <linux/workqueue.h>
26 25
27#include <asm/gpio.h> 26#include <asm/gpio.h>
28 27
29struct gpio_button_data { 28struct gpio_button_data {
30 struct gpio_keys_button *button; 29 struct gpio_keys_button *button;
31 struct input_dev *input; 30 struct input_dev *input;
32 struct delayed_work work; 31 struct timer_list timer;
33}; 32};
34 33
35struct gpio_keys_drvdata { 34struct gpio_keys_drvdata {
@@ -37,10 +36,8 @@ struct gpio_keys_drvdata {
37 struct gpio_button_data data[0]; 36 struct gpio_button_data data[0];
38}; 37};
39 38
40static void gpio_keys_report_event(struct work_struct *work) 39static void gpio_keys_report_event(struct gpio_button_data *bdata)
41{ 40{
42 struct gpio_button_data *bdata =
43 container_of(work, struct gpio_button_data, work.work);
44 struct gpio_keys_button *button = bdata->button; 41 struct gpio_keys_button *button = bdata->button;
45 struct input_dev *input = bdata->input; 42 struct input_dev *input = bdata->input;
46 unsigned int type = button->type ?: EV_KEY; 43 unsigned int type = button->type ?: EV_KEY;
@@ -50,17 +47,25 @@ static void gpio_keys_report_event(struct work_struct *work)
50 input_sync(input); 47 input_sync(input);
51} 48}
52 49
50static void gpio_check_button(unsigned long _data)
51{
52 struct gpio_button_data *data = (struct gpio_button_data *)_data;
53
54 gpio_keys_report_event(data);
55}
56
53static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 57static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
54{ 58{
55 struct gpio_button_data *bdata = dev_id; 59 struct gpio_button_data *bdata = dev_id;
56 struct gpio_keys_button *button = bdata->button; 60 struct gpio_keys_button *button = bdata->button;
57 unsigned long delay;
58 61
59 BUG_ON(irq != gpio_to_irq(button->gpio)); 62 BUG_ON(irq != gpio_to_irq(button->gpio));
60 63
61 delay = button->debounce_interval ? 64 if (button->debounce_interval)
62 msecs_to_jiffies(button->debounce_interval) : 0; 65 mod_timer(&bdata->timer,
63 schedule_delayed_work(&bdata->work, delay); 66 jiffies + msecs_to_jiffies(button->debounce_interval));
67 else
68 gpio_keys_report_event(bdata);
64 69
65 return IRQ_HANDLED; 70 return IRQ_HANDLED;
66} 71}
@@ -107,7 +112,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
107 112
108 bdata->input = input; 113 bdata->input = input;
109 bdata->button = button; 114 bdata->button = button;
110 INIT_DELAYED_WORK(&bdata->work, gpio_keys_report_event); 115 setup_timer(&bdata->timer,
116 gpio_check_button, (unsigned long)bdata);
111 117
112 error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); 118 error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
113 if (error < 0) { 119 if (error < 0) {
@@ -166,7 +172,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
166 fail2: 172 fail2:
167 while (--i >= 0) { 173 while (--i >= 0) {
168 free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); 174 free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
169 cancel_delayed_work_sync(&ddata->data[i].work); 175 if (pdata->buttons[i].debounce_interval)
176 del_timer_sync(&ddata->data[i].timer);
170 gpio_free(pdata->buttons[i].gpio); 177 gpio_free(pdata->buttons[i].gpio);
171 } 178 }
172 179
@@ -190,7 +197,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
190 for (i = 0; i < pdata->nbuttons; i++) { 197 for (i = 0; i < pdata->nbuttons; i++) {
191 int irq = gpio_to_irq(pdata->buttons[i].gpio); 198 int irq = gpio_to_irq(pdata->buttons[i].gpio);
192 free_irq(irq, &ddata->data[i]); 199 free_irq(irq, &ddata->data[i]);
193 cancel_delayed_work_sync(&ddata->data[i].work); 200 if (pdata->buttons[i].debounce_interval)
201 del_timer_sync(&ddata->data[i].timer);
194 gpio_free(pdata->buttons[i].gpio); 202 gpio_free(pdata->buttons[i].gpio);
195 } 203 }
196 204