lkml.org 
[lkml]   [1998]   [Nov]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] APM fixes, workarounds and tidying
Date
From
Hi Linus,

Could you apply this patch to 2.1.130, please. It is an aggregation
of patches from various people to fix or work around various
problems they are having.

Summary:
keep /proc/apm consistant
Reset interrupt 0 timer to 100Hz after suspend
Add CONFIG_APM_IGNORE_SUSPEND_BOUNCE
Allow boot time disabling of APM
Make boot messages far less verbose by default
Make asm safer

Cheers,
Stephen
--
Stephen Rothwell Stephen.Rothwell@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

diff -ru linux-2.1.130/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.1.130/Documentation/Configure.help Sat Nov 28 23:57:36 1998
+++ linux/Documentation/Configure.help Sun Nov 29 04:03:55 1998
@@ -8328,6 +8328,16 @@
ignored. Without this the Thinkpad 560 has troubles with the user
level daemon apmd, and with the PCMCIA package pcmcia-cs.

+Ignore multiple suspend/resume cycles
+CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ This option is necessary on the Dell Inspiron 3200, but should be
+ safe for all other laptops. When enabled, a system suspend event
+ that occurs within one second of a resume is ignored. Without this
+ the Inspiron will shut itself off a few seconds after you open the
+ lid, requiring you to press the power button to resume it a second
+ time.
+ Say Y.
+
Watchdog Timer Support
CONFIG_WATCHDOG
If you say Y here (and to one of the following options) and create a
diff -ru linux-2.1.130/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- linux-2.1.130/arch/i386/boot/setup.S Fri Oct 9 23:43:07 1998
+++ linux/arch/i386/boot/setup.S Sun Nov 29 01:32:31 1998
@@ -396,8 +396,6 @@
cmp bx,#0x0504d ! check for "PM" signature
jne done_apm_bios ! no signature -> no APM BIOS

- mov [64],ax ! record the APM BIOS version
- mov [76],cx ! and flags
and cx,#0x02 ! Is 32 bit supported?
je done_apm_bios ! no ...

@@ -416,6 +414,26 @@
mov [74],dx ! BIOS data segment
mov [78],esi ! BIOS code segment length
mov [82],di ! BIOS data segment length
+!
+! Redo the installation check as the 32 bit connect
+! modifies the flags returned on some BIOSs
+!
+ mov ax,#0x05300 ! APM BIOS installation check
+ xor bx,bx
+ int 0x15
+ jc apm_disconnect ! error -> should not happen, tidy up
+
+ cmp bx,#0x0504d ! check for "PM" signature
+ jne apm_disconnect ! no signature -> should not happen, tidy up
+
+ mov [64],ax ! record the APM BIOS version
+ mov [76],cx ! and flags
+ jmp done_apm_bios
+
+apm_disconnect:
+ mov ax,#0x05304 ! Disconnect
+ xor bx,bx
+ int 0x15 ! ignore return code
jmp done_apm_bios

no_32_apm_bios:
diff -ru linux-2.1.130/arch/i386/config.in linux/arch/i386/config.in
--- linux-2.1.130/arch/i386/config.in Sun Nov 29 03:51:57 1998
+++ linux/arch/i386/config.in Sun Nov 29 03:51:24 1998
@@ -72,6 +72,7 @@
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
bool ' Power off on shutdown' CONFIG_APM_POWER_OFF
bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
+ bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
fi

