Hi Alan,

This is realtive to the patch I just sent you and should
fix the problems with powering down SMP boxes using APM.

Tony Hoyle <[EMAIL PROTECTED]> writes:
> > 
> Also can I suggest...
> 
> > To Do But Non Showstopper
> > -------------------------
> 
> Merge in one of the SMP apm=power-off fixes (there have been several posted recently)

Cheers,
Stephen
-- 
Stephen Rothwell, Open Source Project Engineer, Linuxcare, Inc.
+61-2-62628990 tel, +61-2-62628991 fax 
[EMAIL PROTECTED], http://www.linuxcare.com/ 
Linuxcare. Support for the revolution.

diff -ruN 2.3.99pre10-3-APM.1/arch/i386/kernel/apm.c 
2.3.99pre10-3-APM.2/arch/i386/kernel/apm.c
--- 2.3.99pre10-3-APM.1/arch/i386/kernel/apm.c  Fri May 26 17:37:08 2000
+++ 2.3.99pre10-3-APM.2/arch/i386/kernel/apm.c  Fri May 26 18:38:26 2000
@@ -140,6 +140,8 @@
  *         modified by sfr).
  *         Disable interrupts while we are suspended (Andy Henroid
  *         <[EMAIL PROTECTED]> fixed by sfr).
+ *         Make power off work on SMP again (Tony Hoyle
+ *         <[EMAIL PROTECTED]> and <[EMAIL PROTECTED]>) modified by sfr.
  *
  * APM 1.1 Reference:
  *
@@ -1082,11 +1084,8 @@
        int timeout = HZ;
        DECLARE_WAITQUEUE(wait, current);
 
-       if (smp_num_cpus > 1)
-               return;
-
        add_wait_queue(&apm_waitqueue, &wait);
-       current->state = TASK_INTERRUPTIBLE;
+       set_current_state(TASK_INTERRUPTIBLE);
        for (;;) {
                /* Nothing to do, just sleep for the timeout */
                timeout = 2*timeout;
@@ -1100,7 +1099,7 @@
                 * Ok, check all events, check for idle (and mark us sleeping
                 * so as not to count towards the load average)..
                 */
-               current->state = TASK_INTERRUPTIBLE;
+               set_current_state(TASK_INTERRUPTIBLE);
                apm_event_handler();
 #ifdef CONFIG_APM_CPU_IDLE
                if (!system_idle())
@@ -1109,7 +1108,7 @@
                        unsigned long start = jiffies;
                        while ((!exit_kapmd) && system_idle()) {
                                apm_do_idle();
-                               if (jiffies - start > APM_CHECK_TIMEOUT) {
+                               if ((jiffies - start) > APM_CHECK_TIMEOUT) {
                                        apm_event_handler();
                                        start = jiffies;
                                }
@@ -1153,7 +1152,7 @@
                        schedule();
                        goto repeat;
                }
-               current->state = TASK_RUNNING;
+               set_current_state(TASK_RUNNING);
                remove_wait_queue(&apm_waitqueue, &wait);
        }
        i = count;
@@ -1244,7 +1243,7 @@
                                        break;
                                schedule();
                        }
-                       current->state = TASK_RUNNING;
+                       set_current_state(TASK_RUNNING);
                        remove_wait_queue(&apm_suspend_waitqueue, &wait);
                        return as->suspend_result;
                }
@@ -1508,27 +1507,15 @@
 #ifdef CONFIG_MAGIC_SYSRQ
        sysrq_power_off = apm_power_off;
 #endif
+       if (smp_num_cpus == 1) {
 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
-       if (smp_num_cpus == 1)
                console_blank_hook = apm_console_blank;
 #endif
-
-       pm_active = 1;
-
-       apm_mainloop();
-
-       pm_active = 0;
-
+               apm_mainloop();
 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
-       if (smp_num_cpus == 1)
                console_blank_hook = NULL;
 #endif
-#ifdef CONFIG_MAGIC_SYSRQ
-       sysrq_power_off = NULL;
-#endif
-       if (power_off)
-               pm_power_off = NULL;
-
+       }
        kapmd_running = 0;
 
        return 0;
@@ -1639,6 +1626,7 @@
                printk(KERN_NOTICE "apm: overridden by ACPI.\n");
                APM_INIT_ERROR_RETURN;
        }
+       pm_active = 1;
 
        /*
         * Set up a segment that references the real mode segment 0x40
@@ -1697,9 +1685,15 @@
 {
        misc_deregister(&apm_device);
        remove_proc_entry("apm", NULL);
+#ifdef CONFIG_MAGIC_SYSRQ
+       sysrq_power_off = NULL;
+#endif
+       if (power_off)
+               pm_power_off = NULL;
        exit_kapmd = 1;
        while (kapmd_running)
                schedule();
+       pm_active = 0;
 }
 
 module_init(apm_init);

Reply via email to