diff options
-rw-r--r-- | arch/arm/kernel/apm.c | 33 |
1 files changed, 13 insertions, 20 deletions
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index 33c55689f999..ecf4f9472d94 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/list.h> | 25 | #include <linux/list.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/completion.h> | 27 | #include <linux/completion.h> |
28 | #include <linux/kthread.h> | ||
28 | 29 | ||
29 | #include <asm/apm.h> /* apm_power_info */ | 30 | #include <asm/apm.h> /* apm_power_info */ |
30 | #include <asm/system.h> | 31 | #include <asm/system.h> |
@@ -80,7 +81,7 @@ struct apm_user { | |||
80 | */ | 81 | */ |
81 | static int suspends_pending; | 82 | static int suspends_pending; |
82 | static int apm_disabled; | 83 | static int apm_disabled; |
83 | static int arm_apm_active; | 84 | static struct task_struct *kapmd_tsk; |
84 | 85 | ||
85 | static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); | 86 | static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); |
86 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); | 87 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); |
@@ -97,7 +98,6 @@ static LIST_HEAD(apm_user_list); | |||
97 | * to be suspending the system. | 98 | * to be suspending the system. |
98 | */ | 99 | */ |
99 | static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); | 100 | static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); |
100 | static DECLARE_COMPLETION(kapmd_exit); | ||
101 | static DEFINE_SPINLOCK(kapmd_queue_lock); | 101 | static DEFINE_SPINLOCK(kapmd_queue_lock); |
102 | static struct apm_queue kapmd_queue; | 102 | static struct apm_queue kapmd_queue; |
103 | 103 | ||
@@ -468,16 +468,13 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) | |||
468 | 468 | ||
469 | static int kapmd(void *arg) | 469 | static int kapmd(void *arg) |
470 | { | 470 | { |
471 | daemonize("kapmd"); | ||
472 | current->flags |= PF_NOFREEZE; | ||
473 | |||
474 | do { | 471 | do { |
475 | apm_event_t event; | 472 | apm_event_t event; |
476 | 473 | ||
477 | wait_event_interruptible(kapmd_wait, | 474 | wait_event_interruptible(kapmd_wait, |
478 | !queue_empty(&kapmd_queue) || !arm_apm_active); | 475 | !queue_empty(&kapmd_queue) || kthread_should_stop()); |
479 | 476 | ||
480 | if (!arm_apm_active) | 477 | if (kthread_should_stop()) |
481 | break; | 478 | break; |
482 | 479 | ||
483 | spin_lock_irq(&kapmd_queue_lock); | 480 | spin_lock_irq(&kapmd_queue_lock); |
@@ -508,7 +505,7 @@ static int kapmd(void *arg) | |||
508 | } | 505 | } |
509 | } while (1); | 506 | } while (1); |
510 | 507 | ||
511 | complete_and_exit(&kapmd_exit, 0); | 508 | return 0; |
512 | } | 509 | } |
513 | 510 | ||
514 | static int __init apm_init(void) | 511 | static int __init apm_init(void) |
@@ -520,13 +517,14 @@ static int __init apm_init(void) | |||
520 | return -ENODEV; | 517 | return -ENODEV; |
521 | } | 518 | } |
522 | 519 | ||
523 | arm_apm_active = 1; | 520 | kapmd_tsk = kthread_create(kapmd, NULL, "kapmd"); |
524 | 521 | if (IS_ERR(kapmd_tsk)) { | |
525 | ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); | 522 | ret = PTR_ERR(kapmd_tsk); |
526 | if (ret < 0) { | 523 | kapmd_tsk = NULL; |
527 | arm_apm_active = 0; | ||
528 | return ret; | 524 | return ret; |
529 | } | 525 | } |
526 | kapmd_tsk->flags |= PF_NOFREEZE; | ||
527 | wake_up_process(kapmd_tsk); | ||
530 | 528 | ||
531 | #ifdef CONFIG_PROC_FS | 529 | #ifdef CONFIG_PROC_FS |
532 | create_proc_info_entry("apm", 0, NULL, apm_get_info); | 530 | create_proc_info_entry("apm", 0, NULL, apm_get_info); |
@@ -535,10 +533,7 @@ static int __init apm_init(void) | |||
535 | ret = misc_register(&apm_device); | 533 | ret = misc_register(&apm_device); |
536 | if (ret != 0) { | 534 | if (ret != 0) { |
537 | remove_proc_entry("apm", NULL); | 535 | remove_proc_entry("apm", NULL); |
538 | 536 | kthread_stop(kapmd_tsk); | |
539 | arm_apm_active = 0; | ||
540 | wake_up(&kapmd_wait); | ||
541 | wait_for_completion(&kapmd_exit); | ||
542 | } | 537 | } |
543 | 538 | ||
544 | return ret; | 539 | return ret; |
@@ -549,9 +544,7 @@ static void __exit apm_exit(void) | |||
549 | misc_deregister(&apm_device); | 544 | misc_deregister(&apm_device); |
550 | remove_proc_entry("apm", NULL); | 545 | remove_proc_entry("apm", NULL); |
551 | 546 | ||
552 | arm_apm_active = 0; | 547 | kthread_stop(kapmd_tsk); |
553 | wake_up(&kapmd_wait); | ||
554 | wait_for_completion(&kapmd_exit); | ||
555 | } | 548 | } |
556 | 549 | ||
557 | module_init(apm_init); | 550 | module_init(apm_init); |