endmenu
diff -ru linux-2.1.130/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- linux-2.1.130/arch/i386/kernel/apm.c Fri Oct 9 23:43:07 1998
+++ linux/arch/i386/kernel/apm.c Sun Nov 29 04:18:34 1998
@@ -30,6 +30,7 @@
* Feb 1998, Version 1.4
* Aug 1998, Version 1.5
* Sep 1998, Version 1.6
+ * Nov 1998, Version 1.7
*
* History:
* 0.6b: first version in official kernel, Linux 1.3.46
@@ -60,6 +61,17 @@
* Fix OOPS at power off with no APM BIOS by Jan Echternach
* <echter@informatik.uni-rostock.de>
* Stephen Rothwell
+ * 1.7: Modify driver's cached copy of the disabled/disengaged flags
+ * to reflect current state of APM BIOS.
+ * Chris Rankin <rankinc@bellsouth.net>
+ * Reset interrupt 0 timer to 100Hz after suspend
+ * Chad Miller <cmiller@surfsouth.com>
+ * Add CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ * Richard Gooch <rgooch@atnf.csiro.au>
+ * Allow boot time disabling of APM
+ * Make boot messages far less verbose by default
+ * Make asm safer
+ * Stephen Rothwell
*
* APM 1.1 Reference:
*
@@ -167,7 +179,7 @@
*
* U: TI 4000M TravelMate: BIOS is *NOT* APM compliant
* [Confirmed by TI representative]
- * U: ACER 486DX4/75: uses dseg 0040, in violation of APM specification
+ * ?: ACER 486DX4/75: uses dseg 0040, in violation of APM specification
* [Confirmed by BIOS disassembly]
* [This may work now ...]
* P: Toshiba 1950S: battery life information only gets updated after resume
@@ -215,6 +227,19 @@
#define APM_RELAX_SEGMENTS

/*
+ * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
+ * This patched by Chad Miller <cmiller@surfsouth.com>, orig code by David
+ * Chen <chen@ctpa04.mit.edu>
+ */
+#undef INIT_TIMER_AFTER_SUSPEND
+
+#ifdef INIT_TIMER_AFTER_SUSPEND
+#include <linux/timex.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#endif
+
+/*
* Need to poll the APM BIOS every second
*/
#define APM_CHECK_TIMEOUT (HZ)
@@ -267,13 +292,15 @@

static long clock_cmos_diff;
static int got_clock_diff = 0;
+static int debug = 0;
+static int apm_disabled = 0;

static struct wait_queue * process_list = NULL;
static struct apm_bios_struct * user_list = NULL;

static struct timer_list apm_timer;

-static char driver_version[] = "1.6"; /* no spaces */
+static char driver_version[] = "1.7"; /* no spaces */

