aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-10-18 12:24:22 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-10-18 12:35:13 -0400
commitb534422b2d1189740c6144c3c7a296be89f581c7 (patch)
tree6c0afd800547209aa715be93216bf2b0cdd1c109 /drivers/input
parent2fd18abad179b11cbd881f2bd271b193ababfb65 (diff)
Input: ad7877 - switch to using threaded IRQ
Instead of using asynchronous SPI API and then spinning waiting for SPI transfer to complete when disabling the device, let's use threaded IRQ model and spi_sync(). Acked-by: Michael Hennerich <michael.hennerich@analog.com> 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/ad7877.c65
1 files changed, 25 insertions, 40 deletions
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
index 326d7336a372..a1952fcc083e 100644
--- a/drivers/input/touchscreen/ad7877.c
+++ b/drivers/input/touchscreen/ad7877.c
@@ -191,13 +191,12 @@ struct ad7877 {
191 struct spi_message msg; 191 struct spi_message msg;
192 192
193 struct mutex mutex; 193 struct mutex mutex;
194 unsigned disabled:1; /* P: mutex */ 194 bool disabled; /* P: mutex */
195 unsigned gpio3:1; /* P: mutex */ 195 bool gpio3; /* P: mutex */
196 unsigned gpio4:1; /* P: mutex */ 196 bool gpio4; /* P: mutex */
197 197
198 spinlock_t lock; 198 spinlock_t lock;
199 struct timer_list timer; /* P: lock */ 199 struct timer_list timer; /* P: lock */
200 unsigned pending:1; /* P: lock */
201 200
202 /* 201 /*
203 * DMA (thus cache coherency maintenance) requires the 202 * DMA (thus cache coherency maintenance) requires the
@@ -333,7 +332,7 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command)
333 return status ? : sample; 332 return status ? : sample;
334} 333}
335 334
336static int ad7877_rx(struct ad7877 *ts) 335static int ad7877_process_data(struct ad7877 *ts)
337{ 336{
338 struct input_dev *input_dev = ts->input; 337 struct input_dev *input_dev = ts->input;
339 unsigned Rt; 338 unsigned Rt;
@@ -374,6 +373,7 @@ static int ad7877_rx(struct ad7877 *ts)
374 input_report_abs(input_dev, ABS_Y, y); 373 input_report_abs(input_dev, ABS_Y, y);
375 input_report_abs(input_dev, ABS_PRESSURE, Rt); 374 input_report_abs(input_dev, ABS_PRESSURE, Rt);
376 input_sync(input_dev); 375 input_sync(input_dev);
376
377 return 0; 377 return 0;
378 } 378 }
379 379
@@ -392,64 +392,49 @@ static inline void ad7877_ts_event_release(struct ad7877 *ts)
392static void ad7877_timer(unsigned long handle) 392static void ad7877_timer(unsigned long handle)
393{ 393{
394 struct ad7877 *ts = (void *)handle; 394 struct ad7877 *ts = (void *)handle;
395 unsigned long flags;
395 396
397 spin_lock_irqsave(&ts->lock, flags);
396 ad7877_ts_event_release(ts); 398 ad7877_ts_event_release(ts);
399 spin_unlock_irqrestore(&ts->lock, flags);
397} 400}
398 401
399static irqreturn_t ad7877_irq(int irq, void *handle) 402static irqreturn_t ad7877_irq(int irq, void *handle)
400{ 403{
401 struct ad7877 *ts = handle; 404 struct ad7877 *ts = handle;
402 unsigned long flags; 405 unsigned long flags;
403 int status; 406 int error;
404 407
405 /* 408 error = spi_sync(ts->spi, &ts->msg);
406 * The repeated conversion sequencer controlled by TMR kicked off 409 if (error) {
407 * too fast. We ignore the last and process the sample sequence 410 dev_err(&ts->spi->dev, "spi_sync --> %d\n", error);
408 * currently in the queue. It can't be older than 9.4ms, and we 411 goto out;
409 * need to avoid that ts->msg doesn't get issued twice while in work. 412 }
410 */
411 413
412 spin_lock_irqsave(&ts->lock, flags); 414 spin_lock_irqsave(&ts->lock, flags);
413 if (!ts->pending) { 415 error = ad7877_process_data(ts);
414 ts->pending = 1; 416 if (!error)
415 417 mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
416 status = spi_async(ts->spi, &ts->msg);
417 if (status)
418 dev_err(&ts->spi->dev, "spi_sync --> %d\n", status);
419 }
420 spin_unlock_irqrestore(&ts->lock, flags); 418 spin_unlock_irqrestore(&ts->lock, flags);
421 419
420out:
422 return IRQ_HANDLED; 421 return IRQ_HANDLED;
423} 422}
424 423
425static void ad7877_callback(void *_ts)
426{
427 struct ad7877 *ts = _ts;
428
429 spin_lock_irq(&ts->lock);
430 if (!ad7877_rx(ts))
431 mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
432 ts->pending = 0;
433 spin_unlock_irq(&ts->lock);
434}
435
436static void ad7877_disable(struct ad7877 *ts) 424static void ad7877_disable(struct ad7877 *ts)
437{ 425{
438 mutex_lock(&ts->mutex); 426 mutex_lock(&ts->mutex);
439 427
440 if (!ts->disabled) { 428 if (!ts->disabled) {
441 ts->disabled = 1; 429 ts->disabled = true;
442 disable_irq(ts->spi->irq); 430 disable_irq(ts->spi->irq);
443 431
444 /* Wait for spi_async callback */
445 while (ts->pending)
446 msleep(1);
447
448 if (del_timer_sync(&ts->timer)) 432 if (del_timer_sync(&ts->timer))
449 ad7877_ts_event_release(ts); 433 ad7877_ts_event_release(ts);
450 } 434 }
451 435
452 /* we know the chip's in lowpower mode since we always 436 /*
437 * We know the chip's in lowpower mode since we always
453 * leave it that way after every request 438 * leave it that way after every request
454 */ 439 */
455 440
@@ -461,7 +446,7 @@ static void ad7877_enable(struct ad7877 *ts)
461 mutex_lock(&ts->mutex); 446 mutex_lock(&ts->mutex);
462 447
463 if (ts->disabled) { 448 if (ts->disabled) {
464 ts->disabled = 0; 449 ts->disabled = false;
465 enable_irq(ts->spi->irq); 450 enable_irq(ts->spi->irq);
466 } 451 }
467 452
@@ -672,7 +657,6 @@ static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts)
672 657
673 spi_message_init(m); 658 spi_message_init(m);
674 659
675 m->complete = ad7877_callback;
676 m->context = ts; 660 m->context = ts;
677 661
678 ts->xfer[0].tx_buf = &ts->cmd_crtl1; 662 ts->xfer[0].tx_buf = &ts->cmd_crtl1;
@@ -795,8 +779,9 @@ static int __devinit ad7877_probe(struct spi_device *spi)
795 779
796 /* Request AD7877 /DAV GPIO interrupt */ 780 /* Request AD7877 /DAV GPIO interrupt */
797 781
798 err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING, 782 err = request_threaded_irq(spi->irq, NULL, ad7877_irq,
799 spi->dev.driver->name, ts); 783 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
784 spi->dev.driver->name, ts);
800 if (err) { 785 if (err) {
801 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); 786 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
802 goto err_free_mem; 787 goto err_free_mem;