diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-10-12 21:30:36 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-10-12 21:30:36 -0400 |
commit | aefca8ba5f1b95431e33a52736bab128fc4f80d4 (patch) | |
tree | 88a84cd919e8431387ea55aba7d8663853b0f9c6 /drivers/hwmon/hdaps.c | |
parent | b981d8b3f5e008ff10d993be633ad00564fc22cd (diff) |
HWMON: hdaps - switch to using input-polldev
Switch to using input-polldev skeleton instead of implementing polling loop
by itself. This also fixes problem with trylock on a mutex in atomic
context.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/hwmon/hdaps.c')
-rw-r--r-- | drivers/hwmon/hdaps.c | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index a7c6d407572b..8a7ae03aeee4 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input-polldev.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
@@ -61,13 +61,12 @@ | |||
61 | #define INIT_TIMEOUT_MSECS 4000 /* wait up to 4s for device init ... */ | 61 | #define INIT_TIMEOUT_MSECS 4000 /* wait up to 4s for device init ... */ |
62 | #define INIT_WAIT_MSECS 200 /* ... in 200ms increments */ | 62 | #define INIT_WAIT_MSECS 200 /* ... in 200ms increments */ |
63 | 63 | ||
64 | #define HDAPS_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */ | 64 | #define HDAPS_POLL_INTERVAL 50 /* poll for input every 1/20s (50 ms)*/ |
65 | #define HDAPS_INPUT_FUZZ 4 /* input event threshold */ | 65 | #define HDAPS_INPUT_FUZZ 4 /* input event threshold */ |
66 | #define HDAPS_INPUT_FLAT 4 | 66 | #define HDAPS_INPUT_FLAT 4 |
67 | 67 | ||
68 | static struct timer_list hdaps_timer; | ||
69 | static struct platform_device *pdev; | 68 | static struct platform_device *pdev; |
70 | static struct input_dev *hdaps_idev; | 69 | static struct input_polled_dev *hdaps_idev; |
71 | static unsigned int hdaps_invert; | 70 | static unsigned int hdaps_invert; |
72 | static u8 km_activity; | 71 | static u8 km_activity; |
73 | static int rest_x; | 72 | static int rest_x; |
@@ -323,24 +322,19 @@ static void hdaps_calibrate(void) | |||
323 | __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &rest_x, &rest_y); | 322 | __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &rest_x, &rest_y); |
324 | } | 323 | } |
325 | 324 | ||
326 | static void hdaps_mousedev_poll(unsigned long unused) | 325 | static void hdaps_mousedev_poll(struct input_polled_dev *dev) |
327 | { | 326 | { |
327 | struct input_dev *input_dev = dev->input; | ||
328 | int x, y; | 328 | int x, y; |
329 | 329 | ||
330 | /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ | 330 | mutex_lock(&hdaps_mtx); |
331 | if (mutex_trylock(&hdaps_mtx)) { | ||
332 | mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); | ||
333 | return; | ||
334 | } | ||
335 | 331 | ||
336 | if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y)) | 332 | if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y)) |
337 | goto out; | 333 | goto out; |
338 | 334 | ||
339 | input_report_abs(hdaps_idev, ABS_X, x - rest_x); | 335 | input_report_abs(input_dev, ABS_X, x - rest_x); |
340 | input_report_abs(hdaps_idev, ABS_Y, y - rest_y); | 336 | input_report_abs(input_dev, ABS_Y, y - rest_y); |
341 | input_sync(hdaps_idev); | 337 | input_sync(input_dev); |
342 | |||
343 | mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); | ||
344 | 338 | ||
345 | out: | 339 | out: |
346 | mutex_unlock(&hdaps_mtx); | 340 | mutex_unlock(&hdaps_mtx); |
@@ -536,6 +530,7 @@ static struct dmi_system_id __initdata hdaps_whitelist[] = { | |||
536 | 530 | ||
537 | static int __init hdaps_init(void) | 531 | static int __init hdaps_init(void) |
538 | { | 532 | { |
533 | struct input_dev *idev; | ||
539 | int ret; | 534 | int ret; |
540 | 535 | ||
541 | if (!dmi_check_system(hdaps_whitelist)) { | 536 | if (!dmi_check_system(hdaps_whitelist)) { |
@@ -563,39 +558,37 @@ static int __init hdaps_init(void) | |||
563 | if (ret) | 558 | if (ret) |
564 | goto out_device; | 559 | goto out_device; |
565 | 560 | ||
566 | hdaps_idev = input_allocate_device(); | 561 | hdaps_idev = input_allocate_polled_device(); |
567 | if (!hdaps_idev) { | 562 | if (!hdaps_idev) { |
568 | ret = -ENOMEM; | 563 | ret = -ENOMEM; |
569 | goto out_group; | 564 | goto out_group; |
570 | } | 565 | } |
571 | 566 | ||
567 | hdaps_idev->poll = hdaps_mousedev_poll; | ||
568 | hdaps_idev->poll_interval = HDAPS_POLL_INTERVAL; | ||
569 | |||
572 | /* initial calibrate for the input device */ | 570 | /* initial calibrate for the input device */ |
573 | hdaps_calibrate(); | 571 | hdaps_calibrate(); |
574 | 572 | ||
575 | /* initialize the input class */ | 573 | /* initialize the input class */ |
576 | hdaps_idev->name = "hdaps"; | 574 | idev = hdaps_idev->input; |
577 | hdaps_idev->dev.parent = &pdev->dev; | 575 | idev->name = "hdaps"; |
578 | hdaps_idev->evbit[0] = BIT(EV_ABS); | 576 | idev->dev.parent = &pdev->dev; |
579 | input_set_abs_params(hdaps_idev, ABS_X, | 577 | idev->evbit[0] = BIT(EV_ABS); |
578 | input_set_abs_params(idev, ABS_X, | ||
580 | -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT); | 579 | -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT); |
581 | input_set_abs_params(hdaps_idev, ABS_Y, | 580 | input_set_abs_params(idev, ABS_Y, |
582 | -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT); | 581 | -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT); |
583 | 582 | ||
584 | ret = input_register_device(hdaps_idev); | 583 | ret = input_register_polled_device(hdaps_idev); |
585 | if (ret) | 584 | if (ret) |
586 | goto out_idev; | 585 | goto out_idev; |
587 | 586 | ||
588 | /* start up our timer for the input device */ | ||
589 | init_timer(&hdaps_timer); | ||
590 | hdaps_timer.function = hdaps_mousedev_poll; | ||
591 | hdaps_timer.expires = jiffies + HDAPS_POLL_PERIOD; | ||
592 | add_timer(&hdaps_timer); | ||
593 | |||
594 | printk(KERN_INFO "hdaps: driver successfully loaded.\n"); | 587 | printk(KERN_INFO "hdaps: driver successfully loaded.\n"); |
595 | return 0; | 588 | return 0; |
596 | 589 | ||
597 | out_idev: | 590 | out_idev: |
598 | input_free_device(hdaps_idev); | 591 | input_free_polled_device(hdaps_idev); |
599 | out_group: | 592 | out_group: |
600 | sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group); | 593 | sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group); |
601 | out_device: | 594 | out_device: |
@@ -611,8 +604,8 @@ out: | |||
611 | 604 | ||
612 | static void __exit hdaps_exit(void) | 605 | static void __exit hdaps_exit(void) |
613 | { | 606 | { |
614 | del_timer_sync(&hdaps_timer); | 607 | input_unregister_polled_device(hdaps_idev); |
615 | input_unregister_device(hdaps_idev); | 608 | input_free_polled_device(hdaps_idev); |
616 | sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group); | 609 | sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group); |
617 | platform_device_unregister(pdev); | 610 | platform_device_unregister(pdev); |
618 | platform_driver_unregister(&hdaps_driver); | 611 | platform_driver_unregister(&hdaps_driver); |