#ifdef APM_DEBUG
static char * apm_event_name[] = {
@@ -393,7 +420,7 @@
# define APM_DO_RESTORE_SEGS
#endif

-static inline u8 apm_bios_call(u32 eax_in, u32 ebx_in, u32 ecx_in,
+static u8 apm_bios_call(u32 eax_in, u32 ebx_in, u32 ecx_in,
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
{
unsigned int saved_fs;
@@ -404,13 +431,17 @@
APM_DO_CLI;
APM_DO_SAVE_SEGS;
__asm__ __volatile__(APM_DO_ZERO_SEGS
+ "pushl %%edi\n\t"
+ "pushl %%ebp\n\t"
"lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
"setc %%al\n\t"
+ "popl %%ebp\n\t"
+ "popl %%edi\n\t"
APM_DO_POP_SEGS
- : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
- "=S" (*esi)
+ : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
+ "=S" (*esi)
: "a" (eax_in), "b" (ebx_in), "c" (ecx_in)
- : "ax", "bx", "cx", "dx", "si", "di", "bp", "memory", "cc");
+ : "memory", "cc");
APM_DO_RESTORE_SEGS;
__restore_flags(flags);
return *eax & 0xff;
@@ -420,7 +451,7 @@
* This version only returns one value (usually an error code)
*/

-static inline u8 apm_bios_call_simple(u32 eax_in, u32 ebx_in, u32 ecx_in,
+static u8 apm_bios_call_simple(u32 eax_in, u32 ebx_in, u32 ecx_in,
u32 *eax)
{
u8 error;
@@ -431,13 +462,22 @@
__save_flags(flags);
APM_DO_CLI;
APM_DO_SAVE_SEGS;
- __asm__ __volatile__(APM_DO_ZERO_SEGS
- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
- "setc %%bl\n\t"
- APM_DO_POP_SEGS
- : "=a" (*eax), "=b" (error)
- : "a" (eax_in), "b" (ebx_in), "c" (ecx_in)
- : "ax", "bx", "cx", "dx", "si", "di", "bp", "memory", "cc");
+ {
+ int cx, dx, si;
+
+ __asm__ __volatile__(APM_DO_ZERO_SEGS
+ "pushl %%edi\n\t"
+ "pushl %%ebp\n\t"
+ "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
+ "setc %%bl\n\t"
+ "popl %%ebp\n\t"
+ "popl %%edi\n\t"
+ APM_DO_POP_SEGS
+ : "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
+ "=S" (si)
+ : "a" (eax_in), "b" (ebx_in), "c" (ecx_in)
+ : "memory", "cc");
+ }
APM_DO_RESTORE_SEGS;
__restore_flags(flags);
return error;
@@ -470,7 +510,7 @@
return APM_SUCCESS;
}

-static inline int set_power_state(u_short what, u_short state)
+static int set_power_state(u_short what, u_short state)
{
u32 eax;

@@ -499,7 +539,6 @@
#endif

#ifdef CONFIG_APM_DO_ENABLE
-/* Called by apm_setup if apm_enabled will be true. */
static int apm_enable_power_management(void)
{
u32 eax;
@@ -508,6 +547,7 @@
(apm_bios_info.version > 0x100) ? 0x0001 : 0xffff,
1, &eax))
return (eax >> 8) & 0xff;
+ apm_bios_info.flags &= ~APM_BIOS_DISABLED;
return APM_SUCCESS;
}
#endif
@@ -574,9 +614,10 @@
for (i = 0; i < ERROR_COUNT; i++)
if (error_table[i].key == err) break;
if (i < ERROR_COUNT)
- printk(KERN_NOTICE "apm_bios: %s: %s\n", str, error_table[i].msg);
+ printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
else
- printk(KERN_NOTICE "apm_bios: %s: unknown error code %#2.2x\n", str, err);
+ printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
+ str, err);
}

/* Called from console driver -- must make sure apm_enabled. */
@@ -629,7 +670,6 @@
callback_list_t ** ptr;
callback_list_t * old;

- ptr = &callback_list;
for (ptr = &callback_list; *ptr != NULL; ptr = &(*ptr)->next)
if ((*ptr)->callback == callback)
break;
@@ -663,7 +703,7 @@
static int notified;

if (notified == 0) {
- printk( "apm_bios: an event queue overflowed\n" );
+ printk(KERN_ERR "apm: an event queue overflowed\n");
notified = 1;
}
as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
@@ -719,6 +759,18 @@
err = apm_set_power_state(APM_STATE_SUSPEND);
if (err)
apm_error("suspend", err);
+#ifdef INIT_TIMER_AFTER_SUSPEND
+ save_flags(flags);
+ cli();
+ /* set the clock to 100 Hz */
+ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ udelay(10);
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ udelay(10);
+ outb(LATCH >> 8 , 0x40); /* MSB */
+ udelay(10);
+ restore_flags(flags);
+#endif
set_time();
}

@@ -771,24 +823,27 @@

