diff options
Diffstat (limited to 'drivers/input/keyboard/gpio_keys.c')
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 2157cd7de00c..efed0c9e242e 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -29,7 +29,8 @@ | |||
29 | struct gpio_button_data { | 29 | struct gpio_button_data { |
30 | struct gpio_keys_button *button; | 30 | struct gpio_keys_button *button; |
31 | struct input_dev *input; | 31 | struct input_dev *input; |
32 | struct delayed_work work; | 32 | struct timer_list timer; |
33 | struct work_struct work; | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct gpio_keys_drvdata { | 36 | struct gpio_keys_drvdata { |
@@ -40,7 +41,7 @@ struct gpio_keys_drvdata { | |||
40 | static void gpio_keys_report_event(struct work_struct *work) | 41 | static void gpio_keys_report_event(struct work_struct *work) |
41 | { | 42 | { |
42 | struct gpio_button_data *bdata = | 43 | struct gpio_button_data *bdata = |
43 | container_of(work, struct gpio_button_data, work.work); | 44 | container_of(work, struct gpio_button_data, work); |
44 | struct gpio_keys_button *button = bdata->button; | 45 | struct gpio_keys_button *button = bdata->button; |
45 | struct input_dev *input = bdata->input; | 46 | struct input_dev *input = bdata->input; |
46 | unsigned int type = button->type ?: EV_KEY; | 47 | unsigned int type = button->type ?: EV_KEY; |
@@ -50,17 +51,25 @@ static void gpio_keys_report_event(struct work_struct *work) | |||
50 | input_sync(input); | 51 | input_sync(input); |
51 | } | 52 | } |
52 | 53 | ||
54 | static void gpio_keys_timer(unsigned long _data) | ||
55 | { | ||
56 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | ||
57 | |||
58 | schedule_work(&data->work); | ||
59 | } | ||
60 | |||
53 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | 61 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) |
54 | { | 62 | { |
55 | struct gpio_button_data *bdata = dev_id; | 63 | struct gpio_button_data *bdata = dev_id; |
56 | struct gpio_keys_button *button = bdata->button; | 64 | struct gpio_keys_button *button = bdata->button; |
57 | unsigned long delay; | ||
58 | 65 | ||
59 | BUG_ON(irq != gpio_to_irq(button->gpio)); | 66 | BUG_ON(irq != gpio_to_irq(button->gpio)); |
60 | 67 | ||
61 | delay = button->debounce_interval ? | 68 | if (button->debounce_interval) |
62 | msecs_to_jiffies(button->debounce_interval) : 0; | 69 | mod_timer(&bdata->timer, |
63 | schedule_delayed_work(&bdata->work, delay); | 70 | jiffies + msecs_to_jiffies(button->debounce_interval)); |
71 | else | ||
72 | schedule_work(&bdata->work); | ||
64 | 73 | ||
65 | return IRQ_HANDLED; | 74 | return IRQ_HANDLED; |
66 | } | 75 | } |
@@ -107,7 +116,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
107 | 116 | ||
108 | bdata->input = input; | 117 | bdata->input = input; |
109 | bdata->button = button; | 118 | bdata->button = button; |
110 | INIT_DELAYED_WORK(&bdata->work, gpio_keys_report_event); | 119 | setup_timer(&bdata->timer, |
120 | gpio_keys_timer, (unsigned long)bdata); | ||
121 | INIT_WORK(&bdata->work, gpio_keys_report_event); | ||
111 | 122 | ||
112 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); | 123 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); |
113 | if (error < 0) { | 124 | if (error < 0) { |
@@ -166,7 +177,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
166 | fail2: | 177 | fail2: |
167 | while (--i >= 0) { | 178 | while (--i >= 0) { |
168 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 179 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
169 | cancel_delayed_work_sync(&ddata->data[i].work); | 180 | if (pdata->buttons[i].debounce_interval) |
181 | del_timer_sync(&ddata->data[i].timer); | ||
182 | cancel_work_sync(&ddata->data[i].work); | ||
170 | gpio_free(pdata->buttons[i].gpio); | 183 | gpio_free(pdata->buttons[i].gpio); |
171 | } | 184 | } |
172 | 185 | ||
@@ -190,7 +203,9 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
190 | for (i = 0; i < pdata->nbuttons; i++) { | 203 | for (i = 0; i < pdata->nbuttons; i++) { |
191 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 204 | int irq = gpio_to_irq(pdata->buttons[i].gpio); |
192 | free_irq(irq, &ddata->data[i]); | 205 | free_irq(irq, &ddata->data[i]); |
193 | cancel_delayed_work_sync(&ddata->data[i].work); | 206 | if (pdata->buttons[i].debounce_interval) |
207 | del_timer_sync(&ddata->data[i].timer); | ||
208 | cancel_work_sync(&ddata->data[i].work); | ||
194 | gpio_free(pdata->buttons[i].gpio); | 209 | gpio_free(pdata->buttons[i].gpio); |
195 | } | 210 | } |
196 | 211 | ||