Hi Linus,

This patch (against 2.3.99pre4-4) does the following:

        Allow user mode programs to reject standby and suspend operations.
        Make power off work on SMP again.
        Add APM_IOC_ENABLE.
        Use set_current_state.
        Make CONFIG_APM_CPU_IDLE boot time settable.
        Make CONFIG_APM_REAL_MODE_POWER_OFF boot time settable.
        Make CONFIG_APM_RTC_IS_GMT boot time settable.
        Remove CONFIG_APM_IGNORE_USER_SUSPEND as this can now be done by
                rejecting USER_SUSPEND events from user mode i.e. in apmd.
        Add APM_IOC_LAST_ERROR.

Could you please apply this as the first three items above are very
important to various people.

This patch is also available on the apm web page at
http://linuxcare.com.au/apm/

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.99pre4-4/Documentation/Configure.help 
2.3.99pre4-4-APM/Documentation/Configure.help
--- 2.3.99pre4-4/Documentation/Configure.help   Wed Apr  5 12:49:02 2000
+++ 2.3.99pre4-4-APM/Documentation/Configure.help       Wed Apr  5 12:58:05 2000
@@ -12206,12 +12206,6 @@
   and read Documentation/modules.txt. The module will be called
   apm.o.
 
-Ignore USER SUSPEND
-CONFIG_APM_IGNORE_USER_SUSPEND
-  This option will ignore USER SUSPEND requests. On machines with a
-  compliant APM BIOS, you want to say N. However, on the NEC Versa M
-  series notebooks, it is necessary to say Y because of a BIOS bug.
-
 Enable APM at boot time
 CONFIG_APM_DO_ENABLE
   Enable APM features at boot time. From page 36 of the APM BIOS
@@ -12238,6 +12232,10 @@
   whenever the CPU becomes idle. (On machines with more than one CPU,
   this option does nothing.)
 
+  This just sets the default behaviour and may be modified using the
+  "apm=do_idle" kernel command line option or the do_idle module
+  option.
+
 Enable console blanking using APM
 CONFIG_APM_DISPLAY_BLANK
   Enable console blanking using the APM. Some laptops can use this to
@@ -12278,6 +12276,10 @@
   reason not to use GMT in your RTC is if you also run a broken OS
   that doesn't understand GMT.
 
+  This just sets the default behaviour and may be modified using the
+  "apm=rtc_is_gmt" kernel command line option or the rtc_is_gmt module
+  option.
+
 Allow interrupts during APM BIOS calls
 CONFIG_APM_ALLOW_INTS
   Normally we disable external interrupts while we are making calls to
@@ -12292,6 +12294,10 @@
   Use real mode APM BIOS calls to switch off the computer. This is
   a work-around for a number of buggy BIOSes. Switch this option on if
   your computer crashes instead of powering off properly.
+
+  This just sets the default behaviour and may be modified using the
+  "apm=real_mode_power_off" kernel command line option or the
+  real_mode_power_off module option.
 
 Watchdog Timer Support 
 CONFIG_WATCHDOG
diff -ruN 2.3.99pre4-4/arch/i386/kernel/apm.c 2.3.99pre4-4-APM/arch/i386/kernel/apm.c
--- 2.3.99pre4-4/arch/i386/kernel/apm.c Fri Mar 10 12:15:02 2000
+++ 2.3.99pre4-4-APM/arch/i386/kernel/apm.c     Wed Apr  5 12:58:05 2000
@@ -132,6 +132,19 @@
  *   1.13: Changes for new pm_ interfaces (Andy Henroid
  *         <[EMAIL PROTECTED]>).
  *         Modularize the code.
