diff options
Diffstat (limited to 'drivers/input/gameport/gameport.c')
-rw-r--r-- | drivers/input/gameport/gameport.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index c77a82e46055..3e72c9b1461e 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -17,11 +17,10 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/gameport.h> | 18 | #include <linux/gameport.h> |
19 | #include <linux/wait.h> | 19 | #include <linux/wait.h> |
20 | #include <linux/completion.h> | ||
21 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
24 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/kthread.h> | ||
25 | 24 | ||
26 | /*#include <asm/io.h>*/ | 25 | /*#include <asm/io.h>*/ |
27 | 26 | ||
@@ -238,8 +237,7 @@ struct gameport_event { | |||
238 | static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ | 237 | static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ |
239 | static LIST_HEAD(gameport_event_list); | 238 | static LIST_HEAD(gameport_event_list); |
240 | static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); | 239 | static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); |
241 | static DECLARE_COMPLETION(gameport_exited); | 240 | static struct task_struct *gameport_task; |
242 | static int gameport_pid; | ||
243 | 241 | ||
244 | static void gameport_queue_event(void *object, struct module *owner, | 242 | static void gameport_queue_event(void *object, struct module *owner, |
245 | enum gameport_event_type event_type) | 243 | enum gameport_event_type event_type) |
@@ -250,12 +248,12 @@ static void gameport_queue_event(void *object, struct module *owner, | |||
250 | spin_lock_irqsave(&gameport_event_lock, flags); | 248 | spin_lock_irqsave(&gameport_event_lock, flags); |
251 | 249 | ||
252 | /* | 250 | /* |
253 | * Scan event list for the other events for the same gameport port, | 251 | * Scan event list for the other events for the same gameport port, |
254 | * starting with the most recent one. If event is the same we | 252 | * starting with the most recent one. If event is the same we |
255 | * do not need add new one. If event is of different type we | 253 | * do not need add new one. If event is of different type we |
256 | * need to add this event and should not look further because | 254 | * need to add this event and should not look further because |
257 | * we need to preseve sequence of distinct events. | 255 | * we need to preseve sequence of distinct events. |
258 | */ | 256 | */ |
259 | list_for_each_entry_reverse(event, &gameport_event_list, node) { | 257 | list_for_each_entry_reverse(event, &gameport_event_list, node) { |
260 | if (event->object == object) { | 258 | if (event->object == object) { |
261 | if (event->type == event_type) | 259 | if (event->type == event_type) |
@@ -432,20 +430,15 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent) | |||
432 | 430 | ||
433 | static int gameport_thread(void *nothing) | 431 | static int gameport_thread(void *nothing) |
434 | { | 432 | { |
435 | lock_kernel(); | ||
436 | daemonize("kgameportd"); | ||
437 | allow_signal(SIGTERM); | ||
438 | |||
439 | do { | 433 | do { |
440 | gameport_handle_events(); | 434 | gameport_handle_events(); |
441 | wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list)); | 435 | wait_event_interruptible(gameport_wait, |
436 | kthread_should_stop() || !list_empty(&gameport_event_list)); | ||
442 | try_to_freeze(); | 437 | try_to_freeze(); |
443 | } while (!signal_pending(current)); | 438 | } while (!kthread_should_stop()); |
444 | 439 | ||
445 | printk(KERN_DEBUG "gameport: kgameportd exiting\n"); | 440 | printk(KERN_DEBUG "gameport: kgameportd exiting\n"); |
446 | 441 | return 0; | |
447 | unlock_kernel(); | ||
448 | complete_and_exit(&gameport_exited, 0); | ||
449 | } | 442 | } |
450 | 443 | ||
451 | 444 | ||
@@ -773,9 +766,10 @@ void gameport_close(struct gameport *gameport) | |||
773 | 766 | ||
774 | static int __init gameport_init(void) | 767 | static int __init gameport_init(void) |
775 | { | 768 | { |
776 | if (!(gameport_pid = kernel_thread(gameport_thread, NULL, CLONE_KERNEL))) { | 769 | gameport_task = kthread_run(gameport_thread, NULL, "kgameportd"); |
770 | if (IS_ERR(gameport_task)) { | ||
777 | printk(KERN_ERR "gameport: Failed to start kgameportd\n"); | 771 | printk(KERN_ERR "gameport: Failed to start kgameportd\n"); |
778 | return -1; | 772 | return PTR_ERR(gameport_task); |
779 | } | 773 | } |
780 | 774 | ||
781 | gameport_bus.dev_attrs = gameport_device_attrs; | 775 | gameport_bus.dev_attrs = gameport_device_attrs; |
@@ -789,8 +783,7 @@ static int __init gameport_init(void) | |||
789 | static void __exit gameport_exit(void) | 783 | static void __exit gameport_exit(void) |
790 | { | 784 | { |
791 | bus_unregister(&gameport_bus); | 785 | bus_unregister(&gameport_bus); |
792 | kill_proc(gameport_pid, SIGTERM, 1); | 786 | kthread_stop(gameport_task); |
793 | wait_for_completion(&gameport_exited); | ||
794 | } | 787 | } |
795 | 788 | ||
796 | module_init(gameport_init); | 789 | module_init(gameport_init); |