aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-03-17 01:11:08 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-03-17 02:29:12 -0400
commit80cc2f0c928ddf58051f2809e1c2e7d0172d0291 (patch)
tree8e14bc4601b5584711490c4a36d94ec1a44afbdd /drivers/input/touchscreen
parent9a6e180af78247e3a7680460240bb450c39d3a5b (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.c58
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)
239static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) 239static 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
305out: 308out:
306 mutex_unlock(&ts->mutex); 309 mutex_unlock(&ts->mutex);
@@ -310,17 +313,11 @@ out:
310static void tsc2005_penup_timer(unsigned long data) 313static 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
317static 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
326static void tsc2005_start_scan(struct tsc2005 *ts) 323static 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);