diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-09-16 04:06:42 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-09-18 02:24:01 -0400 |
commit | 30b37131aa63f4f73ebc48a026666448e5907255 (patch) | |
tree | 4d9dc23f588a427ebe9980e7ba88ffbb16472142 /drivers/input/mouse/synaptics_i2c.c | |
parent | 36fb25277825b6ef6acd57091e6aaa6dc8a4c203 (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.c | 51 |
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 */ |
206 | static int polling_req; | 206 | static bool polling_req; |
207 | module_param(polling_req, bool, 0444); | 207 | module_param(polling_req, bool, 0444); |
208 | MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)"); | 208 | MODULE_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 | ||
369 | static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id) | 370 | static 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 | |||
387 | static 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 | ||
458 | static int synaptics_i2c_open(struct input_dev *input) | 470 | static 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 | ||
585 | err_input_free: | 599 | err_input_free: |
586 | input_free_device(touch->input); | 600 | input_free_device(touch->input); |
587 | err_mem_free: | 601 | err_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 | } |