+ *   1.14: Allow user mode programs to reject standby and suspend
+ *         operations (Craig Markwardt <[EMAIL PROTECTED]>).
+ *         Make power off work on SMP again (Tony Hoyle
+ *         <[EMAIL PROTECTED]> and <[EMAIL PROTECTED]>) modified by sfr.
+ *         Use set_current_state (Richard Gooch <[EMAIL PROTECTED]>).
+ *   1.15: Make CONFIG_APM_CPU_IDLE boot time settable.
+ *         Make CONFIG_APM_REAL_MODE_POWER_OFF boot time settable.
+ *         Make CONFIG_APM_RTC_IS_GMT boot time settable.
+ *         Remove CONFIG_APM_IGNORE_USER_SUSPEND as this can now be
+ *         done by rejecting USER_SUSPEND events from user mode i.e.
+ *         in apmd.
+ *         Add APM_IOC_ENABLE (Edward A. Falk <[EMAIL PROTECTED]>).
+ *         Add APM_IOC_LAST_ERROR.
  *
  * APM 1.1 Reference:
  *
@@ -197,6 +210,10 @@
  *     apm=on/off                      enable/disable APM
  *         [no-]debug                  log some debugging messages
  *         [no-]power[-_]off           power off on shutdown
+ *         [no-]do[-_]idle             do BIOS idle calls
+ *         [no-]real[-_]mode[-_]power[-_]off   switch to real mode before
+ *                                     powering off
+ *         [no-]rtc[-_]is[-_]gmt       assume the RTC stores GMT
  */
 
 /* KNOWN PROBLEM MACHINES:
@@ -286,6 +303,8 @@
        int             standbys_pending;
        int             suspends_read;
        int             standbys_read;
+       int             rejects_pending;
+       int             last_error;
        int             event_head;
        int             event_tail;
        apm_event_t     events[APM_MAX_EVENTS];
@@ -303,37 +322,46 @@
        unsigned long   offset;
        unsigned short  segment;
 }                              apm_bios_entry;
+static int                     clock_slowed;
 #ifdef CONFIG_APM_CPU_IDLE
-static int                     clock_slowed = 0;
+static int                     do_idle = 1;
+#else
+static int                     do_idle;
 #endif
-static int                     suspends_pending = 0;
-static int                     standbys_pending = 0;
+static int                     rejects_pending;
+static int                     suspends_pending;
+static int                     standbys_pending;
 #ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
-static int                     waiting_for_resume = 0;
+static int                     waiting_for_resume;
 #endif
 
 #ifdef CONFIG_APM_RTC_IS_GMT
-#      define  clock_cmos_diff 0
-#      define  got_clock_diff  1
+static int                     rtc_is_gmt = 1;
 #else
-static long                    clock_cmos_diff;
-static int                     got_clock_diff = 0;
+static int                     rtc_is_gmt;
 #endif
-static int                     debug = 0;
-static int                     apm_disabled = 0;
+static long                    clock_cmos_diff;
+static int                     got_clock_diff;
+static int                     debug;
+static int                     apm_disabled;
 #ifdef CONFIG_SMP
-static int                     power_off = 0;
+static int                     power_off;
 #else
 static int                     power_off = 1;
 #endif
-static int                     exit_kapmd = 0;
-static int                     kapmd_running = 0;
+static int                     exit_kapmd;
+static int                     kapmd_running;
+#ifdef CONFIG_APM_REAL_MODE_POWER_OFF
+static int                     real_mode_power_off = 1;
+#else
+static int                     real_mode_power_off;
+#endif
 
 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
 static struct apm_user *       user_list = NULL;
 
-static char                    driver_version[] = "1.13";      /* no spaces */
+static char                    driver_version[] = "1.15";      /* no spaces */
 
 static char *  apm_event_name[] = {
        "system standby",
@@ -452,7 +480,11 @@
                : "memory", "cc");
        APM_DO_RESTORE_SEGS;
        __restore_flags(flags);
-       return *eax & 0xff;
+       if (*eax & 0xff) {
+               *eax = (*eax >> 8) & 0xff;
+               return 1;
+       }
+       return 0;
 }
 
 /*
@@ -490,6 +522,8 @@
        }
        APM_DO_RESTORE_SEGS;
        __restore_flags(flags);
+       if (error)
+               *eax = (*eax >> 8) & 0xff;
        return error;
 }
 
@@ -498,7 +532,7 @@
        u32     eax;
 
        if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
-               return (eax >> 8) & 0xff;
+               return eax;
        *val = eax;
        return APM_SUCCESS;
 }
@@ -512,7 +546,7 @@
 
        if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
                        &dummy, &dummy))
-               return (eax >> 8) & 0xff;
+               return eax;
        *event = ebx;
        if (apm_bios_info.version < 0x0102)
                *info = ~0; /* indicate info not valid */
