aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/gameport/gameport.c31
1 files changed, 12 insertions, 19 deletions
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index f20c3f23388b..d7dfa6f53cf6 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 {
238static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ 237static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */
239static LIST_HEAD(gameport_event_list); 238static LIST_HEAD(gameport_event_list);
240static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); 239static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
241static DECLARE_COMPLETION(gameport_exited); 240static struct task_struct *gameport_task;
242static int gameport_pid;
243 241
244static void gameport_queue_event(void *object, struct module *owner, 242static 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
433static int gameport_thread(void *nothing) 431static 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(PF_FREEZE); 437 try_to_freeze(PF_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
774static int __init gameport_init(void) 767static 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)
789static void __exit gameport_exit(void) 783static 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
796module_init(gameport_init); 789module_init(gameport_init);