aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/synaptics_i2c.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-09-16 04:06:42 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-09-18 02:24:01 -0400
commit30b37131aa63f4f73ebc48a026666448e5907255 (patch)
tree4d9dc23f588a427ebe9980e7ba88ffbb16472142 /drivers/input/mouse/synaptics_i2c.c
parent36fb25277825b6ef6acd57091e6aaa6dc8a4c203 (diff)
Input: synaptics_i2c - switch to using __cancel_delayed_work()
cancel_delayed_work() may spin and therefore should not be used in interrupt contexts. Acked-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse/synaptics_i2c.c')
-rw-r--r--drivers/input/mouse/synaptics_i2c.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c
index eac9fdde7ee9..7283c78044af 100644
--- a/drivers/input/mouse/synaptics_i2c.c
+++ b/drivers/input/mouse/synaptics_i2c.c
@@ -203,7 +203,7 @@ MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)");
203 * and the irq configuration should be set to Falling Edge Trigger 203 * and the irq configuration should be set to Falling Edge Trigger
204 */ 204 */
205/* Control IRQ / Polling option */ 205/* Control IRQ / Polling option */
206static int polling_req; 206static bool polling_req;
207module_param(polling_req, bool, 0444); 207module_param(polling_req, bool, 0444);
208MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)"); 208MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)");
209 209
@@ -217,6 +217,7 @@ struct synaptics_i2c {
217 struct i2c_client *client; 217 struct i2c_client *client;
218 struct input_dev *input; 218 struct input_dev *input;
219 struct delayed_work dwork; 219 struct delayed_work dwork;
220 spinlock_t lock;
220 int no_data_count; 221 int no_data_count;
221 int no_decel_param; 222 int no_decel_param;
222 int reduce_report_param; 223 int reduce_report_param;
@@ -366,17 +367,28 @@ static bool synaptics_i2c_get_input(struct synaptics_i2c *touch)
366 return xy_delta || gesture; 367 return xy_delta || gesture;
367} 368}
368 369
369static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id) 370static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch,
371 unsigned long delay)
370{ 372{
371 struct synaptics_i2c *touch = dev_id; 373 unsigned long flags;
374
375 spin_lock_irqsave(&touch->lock, flags);
372 376
373 /* 377 /*
374 * We want to have the work run immediately but it might have 378 * If work is already scheduled then subsequent schedules will not
375 * already been scheduled with a delay, that's why we have to 379 * change the scheduled time that's why we have to cancel it first.
376 * cancel it first.
377 */ 380 */
378 cancel_delayed_work(&touch->dwork); 381 __cancel_delayed_work(&touch->dwork);
379 schedule_delayed_work(&touch->dwork, 0); 382 schedule_delayed_work(&touch->dwork, delay);
383
384 spin_unlock_irqrestore(&touch->lock, flags);
385}
386
387static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id)
388{
389 struct synaptics_i2c *touch = dev_id;
390
391 synaptics_i2c_reschedule_work(touch, 0);
380 392
381 return IRQ_HANDLED; 393 return IRQ_HANDLED;
382} 394}
@@ -452,7 +464,7 @@ static void synaptics_i2c_work_handler(struct work_struct *work)
452 * We poll the device once in THREAD_IRQ_SLEEP_SECS and 464 * We poll the device once in THREAD_IRQ_SLEEP_SECS and
453 * if error is detected, we try to reset and reconfigure the touchpad. 465 * if error is detected, we try to reset and reconfigure the touchpad.
454 */ 466 */
455 schedule_delayed_work(&touch->dwork, delay); 467 synaptics_i2c_reschedule_work(touch, delay);
456} 468}
457 469
458static int synaptics_i2c_open(struct input_dev *input) 470static int synaptics_i2c_open(struct input_dev *input)
@@ -465,8 +477,8 @@ static int synaptics_i2c_open(struct input_dev *input)
465 return ret; 477 return ret;
466 478
467 if (polling_req) 479 if (polling_req)
468 schedule_delayed_work(&touch->dwork, 480 synaptics_i2c_reschedule_work(touch,
469 msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); 481 msecs_to_jiffies(NO_DATA_SLEEP_MSECS));
470 482
471 return 0; 483 return 0;
472} 484}
@@ -521,6 +533,7 @@ struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client)
521 touch->scan_rate_param = scan_rate; 533 touch->scan_rate_param = scan_rate;
522 set_scan_rate(touch, scan_rate); 534 set_scan_rate(touch, scan_rate);
523 INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler); 535 INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler);
536 spin_lock_init(&touch->lock);
524 537
525 return touch; 538 return touch;
526} 539}
@@ -535,14 +548,12 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client,
535 if (!touch) 548 if (!touch)
536 return -ENOMEM; 549 return -ENOMEM;
537 550
538 i2c_set_clientdata(client, touch);
539
540 ret = synaptics_i2c_reset_config(client); 551 ret = synaptics_i2c_reset_config(client);
541 if (ret) 552 if (ret)
542 goto err_mem_free; 553 goto err_mem_free;
543 554
544 if (client->irq < 1) 555 if (client->irq < 1)
545 polling_req = 1; 556 polling_req = true;
546 557
547 touch->input = input_allocate_device(); 558 touch->input = input_allocate_device();
548 if (!touch->input) { 559 if (!touch->input) {
@@ -563,7 +574,7 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client,
563 dev_warn(&touch->client->dev, 574 dev_warn(&touch->client->dev,
564 "IRQ request failed: %d, " 575 "IRQ request failed: %d, "
565 "falling back to polling\n", ret); 576 "falling back to polling\n", ret);
566 polling_req = 1; 577 polling_req = true;
567 synaptics_i2c_reg_set(touch->client, 578 synaptics_i2c_reg_set(touch->client,
568 INTERRUPT_EN_REG, 0); 579 INTERRUPT_EN_REG, 0);
569 } 580 }
@@ -580,12 +591,14 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client,
580 "Input device register failed: %d\n", ret); 591 "Input device register failed: %d\n", ret);
581 goto err_input_free; 592 goto err_input_free;
582 } 593 }
594
595 i2c_set_clientdata(client, touch);
596
583 return 0; 597 return 0;
584 598
585err_input_free: 599err_input_free:
586 input_free_device(touch->input); 600 input_free_device(touch->input);
587err_mem_free: 601err_mem_free:
588 i2c_set_clientdata(client, NULL);
589 kfree(touch); 602 kfree(touch);
590 603
591 return ret; 604 return ret;
@@ -596,7 +609,7 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client)
596 struct synaptics_i2c *touch = i2c_get_clientdata(client); 609 struct synaptics_i2c *touch = i2c_get_clientdata(client);
597 610
598 if (!polling_req) 611 if (!polling_req)
599 free_irq(touch->client->irq, touch); 612 free_irq(client->irq, touch);
600 613
601 input_unregister_device(touch->input); 614 input_unregister_device(touch->input);
602 i2c_set_clientdata(client, NULL); 615 i2c_set_clientdata(client, NULL);
@@ -627,8 +640,8 @@ static int synaptics_i2c_resume(struct i2c_client *client)
627 if (ret) 640 if (ret)
628 return ret; 641 return ret;
629 642
630 schedule_delayed_work(&touch->dwork, 643 synaptics_i2c_reschedule_work(touch,
631 msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); 644 msecs_to_jiffies(NO_DATA_SLEEP_MSECS));
632 645
633 return 0; 646 return 0;
634} 647}