#include <linux/smp_lock.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
+#include <linux/kthread.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #else
 static int                     realmode_power_off;
 #endif
-static int                     exit_kapmd __read_mostly;
-static int                     kapmd_running __read_mostly;
 #ifdef CONFIG_APM_ALLOW_INTS
 static int                     allow_ints = 1;
 #else
 
 static const char              driver_version[] = "1.16ac";    /* no spaces */
 
+static struct task_struct *kapmd_task;
+
 /*
  *     APM event names taken from the APM 1.2 specification. These are
  *     the message codes that the BIOS uses to tell us about events
        set_current_state(TASK_INTERRUPTIBLE);
        for (;;) {
                schedule_timeout(APM_CHECK_TIMEOUT);
-               if (exit_kapmd)
+               if (kthread_should_stop())
                        break;
                /*
                 * Ok, check all events, check for idle (and mark us sleeping
        char *          power_stat;
        char *          bat_stat;
 
-       kapmd_running = 1;
-
-       daemonize("kapmd");
-
-       current->flags |= PF_NOFREEZE;
-
 #ifdef CONFIG_SMP
        /* 2002/08/01 - WT
         * This is to avoid random crashes at boot time during initialization
                console_blank_hook = NULL;
 #endif
        }
-       kapmd_running = 0;
 
        return 0;
 }
 {
        struct proc_dir_entry *apm_proc;
        struct desc_struct *gdt;
-       int ret;
+       int err;
 
        dmi_check_system(apm_dmi_table);
 
        if (apm_proc)
                apm_proc->owner = THIS_MODULE;
 
-       ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD);
-       if (ret < 0) {
-               printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n");
+       kapmd_task = kthread_create(apm, NULL, "kapmd");
+       if (IS_ERR(kapmd_task)) {
+               printk(KERN_ERR "apm: disabled - Unable to start kernel "
+                               "thread.\n");
+               err = PTR_ERR(kapmd_task);
+               kapmd_task = NULL;
                remove_proc_entry("apm", NULL);
-               return -ENOMEM;
+               return err;
        }
+       kapmd_task->flags |= PF_NOFREEZE;
+       wake_up_process(kapmd_task);
 
        if (num_online_cpus() > 1 && !smp ) {
                printk(KERN_NOTICE
        remove_proc_entry("apm", NULL);
        if (power_off)
                pm_power_off = NULL;
-       exit_kapmd = 1;
-       while (kapmd_running)
-               schedule();
+       if (kapmd_task) {
+               kthread_stop(kapmd_task);
+               kapmd_task = NULL;
+       }
 #ifdef CONFIG_PM_LEGACY
        pm_active = 0;
 #endif