@@ -526,7 +560,7 @@
        u32     eax;
 
        if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
-               return (eax >> 8) & 0xff;
+               return eax;
        return APM_SUCCESS;
 }
 
@@ -535,7 +569,6 @@
        return set_power_state(APM_DEVICE_ALL, state);
 }
 
-#ifdef CONFIG_APM_CPU_IDLE
 static int apm_do_idle(void)
 {
        u32     dummy;
@@ -610,7 +643,6 @@
        }
 }
 #endif
-#endif
 
 #ifdef CONFIG_SMP
 static int apm_magic(void * unused)
@@ -622,7 +654,6 @@
 
 static void apm_power_off(void)
 {
-#ifdef CONFIG_APM_REAL_MODE_POWER_OFF
        unsigned char   po_bios_call[] = {
                0xb8, 0x00, 0x10,       /* movw  $0x1000,ax  */
                0x8e, 0xd0,             /* movw  ax,ss       */
@@ -632,7 +663,6 @@
                0xb9, 0x03, 0x00,       /* movw  $0x0003,cx  */
                0xcd, 0x15              /* int   $0x15       */
        };
-#endif
 
        /*
         * This may be called on an SMP machine.
@@ -645,11 +675,10 @@
                schedule();
        }
 #endif
-#ifdef CONFIG_APM_REAL_MODE_POWER_OFF
-       machine_real_restart(po_bios_call, sizeof(po_bios_call));
-#else
-       (void) apm_set_power_state(APM_STATE_OFF);
-#endif
+       if (real_mode_power_off)
+               machine_real_restart(po_bios_call, sizeof(po_bios_call));
+       else
+               (void) apm_set_power_state(APM_STATE_OFF);
 }
 
 static int apm_enable_power_management(int enable)
@@ -660,7 +689,7 @@
                return APM_NOT_ENGAGED;
        if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
                        enable, &eax))
-               return (eax >> 8) & 0xff;
+               return eax;
        if (enable)
                apm_bios_info.flags &= ~APM_BIOS_DISABLED;
        else
@@ -678,7 +707,7 @@
 
        if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
                        &eax, &ebx, &ecx, &edx, &dummy))
-               return (eax >> 8) & 0xff;
+               return eax;
        *status = ebx;
        *bat = ecx;
        *life = edx;
@@ -705,7 +734,7 @@
 
        if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax,
                        &ebx, &ecx, &edx, &esi))
-               return (eax >> 8) & 0xff;
+               return eax;
        *status = ebx;
        *bat = ecx;
        *life = edx;
@@ -722,7 +751,7 @@
            && (apm_bios_info.flags & APM_BIOS_DISABLED))
                return APM_DISABLED;
        if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, &eax))
-               return (eax >> 8) & 0xff;
+               return eax;
        if (device == APM_DEVICE_ALL) {
                if (enable)
                        apm_bios_info.flags &= ~APM_BIOS_DISENGAGED;
@@ -779,7 +808,8 @@
        return as->events[as->event_tail];
 }
 
-static void queue_event(apm_event_t event, struct apm_user *sender)
+static void queue_event(apm_event_t event, struct apm_user *sender,
+                       int reject_flag)
 {
        struct apm_user *       as;
 
@@ -811,9 +841,25 @@
                        as->standbys_pending++;
                        standbys_pending++;
                        break;
+
+               case APM_NORMAL_RESUME:
+                       if (reject_flag) {
+                               as->suspend_wait = 0;
+                               as->suspend_result = -EAGAIN;
+                               as->last_error = APM_SUCCESS;
+                       }
+                       /* Fall through to */
+               case APM_STANDBY_RESUME:
+                       if (reject_flag) {
+                               as->rejects_pending++;
+                               rejects_pending++;
+                       }
+                       break;
                }
        }
        wake_up_interruptible(&apm_waitqueue);
