diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-06-30 04:40:52 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-06-30 18:08:09 -0400 |
commit | 7cd7a82d16ad5a711338c1baf2316f24121d93aa (patch) | |
tree | a23145ef643a5cc9d11e78b74dd3bf51bc511d5a /drivers/input | |
parent | 08fa16b6b75005c120b59d00ae42a0b7cc68db45 (diff) |
Input: ad7879 - use threaded IRQ
Tested-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/touchscreen/ad7879.c | 36 |
1 files changed, 9 insertions, 27 deletions
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index 4b32fb4704cd..f947457c858b 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/interrupt.h> | 44 | #include <linux/interrupt.h> |
45 | #include <linux/irq.h> | 45 | #include <linux/irq.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/workqueue.h> | ||
48 | #include <linux/spi/spi.h> | 47 | #include <linux/spi/spi.h> |
49 | #include <linux/i2c.h> | 48 | #include <linux/i2c.h> |
50 | #include <linux/gpio.h> | 49 | #include <linux/gpio.h> |
@@ -131,13 +130,12 @@ typedef struct i2c_client bus_device; | |||
131 | struct ad7879 { | 130 | struct ad7879 { |
132 | bus_device *bus; | 131 | bus_device *bus; |
133 | struct input_dev *input; | 132 | struct input_dev *input; |
134 | struct work_struct work; | ||
135 | struct timer_list timer; | 133 | struct timer_list timer; |
136 | #ifdef CONFIG_GPIOLIB | 134 | #ifdef CONFIG_GPIOLIB |
137 | struct gpio_chip gc; | 135 | struct gpio_chip gc; |
138 | #endif | 136 | #endif |
139 | struct mutex mutex; | 137 | struct mutex mutex; |
140 | unsigned disabled:1; /* P: mutex */ | 138 | bool disabled; /* P: mutex */ |
141 | 139 | ||
142 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) | 140 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) |
143 | struct spi_message msg; | 141 | struct spi_message msg; |
@@ -196,16 +194,6 @@ static void ad7879_report(struct ad7879 *ts) | |||
196 | } | 194 | } |
197 | } | 195 | } |
198 | 196 | ||
199 | static void ad7879_work(struct work_struct *work) | ||
200 | { | ||
201 | struct ad7879 *ts = container_of(work, struct ad7879, work); | ||
202 | |||
203 | /* use keventd context to read the result registers */ | ||
204 | ad7879_collect(ts); | ||
205 | ad7879_report(ts); | ||
206 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
207 | } | ||
208 | |||
209 | static void ad7879_ts_event_release(struct ad7879 *ts) | 197 | static void ad7879_ts_event_release(struct ad7879 *ts) |
210 | { | 198 | { |
211 | struct input_dev *input_dev = ts->input; | 199 | struct input_dev *input_dev = ts->input; |
@@ -225,13 +213,10 @@ static irqreturn_t ad7879_irq(int irq, void *handle) | |||
225 | { | 213 | { |
226 | struct ad7879 *ts = handle; | 214 | struct ad7879 *ts = handle; |
227 | 215 | ||
228 | /* The repeated conversion sequencer controlled by TMR kicked off too fast. | 216 | ad7879_collect(ts); |
229 | * We ignore the last and process the sample sequence currently in the queue. | 217 | ad7879_report(ts); |
230 | * It can't be older than 9.4ms | ||
231 | */ | ||
232 | 218 | ||
233 | if (!work_pending(&ts->work)) | 219 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); |
234 | schedule_work(&ts->work); | ||
235 | 220 | ||
236 | return IRQ_HANDLED; | 221 | return IRQ_HANDLED; |
237 | } | 222 | } |
@@ -249,11 +234,9 @@ static void ad7879_disable(struct ad7879 *ts) | |||
249 | 234 | ||
250 | if (!ts->disabled) { | 235 | if (!ts->disabled) { |
251 | 236 | ||
252 | ts->disabled = 1; | 237 | ts->disabled = true; |
253 | disable_irq(ts->bus->irq); | 238 | disable_irq(ts->bus->irq); |
254 | 239 | ||
255 | cancel_work_sync(&ts->work); | ||
256 | |||
257 | if (del_timer_sync(&ts->timer)) | 240 | if (del_timer_sync(&ts->timer)) |
258 | ad7879_ts_event_release(ts); | 241 | ad7879_ts_event_release(ts); |
259 | 242 | ||
@@ -270,7 +253,7 @@ static void ad7879_enable(struct ad7879 *ts) | |||
270 | 253 | ||
271 | if (ts->disabled) { | 254 | if (ts->disabled) { |
272 | ad7879_setup(ts); | 255 | ad7879_setup(ts); |
273 | ts->disabled = 0; | 256 | ts->disabled = false; |
274 | enable_irq(ts->bus->irq); | 257 | enable_irq(ts->bus->irq); |
275 | } | 258 | } |
276 | 259 | ||
@@ -458,7 +441,6 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
458 | ts->input = input_dev; | 441 | ts->input = input_dev; |
459 | 442 | ||
460 | setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); | 443 | setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); |
461 | INIT_WORK(&ts->work, ad7879_work); | ||
462 | mutex_init(&ts->mutex); | 444 | mutex_init(&ts->mutex); |
463 | 445 | ||
464 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | 446 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
@@ -526,9 +508,9 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
526 | 508 | ||
527 | ad7879_setup(ts); | 509 | ad7879_setup(ts); |
528 | 510 | ||
529 | err = request_irq(bus->irq, ad7879_irq, | 511 | err = request_threaded_irq(bus->irq, NULL, ad7879_irq, |
530 | IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts); | 512 | IRQF_TRIGGER_FALLING, |
531 | 513 | bus->dev.driver->name, ts); | |
532 | if (err) { | 514 | if (err) { |
533 | dev_err(&bus->dev, "irq %d busy?\n", bus->irq); | 515 | dev_err(&bus->dev, "irq %d busy?\n", bus->irq); |
534 | goto err_free_mem; | 516 | goto err_free_mem; |