diff options
Diffstat (limited to 'drivers/input/serio/serio.c')
-rw-r--r-- | drivers/input/serio/serio.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 2f76813c3a64..6521034bc933 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/mutex.h> | ||
37 | 38 | ||
38 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 39 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
39 | MODULE_DESCRIPTION("Serio abstraction core"); | 40 | MODULE_DESCRIPTION("Serio abstraction core"); |
@@ -52,10 +53,10 @@ EXPORT_SYMBOL(serio_rescan); | |||
52 | EXPORT_SYMBOL(serio_reconnect); | 53 | EXPORT_SYMBOL(serio_reconnect); |
53 | 54 | ||
54 | /* | 55 | /* |
55 | * serio_sem protects entire serio subsystem and is taken every time | 56 | * serio_mutex protects entire serio subsystem and is taken every time |
56 | * serio port or driver registrered or unregistered. | 57 | * serio port or driver registrered or unregistered. |
57 | */ | 58 | */ |
58 | static DECLARE_MUTEX(serio_sem); | 59 | static DEFINE_MUTEX(serio_mutex); |
59 | 60 | ||
60 | static LIST_HEAD(serio_list); | 61 | static LIST_HEAD(serio_list); |
61 | 62 | ||
@@ -70,9 +71,9 @@ static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) | |||
70 | { | 71 | { |
71 | int retval; | 72 | int retval; |
72 | 73 | ||
73 | down(&serio->drv_sem); | 74 | mutex_lock(&serio->drv_mutex); |
74 | retval = drv->connect(serio, drv); | 75 | retval = drv->connect(serio, drv); |
75 | up(&serio->drv_sem); | 76 | mutex_unlock(&serio->drv_mutex); |
76 | 77 | ||
77 | return retval; | 78 | return retval; |
78 | } | 79 | } |
@@ -81,20 +82,20 @@ static int serio_reconnect_driver(struct serio *serio) | |||
81 | { | 82 | { |
82 | int retval = -1; | 83 | int retval = -1; |
83 | 84 | ||
84 | down(&serio->drv_sem); | 85 | mutex_lock(&serio->drv_mutex); |
85 | if (serio->drv && serio->drv->reconnect) | 86 | if (serio->drv && serio->drv->reconnect) |
86 | retval = serio->drv->reconnect(serio); | 87 | retval = serio->drv->reconnect(serio); |
87 | up(&serio->drv_sem); | 88 | mutex_unlock(&serio->drv_mutex); |
88 | 89 | ||
89 | return retval; | 90 | return retval; |
90 | } | 91 | } |
91 | 92 | ||
92 | static void serio_disconnect_driver(struct serio *serio) | 93 | static void serio_disconnect_driver(struct serio *serio) |
93 | { | 94 | { |
94 | down(&serio->drv_sem); | 95 | mutex_lock(&serio->drv_mutex); |
95 | if (serio->drv) | 96 | if (serio->drv) |
96 | serio->drv->disconnect(serio); | 97 | serio->drv->disconnect(serio); |
97 | up(&serio->drv_sem); | 98 | mutex_unlock(&serio->drv_mutex); |
98 | } | 99 | } |
99 | 100 | ||
100 | static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) | 101 | static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) |
@@ -195,6 +196,7 @@ static void serio_queue_event(void *object, struct module *owner, | |||
195 | if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { | 196 | if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { |
196 | if (!try_module_get(owner)) { | 197 | if (!try_module_get(owner)) { |
197 | printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); | 198 | printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); |
199 | kfree(event); | ||
198 | goto out; | 200 | goto out; |
199 | } | 201 | } |
200 | 202 | ||
@@ -272,7 +274,7 @@ static void serio_handle_event(void) | |||
272 | struct serio_event *event; | 274 | struct serio_event *event; |
273 | struct serio_driver *serio_drv; | 275 | struct serio_driver *serio_drv; |
274 | 276 | ||
275 | down(&serio_sem); | 277 | mutex_lock(&serio_mutex); |
276 | 278 | ||
277 | /* | 279 | /* |
278 | * Note that we handle only one event here to give swsusp | 280 | * Note that we handle only one event here to give swsusp |
@@ -314,7 +316,7 @@ static void serio_handle_event(void) | |||
314 | serio_free_event(event); | 316 | serio_free_event(event); |
315 | } | 317 | } |
316 | 318 | ||
317 | up(&serio_sem); | 319 | mutex_unlock(&serio_mutex); |
318 | } | 320 | } |
319 | 321 | ||
320 | /* | 322 | /* |
@@ -449,7 +451,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * | |||
449 | struct device_driver *drv; | 451 | struct device_driver *drv; |
450 | int retval; | 452 | int retval; |
451 | 453 | ||
452 | retval = down_interruptible(&serio_sem); | 454 | retval = mutex_lock_interruptible(&serio_mutex); |
453 | if (retval) | 455 | if (retval) |
454 | return retval; | 456 | return retval; |
455 | 457 | ||
@@ -469,7 +471,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * | |||
469 | retval = -EINVAL; | 471 | retval = -EINVAL; |
470 | } | 472 | } |
471 | 473 | ||
472 | up(&serio_sem); | 474 | mutex_unlock(&serio_mutex); |
473 | 475 | ||
474 | return retval; | 476 | return retval; |
475 | } | 477 | } |
@@ -524,7 +526,7 @@ static void serio_init_port(struct serio *serio) | |||
524 | __module_get(THIS_MODULE); | 526 | __module_get(THIS_MODULE); |
525 | 527 | ||
526 | spin_lock_init(&serio->lock); | 528 | spin_lock_init(&serio->lock); |
527 | init_MUTEX(&serio->drv_sem); | 529 | mutex_init(&serio->drv_mutex); |
528 | device_initialize(&serio->dev); | 530 | device_initialize(&serio->dev); |
529 | snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), | 531 | snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), |
530 | "serio%ld", (long)atomic_inc_return(&serio_no) - 1); | 532 | "serio%ld", (long)atomic_inc_return(&serio_no) - 1); |
@@ -661,10 +663,10 @@ void __serio_register_port(struct serio *serio, struct module *owner) | |||
661 | */ | 663 | */ |
662 | void serio_unregister_port(struct serio *serio) | 664 | void serio_unregister_port(struct serio *serio) |
663 | { | 665 | { |
664 | down(&serio_sem); | 666 | mutex_lock(&serio_mutex); |
665 | serio_disconnect_port(serio); | 667 | serio_disconnect_port(serio); |
666 | serio_destroy_port(serio); | 668 | serio_destroy_port(serio); |
667 | up(&serio_sem); | 669 | mutex_unlock(&serio_mutex); |
668 | } | 670 | } |
669 | 671 | ||
670 | /* | 672 | /* |
@@ -672,17 +674,17 @@ void serio_unregister_port(struct serio *serio) | |||
672 | */ | 674 | */ |
673 | void serio_unregister_child_port(struct serio *serio) | 675 | void serio_unregister_child_port(struct serio *serio) |
674 | { | 676 | { |
675 | down(&serio_sem); | 677 | mutex_lock(&serio_mutex); |
676 | if (serio->child) { | 678 | if (serio->child) { |
677 | serio_disconnect_port(serio->child); | 679 | serio_disconnect_port(serio->child); |
678 | serio_destroy_port(serio->child); | 680 | serio_destroy_port(serio->child); |
679 | } | 681 | } |
680 | up(&serio_sem); | 682 | mutex_unlock(&serio_mutex); |
681 | } | 683 | } |
682 | 684 | ||
683 | /* | 685 | /* |
684 | * Submits register request to kseriod for subsequent execution. | 686 | * Submits register request to kseriod for subsequent execution. |
685 | * Can be used when it is not obvious whether the serio_sem is | 687 | * Can be used when it is not obvious whether the serio_mutex is |
686 | * taken or not and when delayed execution is feasible. | 688 | * taken or not and when delayed execution is feasible. |
687 | */ | 689 | */ |
688 | void __serio_unregister_port_delayed(struct serio *serio, struct module *owner) | 690 | void __serio_unregister_port_delayed(struct serio *serio, struct module *owner) |
@@ -765,7 +767,7 @@ void serio_unregister_driver(struct serio_driver *drv) | |||
765 | { | 767 | { |
766 | struct serio *serio; | 768 | struct serio *serio; |
767 | 769 | ||
768 | down(&serio_sem); | 770 | mutex_lock(&serio_mutex); |
769 | drv->manual_bind = 1; /* so serio_find_driver ignores it */ | 771 | drv->manual_bind = 1; /* so serio_find_driver ignores it */ |
770 | 772 | ||
771 | start_over: | 773 | start_over: |
@@ -779,7 +781,7 @@ start_over: | |||
779 | } | 781 | } |
780 | 782 | ||
781 | driver_unregister(&drv->driver); | 783 | driver_unregister(&drv->driver); |
782 | up(&serio_sem); | 784 | mutex_unlock(&serio_mutex); |
783 | } | 785 | } |
784 | 786 | ||
785 | static void serio_set_drv(struct serio *serio, struct serio_driver *drv) | 787 | static void serio_set_drv(struct serio *serio, struct serio_driver *drv) |
@@ -858,7 +860,7 @@ static int serio_resume(struct device *dev) | |||
858 | return 0; | 860 | return 0; |
859 | } | 861 | } |
860 | 862 | ||
861 | /* called from serio_driver->connect/disconnect methods under serio_sem */ | 863 | /* called from serio_driver->connect/disconnect methods under serio_mutex */ |
862 | int serio_open(struct serio *serio, struct serio_driver *drv) | 864 | int serio_open(struct serio *serio, struct serio_driver *drv) |
863 | { | 865 | { |
864 | serio_set_drv(serio, drv); | 866 | serio_set_drv(serio, drv); |
@@ -870,7 +872,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv) | |||
870 | return 0; | 872 | return 0; |
871 | } | 873 | } |
872 | 874 | ||
873 | /* called from serio_driver->connect/disconnect methods under serio_sem */ | 875 | /* called from serio_driver->connect/disconnect methods under serio_mutex */ |
874 | void serio_close(struct serio *serio) | 876 | void serio_close(struct serio *serio) |
875 | { | 877 | { |
876 | if (serio->close) | 878 | if (serio->close) |
@@ -923,5 +925,5 @@ static void __exit serio_exit(void) | |||
923 | kthread_stop(serio_task); | 925 | kthread_stop(serio_task); |
924 | } | 926 | } |
925 | 927 | ||
926 | module_init(serio_init); | 928 | subsys_initcall(serio_init); |
927 | module_exit(serio_exit); | 929 | module_exit(serio_exit); |