+       if (reject_flag && (event == APM_NORMAL_RESUME))
+               wake_up_interruptible(&apm_suspend_waitqueue);
 }
 
 static void set_time(void)
@@ -830,19 +876,19 @@
 
 static void get_time_diff(void)
 {
-#ifndef CONFIG_APM_RTC_IS_GMT
        unsigned long   flags;
 
-       /*
-        * Estimate time zone so that set_time can update the clock
-        */
-       save_flags(flags);
-       clock_cmos_diff = -get_cmos_time();
-       cli();
-       clock_cmos_diff += CURRENT_TIME;
+       if (rtc_is_gmt) {
+               /*
+                * Estimate time zone so that set_time can update the clock
+                */
+               clock_cmos_diff = -get_cmos_time();
+               save_flags(flags);
+               cli();
+               clock_cmos_diff += CURRENT_TIME;
+               restore_flags(flags);
+       }
        got_clock_diff = 1;
-       restore_flags(flags);
-#endif
 }
 
 static void reinit_timer(void)
@@ -866,32 +912,36 @@
 static int suspend(void)
 {
        int             err;
-       int             ret;
        struct apm_user *as;
 
        get_time_diff();
        err = apm_set_power_state(APM_STATE_SUSPEND);
        reinit_timer();
        set_time();
-       ret = (err == APM_SUCCESS) || (err == APM_NO_ERROR);
-       if (!ret)
+       if (err == APM_NO_ERROR)
+               err = APM_SUCCESS;
+       if (err != APM_SUCCESS)
                apm_error("suspend", err);
        for (as = user_list; as != NULL; as = as->next) {
                as->suspend_wait = 0;
-               as->suspend_result = (ret ? 0 : -EIO);
+               as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO);
+               as->last_error = err;
        }
        wake_up_interruptible(&apm_suspend_waitqueue);
-       return ret;
+       return err;
 }
 
-static void standby(void)
+static int standby(void)
 {
        int     err;
 
        get_time_diff();
        err = apm_set_power_state(APM_STATE_STANDBY);
-       if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
+       if (err == APM_NO_ERROR)
+               err = APM_SUCCESS;
+       if (err != APM_SUCCESS)
                apm_error("standby", err);
+       return err;
 }
 
 static apm_event_t get_event(void)
@@ -933,10 +983,15 @@
                break;
        }
 
-       queue_event(event, sender);
+       queue_event(event, sender, 0);
        return 1;
 }
 
+static void unsend_event(apm_event_t event)
+{
+       (void) pm_send_all(PM_RESUME, (void *)0);
+}
+
 static void check_events(void)
 {
        apm_event_t             event;
@@ -971,16 +1026,11 @@
                                waiting_for_resume = 1;
 #endif
                                if (standbys_pending <= 0)
-                                       standby();
+                                       (void) standby();
                        }
                        break;
 
                case APM_USER_SUSPEND:
-#ifdef CONFIG_APM_IGNORE_USER_SUSPEND
-                       if (apm_bios_info.version > 0x100)
-                               apm_set_power_state(APM_STATE_REJECT);
-                       break;
-#endif
                case APM_SYS_SUSPEND:
 #ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
                        if (ignore_bounce)
@@ -1060,11 +1110,8 @@
 {
        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 */
                schedule_timeout(APM_CHECK_TIMEOUT);
@@ -1075,22 +1122,22 @@
                 * 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 (!do_idle)
+                       continue;
                if (!system_idle())
                        continue;
                if (apm_do_idle()) {
                        unsigned long start = jiffies;
                        while (system_idle()) {
                                apm_do_idle();
-                               if (jiffies - start > APM_CHECK_TIMEOUT)
+                               if ((jiffies - start) > APM_CHECK_TIMEOUT)
                                        break;
                        }
                        apm_do_busy();
                        apm_event_handler();
                }
-#endif
        }
 }
 
@@ -1125,7 +1172,7 @@
                        schedule();
                        goto repeat;
                }
-               current->state = TASK_RUNNING;
+               set_current_state(TASK_RUNNING);
                remove_wait_queue(&apm_waitqueue, &wait);
        }
        i = count;
@@ -1170,9 +1217,44 @@
        return 0;
 }
 