static void check_events(void)
{
- apm_event_t event;
+ apm_event_t event;
+#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ static unsigned long last_resume = 0;
+ static int did_resume = 0;
+#endif

while ((event = get_event()) != 0) {
#ifdef APM_DEBUG
if (event <= NR_APM_EVENT_NAME)
- printk(KERN_DEBUG "APM BIOS received %s notify\n",
+ printk(KERN_DEBUG "apm: received %s notify\n",
apm_event_name[event - 1]);
else
- printk(KERN_DEBUG "APM BIOS received unknown "
+ printk(KERN_DEBUG "apm: received unknown "
"event 0x%02x\n", event);
#endif
switch (event) {
case APM_SYS_STANDBY:
case APM_USER_STANDBY:
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
- if (waiting_for_resume) {
- return;
- }
+ if (waiting_for_resume)
+ return;
waiting_for_resume = 1;
#endif
send_event(event, APM_STANDBY_RESUME, NULL);
@@ -803,10 +858,13 @@
break;
#endif
case APM_SYS_SUSPEND:
+#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ if (did_resume && ((jiffies - last_resume) < HZ))
+ break;
+#endif
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
- if (waiting_for_resume) {
- return;
- }
+ if (waiting_for_resume)
+ return;
waiting_for_resume = 1;
#endif
send_event(event, APM_NORMAL_RESUME, NULL);
@@ -820,6 +878,10 @@
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
waiting_for_resume = 0;
#endif
+#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ last_resume = jiffies;
+ did_resume = 1;
+#endif
set_time();
send_event(event, 0, NULL);
break;
@@ -905,7 +967,7 @@
static int check_apm_bios_struct(struct apm_bios_struct *as, const char *func)
{
if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
- printk(KERN_ERR "apm_bios: %s passed bad filp", func);
+ printk(KERN_ERR "apm: %s passed bad filp", func);
return 1;
}
return 0;
@@ -1041,7 +1103,7 @@
as1 = as1->next)
;
if (as1 == NULL)
- printk(KERN_ERR "apm_bios: filp not in user list");
+ printk(KERN_ERR "apm: filp not in user list");
else
as1->next = as->next;
}
@@ -1055,7 +1117,7 @@

as = (struct apm_bios_struct *)kmalloc(sizeof(*as), GFP_KERNEL);
if (as == NULL) {
- printk(KERN_ERR "apm_bios: cannot allocate struct of size %d bytes",
+ printk(KERN_ERR "apm: cannot allocate struct of size %d bytes",
sizeof(*as));
return -ENOMEM;
}
@@ -1168,6 +1230,26 @@
}
#endif

+void __init apm_setup(char *str, int *dummy)
+{
+ int invert;
+
+ while ((str != NULL) && (*str != '\0')) {
+ if (strncmp(str, "off", 3) == 0)
+ apm_disabled = 1;
+ if (strncmp(str, "on", 2) == 0)
+ apm_disabled = 0;
+ invert = (strncmp(str, "no-", 3) == 0);
+ if (invert)
+ str += 3;
+ if (strncmp(str, "debug", 5) == 0)
+ debug = !invert;
+ str = strchr(str, ',');
+ if (str != NULL)
+ str += strspn(str, ", \t");
+ }
+}
+
void __init apm_bios_init(void)
{
unsigned short bx;
@@ -1178,23 +1260,18 @@
char * bat_stat;
static struct proc_dir_entry *ent;

-#ifdef __SMP__
- if (smp_num_cpus > 1) {
- printk(KERN_NOTICE "APM disabled: APM is not SMP safe.\n");
- return;
- }
-#endif
if (apm_bios_info.version == 0) {
- printk(KERN_INFO "APM BIOS not found.\n");
+ printk(KERN_INFO "apm: BIOS not found.\n");
return;
}
- printk(KERN_INFO "APM BIOS version %c.%c Flags 0x%02x (Driver version %s)\n",
- ((apm_bios_info.version >> 8) & 0xff) + '0',
- (apm_bios_info.version & 0xff) + '0',
- apm_bios_info.flags,
- driver_version);
+ printk(KERN_INFO
+ "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
+ ((apm_bios_info.version >> 8) & 0xff),
+ (apm_bios_info.version & 0xff),
+ apm_bios_info.flags,
+ driver_version);
if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0) {
- printk(KERN_INFO " No 32 bit BIOS support\n");
+ printk(KERN_INFO "apm: no 32 bit BIOS support\n");
return;
}

@@ -1209,14 +1286,28 @@
if (apm_bios_info.version < 0x102)
apm_bios_info.cseg_16_len = 0xFFFF; /* 64k */

- printk(KERN_INFO " Entry %x:%lx cseg16 %x dseg %x",
- apm_bios_info.cseg, apm_bios_info.offset,
- apm_bios_info.cseg_16, apm_bios_info.dseg);
- if (apm_bios_info.version > 0x100)
- printk(" cseg len %x, cseg16 len %x, dseg len %x",
- apm_bios_info.cseg_len, apm_bios_info.cseg_16_len,
- apm_bios_info.dseg_len);
- printk("\n");
+ if (debug) {
+ printk(KERN_INFO "apm: entry %x:%lx cseg16 %x dseg %x",
+ apm_bios_info.cseg, apm_bios_info.offset,
+ apm_bios_info.cseg_16, apm_bios_info.dseg);
+ if (apm_bios_info.version > 0x100)
+ printk(" cseg len %x, cseg16 len %x, dseg len %x",
+ apm_bios_info.cseg_len,
+ apm_bios_info.cseg_16_len,
+ apm_bios_info.dseg_len);
+ printk("\n");
+ }
+
+ if (apm_disabled) {
+ printk(KERN_NOTICE "apm: disabled on user request.\n");
+ return;
+ }
+#ifdef __SMP__
+ if (smp_num_cpus > 1) {
+ printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
+ return;
+ }
+#endif

/*
* Set up a segment that references the real mode segment 0x40
@@ -1253,74 +1344,78 @@
set_limit(gdt[APM_CS_16 >> 3], apm_bios_info.cseg_16_len);
set_limit(gdt[APM_DS >> 3], apm_bios_info.dseg_len);
#endif
- /* The APM 1.2 docs state that the apm_driver_version
- * call can fail if we try to connect as 1.2 to a 1.1 bios.
+ /*
+ * We only support BIOSs up to version 1.2
*/
- apm_bios_info.version = 0x0102;
- error = apm_driver_version(&apm_bios_info.version);
- if (error != APM_SUCCESS) { /* Fall back to an APM 1.1 connection. */
- apm_bios_info.version = 0x0101;
- error = apm_driver_version(&apm_bios_info.version);
- }
- if (error != APM_SUCCESS) /* Fall back to an APM 1.0 connection. */
+ if (apm_bios_info.version > 0x0102)
+ apm_bios_info.version = 0x0102;
+ if (apm_driver_version(&apm_bios_info.version) != APM_SUCCESS) {
+ /* Fall back to an APM 1.0 connection. */
apm_bios_info.version = 0x100;
- else {
- apm_engage_power_management(0x0001);
- printk( " Connection version %d.%d\n",
- (apm_bios_info.version >> 8) & 0xff,
- apm_bios_info.version & 0xff );
}
}
-
- error = apm_get_power_status(&bx, &cx, &dx);
- if (error)
- printk(KERN_INFO " Power status not available\n");
- else {
- switch ((bx >> 8) & 0xff) {
- case 0: power_stat = "off line"; break;
- case 1: power_stat = "on line"; break;
- case 2: power_stat = "on backup power"; break;
- default: power_stat = "unknown"; break;
- }
- switch (bx & 0xff) {
- case 0: bat_stat = "high"; break;
- case 1: bat_stat = "low"; break;
- case 2: bat_stat = "critical"; break;
- case 3: bat_stat = "charging"; break;
- default: bat_stat = "unknown"; break;
- }
- printk(KERN_INFO " AC %s, battery status %s, battery life ",
- power_stat, bat_stat);
- if ((cx & 0xff) == 0xff)
- printk("unknown\n");
- else
- printk("%d%%\n", cx & 0xff);
- if (apm_bios_info.version > 0x100) {
- printk(" battery flag 0x%02x, battery life ",
- (cx >> 8) & 0xff);
- if (dx == 0xffff)
+ if (debug) {
+ printk(KERN_INFO "apm: onnection version %d.%d\n",
+ (apm_bios_info.version >> 8) & 0xff,
+ apm_bios_info.version & 0xff );
+
+ error = apm_get_power_status(&bx, &cx, &dx);
+ if (error)
+ printk(KERN_INFO "apm: power status not available\n");
+ else {
+ switch ((bx >> 8) & 0xff) {
+ case 0: power_stat = "off line"; break;
+ case 1: power_stat = "on line"; break;
+ case 2: power_stat = "on backup power"; break;
+ default: power_stat = "unknown"; break;
+ }
+ switch (bx & 0xff) {
+ case 0: bat_stat = "high"; break;
+ case 1: bat_stat = "low"; break;
+ case 2: bat_stat = "critical"; break;
+ case 3: bat_stat = "charging"; break;
+ default: bat_stat = "unknown"; break;
+ }
+ printk(KERN_INFO "apm: AC %s, battery status %s, battery life ",
+ power_stat, bat_stat);
+ if ((cx & 0xff) == 0xff)
printk("unknown\n");
- else {
- if ((dx & 0x8000))
- printk("%d minutes\n", dx & 0x7ffe );
- else
- printk("%d seconds\n", dx & 0x7fff );
+ else
+ printk("%d%%\n", cx & 0xff);
+ if (apm_bios_info.version > 0x100) {
+ printk("apm: battery flag 0x%02x, battery life ",
+ (cx >> 8) & 0xff);
+ if (dx == 0xffff)
+ printk("unknown\n");
+ else {
+ if ((dx & 0x8000))
+ printk("%d minutes\n", dx & 0x7ffe );
+ else
+ printk("%d seconds\n", dx & 0x7fff );
+ }
}
}
}

#ifdef CONFIG_APM_DO_ENABLE
- /*
- * This call causes my NEC UltraLite Versa 33/C to hang if it is
- * booted with PM disabled but not in the docking station.
- * Unfortunate ...
- */
- error = apm_enable_power_management();
- if (error)
- apm_error("enable power management", error);
- if (error == APM_DISABLED)
- return;
+ if (apm_bios_info.flags & APM_BIOS_DISABLED) {
+ /*
+ * This call causes my NEC UltraLite Versa 33/C to hang if it
+ * is booted with PM disabled but not in the docking station.
+ * Unfortunate ...
+ */
+ error = apm_enable_power_management();
+ if (error) {
+ apm_error("enable power management", error);
+ return;
+ }
+ }
#endif
+ if (((apm_bios_info.flags & APM_BIOS_DISABLED) == 0)
+ && (apm_bios_info.version > 0x0100)) {
+ if (apm_engage_power_management(0x0001) == APM_SUCCESS)
+ apm_bios_info.flags &= ~APM_BIOS_DISENGAGED;
+ }

init_timer(&apm_timer);
apm_timer.function = do_apm_timer;
diff -ru linux-2.1.130/include/linux/apm_bios.h linux/include/linux/apm_bios.h
--- linux-2.1.130/include/linux/apm_bios.h Fri Oct 9 23:43:10 1998
+++ linux/include/linux/apm_bios.h Sun Nov 29 02:33:00 1998
@@ -77,6 +77,7 @@
extern struct apm_bios_info apm_bios_info;

extern void apm_bios_init(void);
+extern void apm_setup(char *, int *);

extern int apm_register_callback(int (*callback)(apm_event_t));
extern void apm_unregister_callback(int (*callback)(apm_event_t));
diff -ru linux-2.1.130/init/main.c linux/init/main.c
--- linux-2.1.130/init/main.c Sat Nov 28 23:57:40 1998
+++ linux/init/main.c Sun Nov 29 02:31:54 1998
@@ -41,6 +41,10 @@
# include <asm/mtrr.h>
#endif

+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+#endif
+
/*
* Versions of gcc older than that listed below may actually compile
* and link okay, but the end product can have subtle run time bugs.
@@ -864,6 +868,9 @@
#endif
#ifdef CONFIG_PARIDE_PG
{ "pg.", pg_setup },
+#endif
+#ifdef CONFIG_APM
+ { "apm=", apm_setup },
#endif
{ 0, 0 }
};
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:45    [from the cache]
©2003-2011 Jasper Spaans