diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-17 01:11:08 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-17 02:29:12 -0400 |
commit | 80cc2f0c928ddf58051f2809e1c2e7d0172d0291 (patch) | |
tree | 8e14bc4601b5584711490c4a36d94ec1a44afbdd /drivers/input/touchscreen | |
parent | 9a6e180af78247e3a7680460240bb450c39d3a5b (diff) |
Input: tsc2005 - don't use work for 'pen up' handling
We do not need process context to send input events so let's switch to
a regular timer. I am going to get rid of taking ts->mutex in
tsc2005_irq_thread() later.
Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/tsc2005.c | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 289057e1b9a..dc309da59fc 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c | |||
@@ -129,8 +129,8 @@ struct tsc2005 { | |||
129 | int in_z1; | 129 | int in_z1; |
130 | int in_z2; | 130 | int in_z2; |
131 | 131 | ||
132 | spinlock_t lock; | ||
132 | struct timer_list penup_timer; | 133 | struct timer_list penup_timer; |
133 | struct work_struct penup_work; | ||
134 | 134 | ||
135 | unsigned int esd_timeout; | 135 | unsigned int esd_timeout; |
136 | struct timer_list esd_timer; | 136 | struct timer_list esd_timer; |
@@ -239,11 +239,10 @@ static irqreturn_t tsc2005_irq_handler(int irq, void *dev_id) | |||
239 | static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) | 239 | static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) |
240 | { | 240 | { |
241 | struct tsc2005 *ts = _ts; | 241 | struct tsc2005 *ts = _ts; |
242 | unsigned long flags; | ||
242 | unsigned int pressure; | 243 | unsigned int pressure; |
243 | u32 x; | 244 | u32 x, y; |
244 | u32 y; | 245 | u32 z1, z2; |
245 | u32 z1; | ||
246 | u32 z2; | ||
247 | 246 | ||
248 | mutex_lock(&ts->mutex); | 247 | mutex_lock(&ts->mutex); |
249 | 248 | ||
@@ -261,46 +260,50 @@ static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) | |||
261 | if (unlikely(x > MAX_12BIT || y > MAX_12BIT)) | 260 | if (unlikely(x > MAX_12BIT || y > MAX_12BIT)) |
262 | goto out; | 261 | goto out; |
263 | 262 | ||
264 | /* skip coords if the pressure components are out of range */ | 263 | /* Skip reading if the pressure components are out of range */ |
265 | if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2)) | 264 | if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2)) |
266 | goto out; | 265 | goto out; |
267 | 266 | ||
268 | /* skip point if this is a pen down with the exact same values as | 267 | /* |
268 | * Skip point if this is a pen down with the exact same values as | ||
269 | * the value before pen-up - that implies SPI fed us stale data | 269 | * the value before pen-up - that implies SPI fed us stale data |
270 | */ | 270 | */ |
271 | if (!ts->pen_down && | 271 | if (!ts->pen_down && |
272 | ts->in_x == x && | 272 | ts->in_x == x && ts->in_y == y && |
273 | ts->in_y == y && | 273 | ts->in_z1 == z1 && ts->in_z2 == z2) { |
274 | ts->in_z1 == z1 && | ||
275 | ts->in_z2 == z2) | ||
276 | goto out; | 274 | goto out; |
275 | } | ||
277 | 276 | ||
278 | /* At this point we are happy we have a valid and useful reading. | 277 | /* |
279 | * Remember it for later comparisons. We may now begin downsampling | 278 | * At this point we are happy we have a valid and useful reading. |
280 | */ | 279 | * Remember it for later comparisons. We may now begin downsampling. |
280 | */ | ||
281 | ts->in_x = x; | 281 | ts->in_x = x; |
282 | ts->in_y = y; | 282 | ts->in_y = y; |
283 | ts->in_z1 = z1; | 283 | ts->in_z1 = z1; |
284 | ts->in_z2 = z2; | 284 | ts->in_z2 = z2; |
285 | 285 | ||
286 | /* compute touch pressure resistance using equation #1 */ | 286 | /* Compute touch pressure resistance using equation #1 */ |
287 | pressure = x * (z2 - z1) / z1; | 287 | pressure = x * (z2 - z1) / z1; |
288 | pressure = pressure * ts->x_plate_ohm / 4096; | 288 | pressure = pressure * ts->x_plate_ohm / 4096; |
289 | if (unlikely(pressure > MAX_12BIT)) | 289 | if (unlikely(pressure > MAX_12BIT)) |
290 | goto out; | 290 | goto out; |
291 | 291 | ||
292 | spin_lock_irqsave(&ts->lock, flags); | ||
293 | |||
292 | tsc2005_update_pen_state(ts, x, y, pressure); | 294 | tsc2005_update_pen_state(ts, x, y, pressure); |
293 | 295 | ||
294 | /* set the penup timer */ | 296 | /* set the penup timer */ |
295 | mod_timer(&ts->penup_timer, | 297 | mod_timer(&ts->penup_timer, |
296 | jiffies + msecs_to_jiffies(TSC2005_PENUP_TIME_MS)); | 298 | jiffies + msecs_to_jiffies(TSC2005_PENUP_TIME_MS)); |
297 | 299 | ||
298 | if (!ts->esd_timeout) | 300 | if (ts->esd_timeout && ts->set_reset) { |
299 | goto out; | 301 | /* update the watchdog timer */ |
302 | mod_timer(&ts->esd_timer, round_jiffies(jiffies + | ||
303 | msecs_to_jiffies(ts->esd_timeout))); | ||
304 | } | ||
300 | 305 | ||
301 | /* update the watchdog timer */ | 306 | spin_unlock_irqrestore(&ts->lock, flags); |
302 | mod_timer(&ts->esd_timer, | ||
303 | round_jiffies(jiffies + msecs_to_jiffies(ts->esd_timeout))); | ||
304 | 307 | ||
305 | out: | 308 | out: |
306 | mutex_unlock(&ts->mutex); | 309 | mutex_unlock(&ts->mutex); |
@@ -310,17 +313,11 @@ out: | |||
310 | static void tsc2005_penup_timer(unsigned long data) | 313 | static void tsc2005_penup_timer(unsigned long data) |
311 | { | 314 | { |
312 | struct tsc2005 *ts = (struct tsc2005 *)data; | 315 | struct tsc2005 *ts = (struct tsc2005 *)data; |
316 | unsigned long flags; | ||
313 | 317 | ||
314 | schedule_work(&ts->penup_work); | 318 | spin_lock_irqsave(&ts->lock, flags); |
315 | } | ||
316 | |||
317 | static void tsc2005_penup_work(struct work_struct *work) | ||
318 | { | ||
319 | struct tsc2005 *ts = container_of(work, struct tsc2005, penup_work); | ||
320 | |||
321 | mutex_lock(&ts->mutex); | ||
322 | tsc2005_update_pen_state(ts, 0, 0, 0); | 319 | tsc2005_update_pen_state(ts, 0, 0, 0); |
323 | mutex_unlock(&ts->mutex); | 320 | spin_unlock_irqrestore(&ts->lock, flags); |
324 | } | 321 | } |
325 | 322 | ||
326 | static void tsc2005_start_scan(struct tsc2005 *ts) | 323 | static void tsc2005_start_scan(struct tsc2005 *ts) |
@@ -577,8 +574,8 @@ static int __devinit tsc2005_probe(struct spi_device *spi) | |||
577 | 574 | ||
578 | mutex_init(&ts->mutex); | 575 | mutex_init(&ts->mutex); |
579 | 576 | ||
577 | spin_lock_init(&ts->lock); | ||
580 | setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts); | 578 | setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts); |
581 | INIT_WORK(&ts->penup_work, tsc2005_penup_work); | ||
582 | 579 | ||
583 | setup_timer(&ts->esd_timer, tsc2005_esd_timer, (unsigned long)ts); | 580 | setup_timer(&ts->esd_timer, tsc2005_esd_timer, (unsigned long)ts); |
584 | INIT_WORK(&ts->esd_work, tsc2005_esd_work); | 581 | INIT_WORK(&ts->esd_work, tsc2005_esd_work); |
@@ -659,7 +656,6 @@ static int __devexit tsc2005_remove(struct spi_device *spi) | |||
659 | del_timer_sync(&ts->penup_timer); | 656 | del_timer_sync(&ts->penup_timer); |
660 | 657 | ||
661 | flush_work(&ts->esd_work); | 658 | flush_work(&ts->esd_work); |
662 | flush_work(&ts->penup_work); | ||
663 | 659 | ||
664 | free_irq(ts->spi->irq, ts); | 660 | free_irq(ts->spi->irq, ts); |
665 | input_unregister_device(ts->idev); | 661 | input_unregister_device(ts->idev); |