+static void apm_send_reject(struct apm_user *as, apm_event_t state)
+{
+       if (as->rejects_pending > 0) {
+               as->rejects_pending--;
+               rejects_pending--;
+       } else {
+               switch (state) {
+               case APM_SYS_SUSPEND:
+               case APM_USER_SUSPEND:
+                       queue_event(APM_NORMAL_RESUME, as, 1);
+                       break;
+               case APM_SYS_STANDBY:
+               case APM_USER_STANDBY:
+                       queue_event(APM_STANDBY_RESUME, as, 1);
+                       break;
+               }
+       }
+       if ((rejects_pending <= 0) &&
+           (suspends_pending <= 0) &&
+           (standbys_pending <= 0)) {
+               switch (state) {
+               case APM_SYS_SUSPEND:
+               case APM_USER_SUSPEND:
+                       unsend_event(APM_NORMAL_RESUME);
+                       break;
+               case APM_SYS_STANDBY:
+               case APM_USER_STANDBY:
+                       unsend_event(APM_STANDBY_RESUME);
+                       break;
+               }
+               apm_set_power_state(APM_STATE_REJECT);
+       }
+}
+
 static int do_ioctl(struct inode * inode, struct file *filp,
                    u_int cmd, u_long arg)
 {
+       int                     int_arg;
        struct apm_user *       as;
        DECLARE_WAITQUEUE(wait, current);
 
@@ -1190,7 +1272,7 @@
                } else if (!send_event(APM_USER_STANDBY, as))
                        return -EAGAIN;
                if (standbys_pending <= 0)
-                       standby();
+                       as->last_error = standby();
                break;
        case APM_IOC_SUSPEND:
                if (as->suspends_read > 0) {
@@ -1200,7 +1282,8 @@
                } else if (!send_event(APM_USER_SUSPEND, as))
                        return -EAGAIN;
                if (suspends_pending <= 0) {
-                       if (!suspend())
+                       as->last_error = suspend();
+                       if (as->last_error != APM_SUCCESS)
                                return -EIO;
                } else {
                        as->suspend_wait = 1;
@@ -1212,11 +1295,34 @@
                                        break;
                                schedule();
                        }
-                       current->state = TASK_RUNNING;
+                       set_current_state(TASK_RUNNING);
                        remove_wait_queue(&apm_suspend_waitqueue, &wait);
                        return as->suspend_result;
                }
                break;
+       case APM_IOC_REJECT:
+               if (as->suspends_read > 0) {
+                       as->suspends_read--;
+                       as->suspends_pending--;
+                       suspends_pending--;
+                       apm_send_reject(as, APM_SYS_SUSPEND);
+               } else if (as->standbys_read > 0) {
+                       as->standbys_read--;
+                       as->standbys_pending--;
+                       standbys_pending--;
+                       apm_send_reject(as, APM_SYS_STANDBY);
+               } else
+                       return -EINVAL;
+               break;
+       case APM_IOC_ENABLE:
+               get_user_ret(int_arg, (int *)arg, -EFAULT);
+               as->last_error = apm_enable_power_management(int_arg);
+               if (as->last_error != APM_SUCCESS)
+                       return -EIO;
+               break;
+       case APM_IOC_LAST_ERROR:
+               put_user_ret(as->last_error, (int *)arg, -EFAULT);
+               break;
        default:
                return -EINVAL;
        }
@@ -1233,12 +1339,15 @@
        filp->private_data = NULL;
        if (as->standbys_pending > 0) {
                standbys_pending -= as->standbys_pending;
-               if (standbys_pending <= 0)
-                       standby();
+               rejects_pending -= as->rejects_pending;
+               as->rejects_pending = 0;
+               if ((standbys_pending <= 0) && (rejects_pending <=0))
+                       (void) standby();
        }
        if (as->suspends_pending > 0) {
                suspends_pending -= as->suspends_pending;
-               if (suspends_pending <= 0)
+               rejects_pending -= as->rejects_pending;
+               if ((suspends_pending <= 0) && (rejects_pending <=0))
                        (void) suspend();
        }
        if (user_list == as)
