aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/apm.c33
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 */
81static int suspends_pending; 82static int suspends_pending;
82static int apm_disabled; 83static int apm_disabled;
83static int arm_apm_active; 84static struct task_struct *kapmd_tsk;
84 85
85static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); 86static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
86static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); 87static 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 */
99static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); 100static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
100static DECLARE_COMPLETION(kapmd_exit);
101static DEFINE_SPINLOCK(kapmd_queue_lock); 101static DEFINE_SPINLOCK(kapmd_queue_lock);
102static struct apm_queue kapmd_queue; 102static 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
469static int kapmd(void *arg) 469static 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
514static int __init apm_init(void) 511static 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
557module_init(apm_init); 550module_init(apm_init);