@@ -1277,6 +1386,7 @@
        as->event_tail = as->event_head = 0;
        as->suspends_pending = as->standbys_pending = 0;
        as->suspends_read = as->standbys_read = 0;
+       as->rejects_pending = 0;
        /*
         * XXX - this is a tiny bit broken, when we consider BSD
          * process accounting. If the device is opened by root, we
@@ -1475,27 +1585,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;
@@ -1518,6 +1616,15 @@
                if ((strncmp(str, "power-off", 9) == 0) ||
                    (strncmp(str, "power_off", 9) == 0))
                        power_off = !invert;
+               if ((strncmp(str, "do-idle", 7) == 0) ||
+                   (strncmp(str, "do_idle", 7) == 0))
+                       do_idle = !invert;
+               if ((strncmp(str, "real-mode-power-off", 19) == 0) ||
+                   (strncmp(str, "real_mode_power_off", 19) == 0))
+                       real_mode_power_off = !invert;
+               if ((strncmp(str, "rtc-is-gmt", 10) == 0) ||
+                   (strncmp(str, "rtc_is_gmt", 10) == 0))
+                       rtc_is_gmt = !invert;
                str = strchr(str, ',');
                if (str != NULL)
                        str += strspn(str, ", \t");
@@ -1606,6 +1713,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
@@ -1664,9 +1772,18 @@
 {
        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);
@@ -1676,5 +1793,13 @@
 MODULE_DESCRIPTION("Advanced Power Management");
 MODULE_PARM(debug, "i");
 MODULE_PARM_DESC(debug, "Enable debug mode");
+MODULE_PARM(power_off, "i");
+MODULE_PARM_DESC(power_off, "Enable power off");
+MODULE_PARM(do_idle, "i");
+MODULE_PARM_DESC(do_idle, "Enable calls to BIOS idle routine");
+MODULE_PARM(real_mode_power_off, "i");
+MODULE_PARM_DESC(real_mode_power_off, "Switch to real mode bfore powering off");
+MODULE_PARM(rtc_is_gmt, "i");
+MODULE_PARM_DESC(rtc_is_gmt, "The real time clock stores GMT");
 
 EXPORT_NO_SYMBOLS;
diff -ruN 2.3.99pre4-4/arch/i386/kernel/i386_ksyms.c 
2.3.99pre4-4-APM/arch/i386/kernel/i386_ksyms.c
--- 2.3.99pre4-4/arch/i386/kernel/i386_ksyms.c  Thu Mar 16 06:08:04 2000
+++ 2.3.99pre4-4-APM/arch/i386/kernel/i386_ksyms.c      Wed Apr  5 12:58:05 2000
@@ -26,6 +26,7 @@
 extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(elf_fpregset_t *);
 extern spinlock_t rtc_lock;
+extern void machine_real_restart(unsigned char *, int);
 
 #ifdef CONFIG_SMP
 extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
@@ -58,6 +59,7 @@
 EXPORT_SYMBOL(pm_power_off);
 EXPORT_SYMBOL(get_cmos_time);
 EXPORT_SYMBOL(apm_bios_info);
+EXPORT_SYMBOL(machine_real_restart);
 EXPORT_SYMBOL(gdt);
 
 EXPORT_SYMBOL_NOVERS(__down_failed);
diff -ruN 2.3.99pre4-4/include/linux/apm_bios.h 
2.3.99pre4-4-APM/include/linux/apm_bios.h
--- 2.3.99pre4-4/include/linux/apm_bios.h       Mon Feb 21 15:37:09 2000
+++ 2.3.99pre4-4-APM/include/linux/apm_bios.h   Wed Apr  5 12:58:05 2000
@@ -204,5 +204,8 @@
 
 #define APM_IOC_STANDBY                _IO('A', 1)
 #define APM_IOC_SUSPEND                _IO('A', 2)
+#define APM_IOC_REJECT         _IO('A', 3)
+#define APM_IOC_ENABLE         _IOW('A', 4, int)
+#define APM_IOC_LAST_ERROR     _IOR('A', 5, int)
 
 #endif /* LINUX_APM_H */

Reply via email to