v2.5.0.4 -> v2.5.0.5
[linux-flexiantxendom0-3.2.10.git] / arch / i386 / kernel / apm.c
1 /* -*- linux-c -*-
2  * APM BIOS driver for Linux
3  * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
4  *
5  * Initial development of this driver was funded by NEC Australia P/L
6  *      and NEC Corporation
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * October 1995, Rik Faith (faith@cs.unc.edu):
19  *    Minor enhancements and updates (to the patch set) for 1.3.x
20  *    Documentation
21  * January 1996, Rik Faith (faith@cs.unc.edu):
22  *    Make /proc/apm easy to format (bump driver version)
23  * March 1996, Rik Faith (faith@cs.unc.edu):
24  *    Prohibit APM BIOS calls unless apm_enabled.
25  *    (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>)
26  * April 1996, Stephen Rothwell (sfr@canb.auug.org.au)
27  *    Version 1.0 and 1.1
28  * May 1996, Version 1.2
29  * Feb 1998, Version 1.3
30  * Feb 1998, Version 1.4
31  * Aug 1998, Version 1.5
32  * Sep 1998, Version 1.6
33  * Nov 1998, Version 1.7
34  * Jan 1999, Version 1.8
35  * Jan 1999, Version 1.9
36  * Oct 1999, Version 1.10
37  * Nov 1999, Version 1.11
38  * Jan 2000, Version 1.12
39  * Feb 2000, Version 1.13
40  * Nov 2000, Version 1.14
41  * Oct 2001, Version 1.15
42  *
43  * History:
44  *    0.6b: first version in official kernel, Linux 1.3.46
45  *    0.7: changed /proc/apm format, Linux 1.3.58
46  *    0.8: fixed gcc 2.7.[12] compilation problems, Linux 1.3.59
47  *    0.9: only call bios if bios is present, Linux 1.3.72
48  *    1.0: use fixed device number, consolidate /proc/apm into this file,
49  *         Linux 1.3.85
50  *    1.1: support user-space standby and suspend, power off after system
51  *         halted, Linux 1.3.98
52  *    1.2: When resetting RTC after resume, take care so that the time
53  *         is only incorrect by 30-60mS (vs. 1S previously) (Gabor J. Toth
54  *         <jtoth@princeton.edu>); improve interaction between
55  *         screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
56  *    1.2a:Simple change to stop mysterious bug reports with SMP also added
57  *         levels to the printk calls. APM is not defined for SMP machines.
58  *         The new replacment for it is, but Linux doesn't yet support this.
59  *         Alan Cox Linux 2.1.55
60  *    1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
61  *    1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by
62  *         Dean Gaudet <dgaudet@arctic.org>.
63  *         C. Scott Ananian <cananian@alumni.princeton.edu> Linux 2.1.87
64  *    1.5: Fix segment register reloading (in case of bad segments saved
65  *         across BIOS call).
66  *         Stephen Rothwell
67  *    1.6: Cope with complier/assembler differences.
68  *         Only try to turn off the first display device.
69  *         Fix OOPS at power off with no APM BIOS by Jan Echternach
70  *                   <echter@informatik.uni-rostock.de>
71  *         Stephen Rothwell
72  *    1.7: Modify driver's cached copy of the disabled/disengaged flags
73  *         to reflect current state of APM BIOS.
74  *         Chris Rankin <rankinc@bellsouth.net>
75  *         Reset interrupt 0 timer to 100Hz after suspend
76  *         Chad Miller <cmiller@surfsouth.com>
77  *         Add CONFIG_APM_IGNORE_SUSPEND_BOUNCE
78  *         Richard Gooch <rgooch@atnf.csiro.au>
79  *         Allow boot time disabling of APM
80  *         Make boot messages far less verbose by default
81  *         Make asm safer
82  *         Stephen Rothwell
83  *    1.8: Add CONFIG_APM_RTC_IS_GMT
84  *         Richard Gooch <rgooch@atnf.csiro.au>
85  *         change APM_NOINTS to CONFIG_APM_ALLOW_INTS
86  *         remove dependency on CONFIG_PROC_FS
87  *         Stephen Rothwell
88  *    1.9: Fix small typo.  <laslo@ilo.opole.pl>
89  *         Try to cope with BIOS's that need to have all display
90  *         devices blanked and not just the first one.
91  *         Ross Paterson <ross@soi.city.ac.uk>
92  *         Fix segment limit setting it has always been wrong as
93  *         the segments needed to have byte granularity.
94  *         Mark a few things __init.
95  *         Add hack to allow power off of SMP systems by popular request.
96  *         Use CONFIG_SMP instead of __SMP__
97  *         Ignore BOUNCES for three seconds.
98  *         Stephen Rothwell
99  *   1.10: Fix for Thinkpad return code.
100  *         Merge 2.2 and 2.3 drivers.
101  *         Remove APM dependencies in arch/i386/kernel/process.c
102  *         Remove APM dependencies in drivers/char/sysrq.c
103  *         Reset time across standby.
104  *         Allow more inititialisation on SMP.
105  *         Remove CONFIG_APM_POWER_OFF and make it boot time
106  *         configurable (default on).
107  *         Make debug only a boot time parameter (remove APM_DEBUG).
108  *         Try to blank all devices on any error.
109  *   1.11: Remove APM dependencies in drivers/char/console.c
110  *         Check nr_running to detect if we are idle (from
111  *         Borislav Deianov <borislav@lix.polytechnique.fr>)
112  *         Fix for bioses that don't zero the top part of the
113  *         entrypoint offset (Mario Sitta <sitta@al.unipmn.it>)
114  *         (reported by Panos Katsaloulis <teras@writeme.com>).
115  *         Real mode power off patch (Walter Hofmann
116  *         <Walter.Hofmann@physik.stud.uni-erlangen.de>).
117  *   1.12: Remove CONFIG_SMP as the compiler will optimize
118  *         the code away anyway (smp_num_cpus == 1 in UP)
119  *         noted by Artur Skawina <skawina@geocities.com>.
120  *         Make power off under SMP work again.
121  *         Fix thinko with initial engaging of BIOS.
122  *         Make sure power off only happens on CPU 0
123  *         (Paul "Rusty" Russell <rusty@rustcorp.com.au>).
124  *         Do error notification to user mode if BIOS calls fail.
125  *         Move entrypoint offset fix to ...boot/setup.S
126  *         where it belongs (Cosmos <gis88564@cis.nctu.edu.tw>).
127  *         Remove smp-power-off. SMP users must now specify
128  *         "apm=power-off" on the kernel command line. Suggested
129  *         by Jim Avera <jima@hal.com>, modified by Alan Cox
130  *         <alan@lxorguk.ukuu.org.uk>.
131  *         Register the /proc/apm entry even on SMP so that
132  *         scripts that check for it before doing power off
133  *         work (Jim Avera <jima@hal.com>).
134  *   1.13: Changes for new pm_ interfaces (Andy Henroid
135  *         <andy_henroid@yahoo.com>).
136  *         Modularize the code.
137  *         Fix the Thinkpad (again) :-( (CONFIG_APM_IGNORE_MULTIPLE_SUSPENDS
138  *         is now the way life works).
139  *         Fix thinko in suspend() (wrong return).
140  *         Notify drivers on critical suspend.
141  *         Make kapmd absorb more idle time (Pavel Machek <pavel@suse.cz>
142  *         modified by sfr).
143  *         Disable interrupts while we are suspended (Andy Henroid
144  *         <andy_henroid@yahoo.com> fixed by sfr).
145  *         Make power off work on SMP again (Tony Hoyle
146  *         <tmh@magenta-logic.com> and <zlatko@iskon.hr>) modified by sfr.
147  *         Remove CONFIG_APM_SUSPEND_BOUNCE.  The bounce ignore
148  *         interval is now configurable.
149  *   1.14: Make connection version persist across module unload/load.
150  *         Enable and engage power management earlier.
151  *         Disengage power management on module unload.
152  *         Changed to use the sysrq-register hack for registering the
153  *         power off function called by magic sysrq based upon discussions
154  *         in irc://irc.openprojects.net/#kernelnewbies
155  *         (Crutcher Dunnavant <crutcher+kernel@datastacks.com>).
156  *         Make CONFIG_APM_REAL_MODE_POWER_OFF run time configurable.
157  *         (Arjan van de Ven <arjanv@redhat.com>) modified by sfr.
158  *         Work around byte swap bug in one of the Vaio's BIOS's
159  *         (Marc Boucher <marc@mbsi.ca>).
160  *         Exposed the disable flag to dmi so that we can handle known
161  *         broken APM (Alan Cox <alan@redhat.com>).
162  *   1.14ac: If the BIOS says "I slowed the CPU down" then don't spin
163  *         calling it - instead idle. (Alan Cox <alan@redhat.com>)
164  *         If an APM idle fails log it and idle sensibly
165  *   1.15: Don't queue events to clients who open the device O_WRONLY.
166  *         Don't expect replies from clients who open the device O_RDONLY.
167  *         (Idea from Thomas Hood <jdthood at yahoo.co.uk>)
168  *         Minor waitqueue cleanups.(John Fremlin <chief@bandits.org>)
169  *
170  * APM 1.1 Reference:
171  *
172  *   Intel Corporation, Microsoft Corporation. Advanced Power Management
173  *   (APM) BIOS Interface Specification, Revision 1.1, September 1993.
174  *   Intel Order Number 241704-001.  Microsoft Part Number 781-110-X01.
175  *
176  * [This document is available free from Intel by calling 800.628.8686 (fax
177  * 916.356.6100) or 800.548.4725; or via anonymous ftp from
178  * ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc.  It is also
179  * available from Microsoft by calling 206.882.8080.]
180  *
181  * APM 1.2 Reference:
182  *   Intel Corporation, Microsoft Corporation. Advanced Power Management
183  *   (APM) BIOS Interface Specification, Revision 1.2, February 1996.
184  *
185  * [This document is available from Microsoft at:
186  *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
187  */
188
189 #include <linux/config.h>
190 #include <linux/module.h>
191
192 #include <linux/poll.h>
193 #include <linux/types.h>
194 #include <linux/stddef.h>
195 #include <linux/timer.h>
196 #include <linux/fcntl.h>
197 #include <linux/slab.h>
198 #include <linux/stat.h>
199 #include <linux/proc_fs.h>
200 #include <linux/miscdevice.h>
201 #include <linux/apm_bios.h>
202 #include <linux/init.h>
203 #include <linux/sched.h>
204 #include <linux/pm.h>
205 #include <linux/kernel.h>
206 #include <linux/smp_lock.h>
207
208 #include <asm/system.h>
209 #include <asm/uaccess.h>
210 #include <asm/desc.h>
211
212 #include <linux/sysrq.h>
213
214 extern unsigned long get_cmos_time(void);
215 extern void machine_real_restart(unsigned char *, int);
216
217 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
218 extern int (*console_blank_hook)(int);
219 #endif
220
221 /*
222  * The apm_bios device is one of the misc char devices.
223  * This is its minor number.
224  */
225 #define APM_MINOR_DEV   134
226
227 /*
228  * See Documentation/Config.help for the configuration options.
229  *
230  * Various options can be changed at boot time as follows:
231  * (We allow underscores for compatibility with the modules code)
232  *      apm=on/off                      enable/disable APM
233  *          [no-]allow[-_]ints          allow interrupts during BIOS calls
234  *          [no-]broken[-_]psr          BIOS has a broken GetPowerStatus call
235  *          [no-]realmode[-_]power[-_]off       switch to real mode before
236  *                                              powering off
237  *          [no-]debug                  log some debugging messages
238  *          [no-]power[-_]off           power off on shutdown
239  *          bounce[-_]interval=<n>      number of ticks to ignore suspend
240  *                                      bounces
241  */
242
243 /* KNOWN PROBLEM MACHINES:
244  *
245  * U: TI 4000M TravelMate: BIOS is *NOT* APM compliant
246  *                         [Confirmed by TI representative]
247  * ?: ACER 486DX4/75: uses dseg 0040, in violation of APM specification
248  *                    [Confirmed by BIOS disassembly]
249  *                    [This may work now ...]
250  * P: Toshiba 1950S: battery life information only gets updated after resume
251  * P: Midwest Micro Soundbook Elite DX2/66 monochrome: screen blanking
252  *      broken in BIOS [Reported by Garst R. Reese <reese@isn.net>]
253  * ?: AcerNote-950: oops on reading /proc/apm - workaround is a WIP
254  *      Neale Banks <neale@lowendale.com.au> December 2000
255  *
256  * Legend: U = unusable with APM patches
257  *         P = partially usable with APM patches
258  */
259
260 /*
261  * Define to always call the APM BIOS busy routine even if the clock was
262  * not slowed by the idle routine.
263  */
264 #define ALWAYS_CALL_BUSY
265
266 /*
267  * Define to make the APM BIOS calls zero all data segment registers (so
268  * that an incorrect BIOS implementation will cause a kernel panic if it
269  * tries to write to arbitrary memory).
270  */
271 #define APM_ZERO_SEGS
272
273 /*
274  * Define to make all _set_limit calls use 64k limits.  The APM 1.1 BIOS is
275  * supposed to provide limit information that it recognizes.  Many machines
276  * do this correctly, but many others do not restrict themselves to their
277  * claimed limit.  When this happens, they will cause a segmentation
278  * violation in the kernel at boot time.  Most BIOS's, however, will
279  * respect a 64k limit, so we use that.  If you want to be pedantic and
280  * hold your BIOS to its claims, then undefine this.
281  */
282 #define APM_RELAX_SEGMENTS
283
284 /*
285  * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
286  * This patched by Chad Miller <cmiller@surfsouth.com>, original code by
287  * David Chen <chen@ctpa04.mit.edu>
288  */
289 #undef INIT_TIMER_AFTER_SUSPEND
290
291 #ifdef INIT_TIMER_AFTER_SUSPEND
292 #include <linux/timex.h>
293 #include <asm/io.h>
294 #include <linux/delay.h>
295 #endif
296
297 /*
298  * Need to poll the APM BIOS every second
299  */
300 #define APM_CHECK_TIMEOUT       (HZ)
301
302 /*
303  * Ignore suspend events for this amount of time after a resume
304  */
305 #define DEFAULT_BOUNCE_INTERVAL         (3 * HZ)
306
307 /*
308  * Save a segment register away
309  */
310 #define savesegment(seg, where) \
311                 __asm__ __volatile__("movl %%" #seg ",%0" : "=m" (where))
312
313 /*
314  * Maximum number of events stored
315  */
316 #define APM_MAX_EVENTS          20
317
318 /*
319  * The per-file APM data
320  */
321 struct apm_user {
322         int             magic;
323         struct apm_user *       next;
324         int             suser: 1;
325         int             writer: 1;
326         int             reader: 1;
327         int             suspend_wait: 1;
328         int             suspend_result;
329         int             suspends_pending;
330         int             standbys_pending;
331         int             suspends_read;
332         int             standbys_read;
333         int             event_head;
334         int             event_tail;
335         apm_event_t     events[APM_MAX_EVENTS];
336 };
337
338 /*
339  * The magic number in apm_user
340  */
341 #define APM_BIOS_MAGIC          0x4101
342
343 /*
344  * Local variables
345  */
346 static struct {
347         unsigned long   offset;
348         unsigned short  segment;
349 }                               apm_bios_entry;
350 #ifdef CONFIG_APM_CPU_IDLE
351 static int                      clock_slowed;
352 #endif
353 static int                      suspends_pending;
354 static int                      standbys_pending;
355 static int                      waiting_for_resume;
356 static int                      ignore_normal_resume;
357 static int                      bounce_interval = DEFAULT_BOUNCE_INTERVAL;
358
359 #ifdef CONFIG_APM_RTC_IS_GMT
360 #       define  clock_cmos_diff 0
361 #       define  got_clock_diff  1
362 #else
363 static long                     clock_cmos_diff;
364 static int                      got_clock_diff;
365 #endif
366 static int                      debug;
367 static int                      apm_disabled = -1;
368 #ifdef CONFIG_SMP
369 static int                      power_off;
370 #else
371 static int                      power_off = 1;
372 #endif
373 #ifdef CONFIG_APM_REAL_MODE_POWER_OFF
374 static int                      realmode_power_off = 1;
375 #else
376 static int                      realmode_power_off;
377 #endif
378 static int                      exit_kapmd;
379 static int                      kapmd_running;
380 #ifdef CONFIG_APM_ALLOW_INTS
381 static int                      allow_ints = 1;
382 #else
383 static int                      allow_ints;
384 #endif
385 static int                      broken_psr;
386
387 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
388 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
389 static struct apm_user *        user_list;
390 static spinlock_t               user_list_lock = SPIN_LOCK_UNLOCKED;
391
392 static char                     driver_version[] = "1.15";      /* no spaces */
393
394 /*
395  *      APM event names taken from the APM 1.2 specification. These are
396  *      the message codes that the BIOS uses to tell us about events
397  */
398 static char *   apm_event_name[] = {
399         "system standby",
400         "system suspend",
401         "normal resume",
402         "critical resume",
403         "low battery",
404         "power status change",
405         "update time",
406         "critical suspend",
407         "user standby",
408         "user suspend",
409         "system standby resume",
410         "capabilities change"
411 };
412 #define NR_APM_EVENT_NAME       \
413                 (sizeof(apm_event_name) / sizeof(apm_event_name[0]))
414
415 typedef struct lookup_t {
416         int     key;
417         char *  msg;
418 } lookup_t;
419
420 /*
421  *      The BIOS returns a set of standard error codes in AX when the
422  *      carry flag is set.
423  */
424  
425 static const lookup_t error_table[] = {
426 /* N/A  { APM_SUCCESS,          "Operation succeeded" }, */
427         { APM_DISABLED,         "Power management disabled" },
428         { APM_CONNECTED,        "Real mode interface already connected" },
429         { APM_NOT_CONNECTED,    "Interface not connected" },
430         { APM_16_CONNECTED,     "16 bit interface already connected" },
431 /* N/A  { APM_16_UNSUPPORTED,   "16 bit interface not supported" }, */
432         { APM_32_CONNECTED,     "32 bit interface already connected" },
433         { APM_32_UNSUPPORTED,   "32 bit interface not supported" },
434         { APM_BAD_DEVICE,       "Unrecognized device ID" },
435         { APM_BAD_PARAM,        "Parameter out of range" },
436         { APM_NOT_ENGAGED,      "Interface not engaged" },
437         { APM_BAD_FUNCTION,     "Function not supported" },
438         { APM_RESUME_DISABLED,  "Resume timer disabled" },
439         { APM_BAD_STATE,        "Unable to enter requested state" },
440 /* N/A  { APM_NO_EVENTS,        "No events pending" }, */
441         { APM_NO_ERROR,         "BIOS did not set a return code" },
442         { APM_NOT_PRESENT,      "No APM present" }
443 };
444 #define ERROR_COUNT     (sizeof(error_table)/sizeof(lookup_t))
445
446 /*
447  * These are the actual BIOS calls.  Depending on APM_ZERO_SEGS and
448  * apm_info.allow_ints, we are being really paranoid here!  Not only
449  * are interrupts disabled, but all the segment registers (except SS)
450  * are saved and zeroed this means that if the BIOS tries to reference
451  * any data without explicitly loading the segment registers, the kernel
452  * will fault immediately rather than have some unforeseen circumstances
453  * for the rest of the kernel.  And it will be very obvious!  :-) Doing
454  * this depends on CS referring to the same physical memory as DS so that
455  * DS can be zeroed before the call. Unfortunately, we can't do anything
456  * about the stack segment/pointer.  Also, we tell the compiler that
457  * everything could change.
458  *
459  * Also, we KNOW that for the non error case of apm_bios_call, there
460  * is no useful data returned in the low order 8 bits of eax.
461  */
462 #define APM_DO_CLI      \
463         if (apm_info.allow_ints) \
464                 __sti(); \
465         else \
466                 __cli();
467
468 #ifdef APM_ZERO_SEGS
469 #       define APM_DECL_SEGS \
470                 unsigned int saved_fs; unsigned int saved_gs;
471 #       define APM_DO_SAVE_SEGS \
472                 savesegment(fs, saved_fs); savesegment(gs, saved_gs)
473 #       define APM_DO_ZERO_SEGS \
474                 "pushl %%ds\n\t" \
475                 "pushl %%es\n\t" \
476                 "xorl %%edx, %%edx\n\t" \
477                 "mov %%dx, %%ds\n\t" \
478                 "mov %%dx, %%es\n\t" \
479                 "mov %%dx, %%fs\n\t" \
480                 "mov %%dx, %%gs\n\t"
481 #       define APM_DO_POP_SEGS \
482                 "popl %%es\n\t" \
483                 "popl %%ds\n\t"
484 #       define APM_DO_RESTORE_SEGS \
485                 loadsegment(fs, saved_fs); loadsegment(gs, saved_gs)
486 #else
487 #       define APM_DECL_SEGS
488 #       define APM_DO_SAVE_SEGS
489 #       define APM_DO_ZERO_SEGS
490 #       define APM_DO_POP_SEGS
491 #       define APM_DO_RESTORE_SEGS
492 #endif
493
494 /**
495  *      apm_bios_call   -       Make an APM BIOS 32bit call
496  *      @func: APM function to execute
497  *      @ebx_in: EBX register for call entry
498  *      @ecx_in: ECX register for call entry
499  *      @eax: EAX register return
500  *      @ebx: EBX register return
501  *      @ecx: ECX register return
502  *      @edx: EDX register return
503  *      @esi: ESI register return
504  *
505  *      Make an APM call using the 32bit protected mode interface. The
506  *      caller is responsible for knowing if APM BIOS is configured and
507  *      enabled. This call can disable interrupts for a long period of
508  *      time on some laptops.  The return value is in AH and the carry
509  *      flag is loaded into AL.  If there is an error, then the error
510  *      code is returned in AH (bits 8-15 of eax) and this function
511  *      returns non-zero.
512  */
513  
514 static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
515         u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
516 {
517         APM_DECL_SEGS
518         unsigned long   flags;
519
520         __save_flags(flags);
521         APM_DO_CLI;
522         APM_DO_SAVE_SEGS;
523         /*
524          * N.B. We do NOT need a cld after the BIOS call
525          * because we always save and restore the flags.
526          */
527         __asm__ __volatile__(APM_DO_ZERO_SEGS
528                 "pushl %%edi\n\t"
529                 "pushl %%ebp\n\t"
530                 "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
531                 "setc %%al\n\t"
532                 "popl %%ebp\n\t"
533                 "popl %%edi\n\t"
534                 APM_DO_POP_SEGS
535                 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
536                   "=S" (*esi)
537                 : "a" (func), "b" (ebx_in), "c" (ecx_in)
538                 : "memory", "cc");
539         APM_DO_RESTORE_SEGS;
540         __restore_flags(flags);
541         return *eax & 0xff;
542 }
543
544 /**
545  *      apm_bios_call_simple    -       make a simple APM BIOS 32bit call
546  *      @func: APM function to invoke
547  *      @ebx_in: EBX register value for BIOS call
548  *      @ecx_in: ECX register value for BIOS call
549  *      @eax: EAX register on return from the BIOS call
550  *
551  *      Make a BIOS call that does only returns one value, or just status.
552  *      If there is an error, then the error code is returned in AH
553  *      (bits 8-15 of eax) and this function returns non-zero. This is
554  *      used for simpler BIOS operations. This call may hold interrupts
555  *      off for a long time on some laptops.
556  */
557
558 static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
559 {
560         u8              error;
561         APM_DECL_SEGS
562         unsigned long   flags;
563
564         __save_flags(flags);
565         APM_DO_CLI;
566         APM_DO_SAVE_SEGS;
567         {
568                 int     cx, dx, si;
569
570                 /*
571                  * N.B. We do NOT need a cld after the BIOS call
572                  * because we always save and restore the flags.
573                  */
574                 __asm__ __volatile__(APM_DO_ZERO_SEGS
575                         "pushl %%edi\n\t"
576                         "pushl %%ebp\n\t"
577                         "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
578                         "setc %%bl\n\t"
579                         "popl %%ebp\n\t"
580                         "popl %%edi\n\t"
581                         APM_DO_POP_SEGS
582                         : "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
583                           "=S" (si)
584                         : "a" (func), "b" (ebx_in), "c" (ecx_in)
585                         : "memory", "cc");
586         }
587         APM_DO_RESTORE_SEGS;
588         __restore_flags(flags);
589         return error;
590 }
591
592 /**
593  *      apm_driver_version      -       APM driver version
594  *      @val:   loaded with the APM version on return
595  *
596  *      Retrieve the APM version supported by the BIOS. This is only
597  *      supported for APM 1.1 or higher. An error indicates APM 1.0 is
598  *      probably present.
599  *
600  *      On entry val should point to a value indicating the APM driver
601  *      version with the high byte being the major and the low byte the
602  *      minor number both in BCD
603  *
604  *      On return it will hold the BIOS revision supported in the
605  *      same format.
606  */
607
608 static int __init apm_driver_version(u_short *val)
609 {
610         u32     eax;
611
612         if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
613                 return (eax >> 8) & 0xff;
614         *val = eax;
615         return APM_SUCCESS;
616 }
617
618 /**
619  *      apm_get_event   -       get an APM event from the BIOS
620  *      @event: pointer to the event
621  *      @info: point to the event information
622  *
623  *      The APM BIOS provides a polled information for event
624  *      reporting. The BIOS expects to be polled at least every second
625  *      when events are pending. When a message is found the caller should
626  *      poll until no more messages are present.  However, this causes
627  *      problems on some laptops where a suspend event notification is
628  *      not cleared until it is acknowledged.
629  *
630  *      Additional information is returned in the info pointer, providing
631  *      that APM 1.2 is in use. If no messges are pending the value 0x80
632  *      is returned (No power management events pending).
633  */
634  
635 static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
636 {
637         u32     eax;
638         u32     ebx;
639         u32     ecx;
640         u32     dummy;
641
642         if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
643                         &dummy, &dummy))
644                 return (eax >> 8) & 0xff;
645         *event = ebx;
646         if (apm_info.connection_version < 0x0102)
647                 *info = ~0; /* indicate info not valid */
648         else
649                 *info = ecx;
650         return APM_SUCCESS;
651 }
652
653 /**
654  *      set_power_state -       set the power management state
655  *      @what: which items to transition
656  *      @state: state to transition to
657  *
658  *      Request an APM change of state for one or more system devices. The
659  *      processor state must be transitioned last of all. what holds the
660  *      class of device in the upper byte and the device number (0xFF for
661  *      all) for the object to be transitioned.
662  *
663  *      The state holds the state to transition to, which may in fact
664  *      be an acceptance of a BIOS requested state change.
665  */
666  
667 static int set_power_state(u_short what, u_short state)
668 {
669         u32     eax;
670
671         if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
672                 return (eax >> 8) & 0xff;
673         return APM_SUCCESS;
674 }
675
676 /**
677  *      apm_set_power_state - set system wide power state
678  *      @state: which state to enter
679  *
680  *      Transition the entire system into a new APM power state.
681  */
682  
683 static int apm_set_power_state(u_short state)
684 {
685         return set_power_state(APM_DEVICE_ALL, state);
686 }
687
688 #ifdef CONFIG_APM_CPU_IDLE
689
690 /**
691  *      apm_do_idle     -       perform power saving
692  *
693  *      This function notifies the BIOS that the processor is (in the view
694  *      of the OS) idle. It returns -1 in the event that the BIOS refuses
695  *      to handle the idle request. On a success the function returns 1
696  *      if the BIOS did clock slowing or 0 otherwise.
697  */
698  
699 static int apm_do_idle(void)
700 {
701         u32     eax;
702         int     slowed;
703
704         if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) {
705                 static unsigned long t;
706
707                 if (time_after(jiffies, t + 10 * HZ)) {
708                         printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
709                                         (eax >> 8) & 0xff);
710                         t = jiffies;
711                 }
712                 return -1;
713         }
714         slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
715 #ifdef ALWAYS_CALL_BUSY
716         clock_slowed = 1;
717 #else
718         clock_slowed = slowed;
719 #endif
720         return slowed;
721 }
722
723 /**
724  *      apm_do_busy     -       inform the BIOS the CPU is busy
725  *
726  *      Request that the BIOS brings the CPU back to full performance. 
727  */
728  
729 static void apm_do_busy(void)
730 {
731         u32     dummy;
732
733         if (clock_slowed) {
734                 (void) apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
735                 clock_slowed = 0;
736         }
737 }
738
739 #if 0
740 extern int hlt_counter;
741
742 /*
743  * If no process has been interested in this
744  * CPU for some time, we want to wake up the
745  * power management thread - we probably want
746  * to conserve power.
747  */
748 #define HARD_IDLE_TIMEOUT (HZ/3)
749
750 /* This should wake up kapmd and ask it to slow the CPU */
751 #define powermanagement_idle()  do { } while (0)
752
753 /**
754  * apm_cpu_idle         -       cpu idling for APM capable Linux
755  *
756  * This is the idling function the kernel executes when APM is available. It 
757  * tries to save processor time directly by using hlt instructions. A
758  * separate apm thread tries to do the BIOS power management.
759  *
760  * N.B. This is curently not used for kernels 2.4.x.
761  */
762
763 static void apm_cpu_idle(void)
764 {
765         unsigned int start_idle;
766
767         start_idle = jiffies;
768         while (1) {
769                 if (!current->need_resched) {
770                         if (jiffies - start_idle < HARD_IDLE_TIMEOUT) {
771                                 if (!current_cpu_data.hlt_works_ok)
772                                         continue;
773                                 if (hlt_counter)
774                                         continue;
775                                 __cli();
776                                 if (!current->need_resched)
777                                         safe_halt();
778                                 else
779                                         __sti();
780                                 continue;
781                         }
782
783                         /*
784                          * Ok, do some power management - we've been idle for too long
785                          */
786                         powermanagement_idle();
787                 }
788
789                 schedule();
790                 check_pgt_cache();
791                 start_idle = jiffies;
792         }
793 }
794 #endif
795 #endif
796
797 #ifdef CONFIG_SMP
798 static int apm_magic(void * unused)
799 {
800         while (1)
801                 schedule();
802 }
803 #endif
804
805 /**
806  *      apm_power_off   -       ask the BIOS to power off
807  *
808  *      Handle the power off sequence. This is the one piece of code we
809  *      will execute even on SMP machines. In order to deal with BIOS
810  *      bugs we support real mode APM BIOS power off calls. We also make
811  *      the SMP call on CPU0 as some systems will only honour this call
812  *      on their first cpu.
813  */
814  
815 static void apm_power_off(void)
816 {
817         unsigned char   po_bios_call[] = {
818                 0xb8, 0x00, 0x10,       /* movw  $0x1000,ax  */
819                 0x8e, 0xd0,             /* movw  ax,ss       */
820                 0xbc, 0x00, 0xf0,       /* movw  $0xf000,sp  */
821                 0xb8, 0x07, 0x53,       /* movw  $0x5307,ax  */
822                 0xbb, 0x01, 0x00,       /* movw  $0x0001,bx  */
823                 0xb9, 0x03, 0x00,       /* movw  $0x0003,cx  */
824                 0xcd, 0x15              /* int   $0x15       */
825         };
826
827         /*
828          * This may be called on an SMP machine.
829          */
830 #ifdef CONFIG_SMP
831         /* Some bioses don't like being called from CPU != 0 */
832         while (cpu_number_map(smp_processor_id()) != 0) {
833                 kernel_thread(apm_magic, NULL,
834                         CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
835                 schedule();
836         }
837 #endif
838         if (apm_info.realmode_power_off)
839                 machine_real_restart(po_bios_call, sizeof(po_bios_call));
840         else
841                 (void) apm_set_power_state(APM_STATE_OFF);
842 }
843
844 /**
845  * handle_poweroff      -       sysrq callback for power down
846  * @key: key pressed (unused)
847  * @pt_regs: register state (unused)
848  * @kbd: keyboard state (unused)
849  * @tty: tty involved (unused)
850  *
851  * When the user hits Sys-Rq o to power down the machine this is the
852  * callback we use.
853  */
854
855 void handle_poweroff (int key, struct pt_regs *pt_regs,
856                 struct kbd_struct *kbd, struct tty_struct *tty) {
857         apm_power_off();
858 }
859
860 struct sysrq_key_op     sysrq_poweroff_op = {
861         handler:        handle_poweroff,
862         help_msg:       "Off",
863         action_msg:     "Power Off\n"
864 };
865
866
867 #ifdef CONFIG_APM_DO_ENABLE
868
869 /**
870  *      apm_enable_power_management - enable BIOS APM power management
871  *      @enable: enable yes/no
872  *
873  *      Enable or disable the APM BIOS power services. 
874  */
875  
876 static int apm_enable_power_management(int enable)
877 {
878         u32     eax;
879
880         if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED))
881                 return APM_NOT_ENGAGED;
882         if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
883                         enable, &eax))
884                 return (eax >> 8) & 0xff;
885         if (enable)
886                 apm_info.bios.flags &= ~APM_BIOS_DISABLED;
887         else
888                 apm_info.bios.flags |= APM_BIOS_DISABLED;
889         return APM_SUCCESS;
890 }
891 #endif
892
893 /**
894  *      apm_get_power_status    -       get current power state
895  *      @status: returned status
896  *      @bat: battery info
897  *      @life: estimated life
898  *
899  *      Obtain the current power status from the APM BIOS. We return a
900  *      status which gives the rough battery status, and current power
901  *      source. The bat value returned give an estimate as a percentage
902  *      of life and a status value for the battery. The estimated life
903  *      if reported is a lifetime in secodnds/minutes at current powwer
904  *      consumption.
905  */
906  
907 static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
908 {
909         u32     eax;
910         u32     ebx;
911         u32     ecx;
912         u32     edx;
913         u32     dummy;
914
915         if (apm_info.get_power_status_broken)
916                 return APM_32_UNSUPPORTED;
917         if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
918                         &eax, &ebx, &ecx, &edx, &dummy))
919                 return (eax >> 8) & 0xff;
920         *status = ebx;
921         *bat = ecx;
922         if (apm_info.get_power_status_swabinminutes) {
923                 *life = swab16((u16)edx);
924                 *life |= 0x8000;
925         } else
926                 *life = edx;
927         return APM_SUCCESS;
928 }
929
930 #if 0
931 static int apm_get_battery_status(u_short which, u_short *status,
932                                   u_short *bat, u_short *life, u_short *nbat)
933 {
934         u32     eax;
935         u32     ebx;
936         u32     ecx;
937         u32     edx;
938         u32     esi;
939
940         if (apm_info.connection_version < 0x0102) {
941                 /* pretend we only have one battery. */
942                 if (which != 1)
943                         return APM_BAD_DEVICE;
944                 *nbat = 1;
945                 return apm_get_power_status(status, bat, life);
946         }
947
948         if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax,
949                         &ebx, &ecx, &edx, &esi))
950                 return (eax >> 8) & 0xff;
951         *status = ebx;
952         *bat = ecx;
953         *life = edx;
954         *nbat = esi;
955         return APM_SUCCESS;
956 }
957 #endif
958
959 /**
960  *      apm_engage_power_management     -       enable PM on a device
961  *      @device: identity of device
962  *      @enable: on/off
963  *
964  *      Activate or deactive power management on either a specific device
965  *      or the entire system (%APM_DEVICE_ALL).
966  */
967  
968 static int apm_engage_power_management(u_short device, int enable)
969 {
970         u32     eax;
971
972         if ((enable == 0) && (device == APM_DEVICE_ALL)
973             && (apm_info.bios.flags & APM_BIOS_DISABLED))
974                 return APM_DISABLED;
975         if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, &eax))
976                 return (eax >> 8) & 0xff;
977         if (device == APM_DEVICE_ALL) {
978                 if (enable)
979                         apm_info.bios.flags &= ~APM_BIOS_DISENGAGED;
980                 else
981                         apm_info.bios.flags |= APM_BIOS_DISENGAGED;
982         }
983         return APM_SUCCESS;
984 }
985
986 /**
987  *      apm_error       -       display an APM error
988  *      @str: information string
989  *      @err: APM BIOS return code
990  *
991  *      Write a meaningful log entry to the kernel log in the event of
992  *      an APM error.
993  */
994  
995 static void apm_error(char *str, int err)
996 {
997         int     i;
998
999         for (i = 0; i < ERROR_COUNT; i++)
1000                 if (error_table[i].key == err) break;
1001         if (i < ERROR_COUNT)
1002                 printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
1003         else
1004                 printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
1005                         str, err);
1006 }
1007
1008 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1009
1010 /**
1011  *      apm_console_blank       -       blank the display
1012  *      @blank: on/off
1013  *
1014  *      Attempt to blank the console, firstly by blanking just video device
1015  *      zero, and if that fails (some BIOSes dont support it) then it blanks
1016  *      all video devices. Typically the BIOS will do laptop backlight and
1017  *      monitor powerdown for us.
1018  */
1019  
1020 static int apm_console_blank(int blank)
1021 {
1022         int     error;
1023         u_short state;
1024
1025         state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
1026         /* Blank the first display device */
1027         error = set_power_state(0x100, state);
1028         if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) {
1029                 /* try to blank them all instead */
1030                 error = set_power_state(0x1ff, state);
1031                 if ((error != APM_SUCCESS) && (error != APM_NO_ERROR))
1032                         /* try to blank device one instead */
1033                         error = set_power_state(0x101, state);
1034         }
1035         if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
1036                 return 1;
1037         apm_error("set display", error);
1038         return 0;
1039 }
1040 #endif
1041
1042 static int queue_empty(struct apm_user *as)
1043 {
1044         return as->event_head == as->event_tail;
1045 }
1046
1047 static apm_event_t get_queued_event(struct apm_user *as)
1048 {
1049         as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
1050         return as->events[as->event_tail];
1051 }
1052
1053 static void queue_event(apm_event_t event, struct apm_user *sender)
1054 {
1055         struct apm_user *       as;
1056
1057         spin_lock(&user_list_lock);
1058         if (user_list == NULL)
1059                 goto out;
1060         for (as = user_list; as != NULL; as = as->next) {
1061                 if ((as == sender) || (!as->reader))
1062                         continue;
1063                 as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
1064                 if (as->event_head == as->event_tail) {
1065                         static int notified;
1066
1067                         if (notified++ == 0)
1068                             printk(KERN_ERR "apm: an event queue overflowed\n");
1069                         as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
1070                 }
1071                 as->events[as->event_head] = event;
1072                 if ((!as->suser) || (!as->writer))
1073                         continue;
1074                 switch (event) {
1075                 case APM_SYS_SUSPEND:
1076                 case APM_USER_SUSPEND:
1077                         as->suspends_pending++;
1078                         suspends_pending++;
1079                         break;
1080
1081                 case APM_SYS_STANDBY:
1082                 case APM_USER_STANDBY:
1083                         as->standbys_pending++;
1084                         standbys_pending++;
1085                         break;
1086                 }
1087         }
1088         wake_up_interruptible(&apm_waitqueue);
1089 out:
1090         spin_unlock(&user_list_lock);
1091 }
1092
1093 static void set_time(void)
1094 {
1095         unsigned long   flags;
1096
1097         if (got_clock_diff) {   /* Must know time zone in order to set clock */
1098                 save_flags(flags);
1099                 cli();
1100                 CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
1101                 restore_flags(flags);
1102         }
1103 }
1104
1105 static void get_time_diff(void)
1106 {
1107 #ifndef CONFIG_APM_RTC_IS_GMT
1108         unsigned long   flags;
1109
1110         /*
1111          * Estimate time zone so that set_time can update the clock
1112          */
1113         save_flags(flags);
1114         clock_cmos_diff = -get_cmos_time();
1115         cli();
1116         clock_cmos_diff += CURRENT_TIME;
1117         got_clock_diff = 1;
1118         restore_flags(flags);
1119 #endif
1120 }
1121
1122 static void reinit_timer(void)
1123 {
1124 #ifdef INIT_TIMER_AFTER_SUSPEND
1125         unsigned long   flags;
1126
1127         save_flags(flags);
1128         cli();
1129         /* set the clock to 100 Hz */
1130         outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
1131         udelay(10);
1132         outb_p(LATCH & 0xff , 0x40);    /* LSB */
1133         udelay(10);
1134         outb(LATCH >> 8 , 0x40);        /* MSB */
1135         udelay(10);
1136         restore_flags(flags);
1137 #endif
1138 }
1139
1140 static int send_event(apm_event_t event)
1141 {
1142         switch (event) {
1143         case APM_SYS_SUSPEND:
1144         case APM_CRITICAL_SUSPEND:
1145         case APM_USER_SUSPEND:
1146                 /* map all suspends to ACPI D3 */
1147                 if (pm_send_all(PM_SUSPEND, (void *)3)) {
1148                         if (event == APM_CRITICAL_SUSPEND) {
1149                                 printk(KERN_CRIT
1150                                         "apm: Critical suspend was vetoed, "
1151                                         "expect armageddon\n" );
1152                                 return 0;
1153                         }
1154                         if (apm_info.connection_version > 0x100)
1155                                 apm_set_power_state(APM_STATE_REJECT);
1156                         return 0;
1157                 }
1158                 break;
1159         case APM_NORMAL_RESUME:
1160         case APM_CRITICAL_RESUME:
1161                 /* map all resumes to ACPI D0 */
1162                 (void) pm_send_all(PM_RESUME, (void *)0);
1163                 break;
1164         }
1165
1166         return 1;
1167 }
1168
1169 static int suspend(void)
1170 {
1171         int             err;
1172         struct apm_user *as;
1173
1174         get_time_diff();
1175         cli();
1176         err = apm_set_power_state(APM_STATE_SUSPEND);
1177         reinit_timer();
1178         set_time();
1179         if (err == APM_NO_ERROR)
1180                 err = APM_SUCCESS;
1181         if (err != APM_SUCCESS)
1182                 apm_error("suspend", err);
1183         send_event(APM_NORMAL_RESUME);
1184         sti();
1185         queue_event(APM_NORMAL_RESUME, NULL);
1186         spin_lock(&user_list_lock);
1187         for (as = user_list; as != NULL; as = as->next) {
1188                 as->suspend_wait = 0;
1189                 as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO);
1190         }
1191         spin_unlock(&user_list_lock);
1192         ignore_normal_resume = 1;
1193         wake_up_interruptible(&apm_suspend_waitqueue);
1194         return err;
1195 }
1196
1197 static void standby(void)
1198 {
1199         int     err;
1200
1201         get_time_diff();
1202         err = apm_set_power_state(APM_STATE_STANDBY);
1203         if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
1204                 apm_error("standby", err);
1205 }
1206
1207 static apm_event_t get_event(void)
1208 {
1209         int             error;
1210         apm_event_t     event;
1211         apm_eventinfo_t info;
1212
1213         static int notified;
1214
1215         /* we don't use the eventinfo */
1216         error = apm_get_event(&event, &info);
1217         if (error == APM_SUCCESS)
1218                 return event;
1219
1220         if ((error != APM_NO_EVENTS) && (notified++ == 0))
1221                 apm_error("get_event", error);
1222
1223         return 0;
1224 }
1225
1226 static void check_events(void)
1227 {
1228         apm_event_t             event;
1229         static unsigned long    last_resume;
1230         static int              ignore_bounce;
1231
1232         while ((event = get_event()) != 0) {
1233                 if (debug) {
1234                         if (event <= NR_APM_EVENT_NAME)
1235                                 printk(KERN_DEBUG "apm: received %s notify\n",
1236                                        apm_event_name[event - 1]);
1237                         else
1238                                 printk(KERN_DEBUG "apm: received unknown "
1239                                        "event 0x%02x\n", event);
1240                 }
1241                 if (ignore_bounce
1242                     && ((jiffies - last_resume) > bounce_interval))
1243                         ignore_bounce = 0;
1244                 if (ignore_normal_resume && (event != APM_NORMAL_RESUME))
1245                         ignore_normal_resume = 0;
1246
1247                 switch (event) {
1248                 case APM_SYS_STANDBY:
1249                 case APM_USER_STANDBY:
1250                         if (send_event(event)) {
1251                                 queue_event(event, NULL);
1252                                 if (standbys_pending <= 0)
1253                                         standby();
1254                         }
1255                         break;
1256
1257                 case APM_USER_SUSPEND:
1258 #ifdef CONFIG_APM_IGNORE_USER_SUSPEND
1259                         if (apm_info.connection_version > 0x100)
1260                                 apm_set_power_state(APM_STATE_REJECT);
1261                         break;
1262 #endif
1263                 case APM_SYS_SUSPEND:
1264                         if (ignore_bounce) {
1265                                 if (apm_info.connection_version > 0x100)
1266                                         apm_set_power_state(APM_STATE_REJECT);
1267                                 break;
1268                         }
1269                         /*
1270                          * If we are already processing a SUSPEND,
1271                          * then further SUSPEND events from the BIOS
1272                          * will be ignored.  We also return here to
1273                          * cope with the fact that the Thinkpads keep
1274                          * sending a SUSPEND event until something else
1275                          * happens!
1276                          */
1277                         if (waiting_for_resume)
1278                                 return;
1279                         if (send_event(event)) {
1280                                 queue_event(event, NULL);
1281                                 waiting_for_resume = 1;
1282                                 if (suspends_pending <= 0)
1283                                         (void) suspend();
1284                         }
1285                         break;
1286
1287                 case APM_NORMAL_RESUME:
1288                 case APM_CRITICAL_RESUME:
1289                 case APM_STANDBY_RESUME:
1290                         waiting_for_resume = 0;
1291                         last_resume = jiffies;
1292                         ignore_bounce = 1;
1293                         if ((event != APM_NORMAL_RESUME)
1294                             || (ignore_normal_resume == 0)) {
1295                                 set_time();
1296                                 send_event(event);
1297                                 queue_event(event, NULL);
1298                         }
1299                         break;
1300
1301                 case APM_CAPABILITY_CHANGE:
1302                 case APM_LOW_BATTERY:
1303                 case APM_POWER_STATUS_CHANGE:
1304                         send_event(event);
1305                         queue_event(event, NULL);
1306                         break;
1307
1308                 case APM_UPDATE_TIME:
1309                         set_time();
1310                         break;
1311
1312                 case APM_CRITICAL_SUSPEND:
1313                         send_event(event);
1314                         /*
1315                          * We can only hope it worked - we are not allowed
1316                          * to reject a critical suspend.
1317                          */
1318                         (void) suspend();
1319                         break;
1320                 }
1321         }
1322 }
1323
1324 static void apm_event_handler(void)
1325 {
1326         static int      pending_count = 4;
1327         int             err;
1328
1329         if ((standbys_pending > 0) || (suspends_pending > 0)) {
1330                 if ((apm_info.connection_version > 0x100) &&
1331                                 (pending_count-- <= 0)) {
1332                         pending_count = 4;
1333                         if (debug)
1334                                 printk(KERN_DEBUG "apm: setting state busy\n");
1335                         err = apm_set_power_state(APM_STATE_BUSY);
1336                         if (err)
1337                                 apm_error("busy", err);
1338                 }
1339         } else
1340                 pending_count = 4;
1341         check_events();
1342 }
1343
1344 /*
1345  * This is the APM thread main loop.
1346  *
1347  * Check whether we're the only running process to
1348  * decide if we should just power down.
1349  *
1350  */
1351 #define system_idle() (nr_running == 1)
1352
1353 static void apm_mainloop(void)
1354 {
1355         int timeout = HZ;
1356         DECLARE_WAITQUEUE(wait, current);
1357
1358         add_wait_queue(&apm_waitqueue, &wait);
1359         set_current_state(TASK_INTERRUPTIBLE);
1360         for (;;) {
1361                 /* Nothing to do, just sleep for the timeout */
1362                 timeout = 2 * timeout;
1363                 if (timeout > APM_CHECK_TIMEOUT)
1364                         timeout = APM_CHECK_TIMEOUT;
1365                 schedule_timeout(timeout);
1366                 if (exit_kapmd)
1367                         break;
1368
1369                 /*
1370                  * Ok, check all events, check for idle (and mark us sleeping
1371                  * so as not to count towards the load average)..
1372                  */
1373                 set_current_state(TASK_INTERRUPTIBLE);
1374                 apm_event_handler();
1375 #ifdef CONFIG_APM_CPU_IDLE
1376                 if (!system_idle())
1377                         continue;
1378                 
1379                 /*
1380                  *      If we can idle...
1381                  */
1382                 if (apm_do_idle() != -1) {
1383                         unsigned long start = jiffies;
1384                         while ((!exit_kapmd) && system_idle()) {
1385                                 if (apm_do_idle()) {
1386                                         set_current_state(TASK_INTERRUPTIBLE);
1387                                         /* APM needs us to snooze .. either
1388                                            the BIOS call failed (-1) or it
1389                                            slowed the clock (1). We sleep
1390                                            until it talks to us again */
1391                                         schedule_timeout(1);
1392                                 }
1393                                 if ((jiffies - start) > APM_CHECK_TIMEOUT) {
1394                                         apm_event_handler();
1395                                         start = jiffies;
1396                                 }
1397                         }
1398                         apm_do_busy();
1399                         apm_event_handler();
1400                         timeout = 1;
1401                 }
1402 #endif
1403         }
1404         remove_wait_queue(&apm_waitqueue, &wait);
1405 }
1406
1407 static int check_apm_user(struct apm_user *as, const char *func)
1408 {
1409         if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
1410                 printk(KERN_ERR "apm: %s passed bad filp\n", func);
1411                 return 1;
1412         }
1413         return 0;
1414 }
1415
1416 static ssize_t do_read(struct file *fp, char *buf, size_t count, loff_t *ppos)
1417 {
1418         struct apm_user *       as;
1419         int                     i;
1420         apm_event_t             event;
1421
1422         as = fp->private_data;
1423         if (check_apm_user(as, "read"))
1424                 return -EIO;
1425         if (count < sizeof(apm_event_t))
1426                 return -EINVAL;
1427         if ((queue_empty(as)) && (fp->f_flags & O_NONBLOCK))
1428                 return -EAGAIN;
1429         wait_event_interruptible(apm_waitqueue, !queue_empty(as));
1430         i = count;
1431         while ((i >= sizeof(event)) && !queue_empty(as)) {
1432                 event = get_queued_event(as);
1433                 if (copy_to_user(buf, &event, sizeof(event))) {
1434                         if (i < count)
1435                                 break;
1436                         return -EFAULT;
1437                 }
1438                 switch (event) {
1439                 case APM_SYS_SUSPEND:
1440                 case APM_USER_SUSPEND:
1441                         as->suspends_read++;
1442                         break;
1443
1444                 case APM_SYS_STANDBY:
1445                 case APM_USER_STANDBY:
1446                         as->standbys_read++;
1447                         break;
1448                 }
1449                 buf += sizeof(event);
1450                 i -= sizeof(event);
1451         }
1452         if (i < count)
1453                 return count - i;
1454         if (signal_pending(current))
1455                 return -ERESTARTSYS;
1456         return 0;
1457 }
1458
1459 static unsigned int do_poll(struct file *fp, poll_table * wait)
1460 {
1461         struct apm_user * as;
1462
1463         as = fp->private_data;
1464         if (check_apm_user(as, "poll"))
1465                 return 0;
1466         poll_wait(fp, &apm_waitqueue, wait);
1467         if (!queue_empty(as))
1468                 return POLLIN | POLLRDNORM;
1469         return 0;
1470 }
1471
1472 static int do_ioctl(struct inode * inode, struct file *filp,
1473                     u_int cmd, u_long arg)
1474 {
1475         struct apm_user *       as;
1476
1477         as = filp->private_data;
1478         if (check_apm_user(as, "ioctl"))
1479                 return -EIO;
1480         if ((!as->suser) || (!as->writer))
1481                 return -EPERM;
1482         switch (cmd) {
1483         case APM_IOC_STANDBY:
1484                 if (as->standbys_read > 0) {
1485                         as->standbys_read--;
1486                         as->standbys_pending--;
1487                         standbys_pending--;
1488                 } else if (!send_event(APM_USER_STANDBY))
1489                         return -EAGAIN;
1490                 else
1491                         queue_event(APM_USER_STANDBY, as);
1492                 if (standbys_pending <= 0)
1493                         standby();
1494                 break;
1495         case APM_IOC_SUSPEND:
1496                 if (as->suspends_read > 0) {
1497                         as->suspends_read--;
1498                         as->suspends_pending--;
1499                         suspends_pending--;
1500                 } else if (!send_event(APM_USER_SUSPEND))
1501                         return -EAGAIN;
1502                 else
1503                         queue_event(APM_USER_SUSPEND, as);
1504                 if (suspends_pending <= 0) {
1505                         if (suspend() != APM_SUCCESS)
1506                                 return -EIO;
1507                 } else {
1508                         as->suspend_wait = 1;
1509                         wait_event_interruptible(apm_suspend_waitqueue,
1510                                         as->suspend_wait == 0);
1511                         return as->suspend_result;
1512                 }
1513                 break;
1514         default:
1515                 return -EINVAL;
1516         }
1517         return 0;
1518 }
1519
1520 static int do_release(struct inode * inode, struct file * filp)
1521 {
1522         struct apm_user *       as;
1523
1524         as = filp->private_data;
1525         if (check_apm_user(as, "release"))
1526                 return 0;
1527         filp->private_data = NULL;
1528         if (as->standbys_pending > 0) {
1529                 standbys_pending -= as->standbys_pending;
1530                 if (standbys_pending <= 0)
1531                         standby();
1532         }
1533         if (as->suspends_pending > 0) {
1534                 suspends_pending -= as->suspends_pending;
1535                 if (suspends_pending <= 0)
1536                         (void) suspend();
1537         }
1538         spin_lock(&user_list_lock);
1539         if (user_list == as)
1540                 user_list = as->next;
1541         else {
1542                 struct apm_user *       as1;
1543
1544                 for (as1 = user_list;
1545                      (as1 != NULL) && (as1->next != as);
1546                      as1 = as1->next)
1547                         ;
1548                 if (as1 == NULL)
1549                         printk(KERN_ERR "apm: filp not in user list\n");
1550                 else
1551                         as1->next = as->next;
1552         }
1553         spin_unlock(&user_list_lock);
1554         kfree(as);
1555         return 0;
1556 }
1557
1558 static int do_open(struct inode * inode, struct file * filp)
1559 {
1560         struct apm_user *       as;
1561
1562         as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
1563         if (as == NULL) {
1564                 printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
1565                        sizeof(*as));
1566                 return -ENOMEM;
1567         }
1568         as->magic = APM_BIOS_MAGIC;
1569         as->event_tail = as->event_head = 0;
1570         as->suspends_pending = as->standbys_pending = 0;
1571         as->suspends_read = as->standbys_read = 0;
1572         /*
1573          * XXX - this is a tiny bit broken, when we consider BSD
1574          * process accounting. If the device is opened by root, we
1575          * instantly flag that we used superuser privs. Who knows,
1576          * we might close the device immediately without doing a
1577          * privileged operation -- cevans
1578          */
1579         as->suser = capable(CAP_SYS_ADMIN);
1580         as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
1581         as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
1582         spin_lock(&user_list_lock);
1583         as->next = user_list;
1584         user_list = as;
1585         spin_unlock(&user_list_lock);
1586         filp->private_data = as;
1587         return 0;
1588 }
1589
1590 static int apm_get_info(char *buf, char **start, off_t fpos, int length)
1591 {
1592         char *          p;
1593         unsigned short  bx;
1594         unsigned short  cx;
1595         unsigned short  dx;
1596         int             error;
1597         unsigned short  ac_line_status = 0xff;
1598         unsigned short  battery_status = 0xff;
1599         unsigned short  battery_flag   = 0xff;
1600         int             percentage     = -1;
1601         int             time_units     = -1;
1602         char            *units         = "?";
1603
1604         p = buf;
1605
1606         if ((smp_num_cpus == 1) &&
1607             !(error = apm_get_power_status(&bx, &cx, &dx))) {
1608                 ac_line_status = (bx >> 8) & 0xff;
1609                 battery_status = bx & 0xff;
1610                 if ((cx & 0xff) != 0xff)
1611                         percentage = cx & 0xff;
1612
1613                 if (apm_info.connection_version > 0x100) {
1614                         battery_flag = (cx >> 8) & 0xff;
1615                         if (dx != 0xffff) {
1616                                 units = (dx & 0x8000) ? "min" : "sec";
1617                                 time_units = dx & 0x7fff;
1618                         }
1619                 }
1620         }
1621         /* Arguments, with symbols from linux/apm_bios.h.  Information is
1622            from the Get Power Status (0x0a) call unless otherwise noted.
1623
1624            0) Linux driver version (this will change if format changes)
1625            1) APM BIOS Version.  Usually 1.0, 1.1 or 1.2.
1626            2) APM flags from APM Installation Check (0x00):
1627               bit 0: APM_16_BIT_SUPPORT
1628               bit 1: APM_32_BIT_SUPPORT
1629               bit 2: APM_IDLE_SLOWS_CLOCK
1630               bit 3: APM_BIOS_DISABLED
1631               bit 4: APM_BIOS_DISENGAGED
1632            3) AC line status
1633               0x00: Off-line
1634               0x01: On-line
1635               0x02: On backup power (BIOS >= 1.1 only)
1636               0xff: Unknown
1637            4) Battery status
1638               0x00: High
1639               0x01: Low
1640               0x02: Critical
1641               0x03: Charging
1642               0x04: Selected battery not present (BIOS >= 1.2 only)
1643               0xff: Unknown
1644            5) Battery flag
1645               bit 0: High
1646               bit 1: Low
1647               bit 2: Critical
1648               bit 3: Charging
1649               bit 7: No system battery
1650               0xff: Unknown
1651            6) Remaining battery life (percentage of charge):
1652               0-100: valid
1653               -1: Unknown
1654            7) Remaining battery life (time units):
1655               Number of remaining minutes or seconds
1656               -1: Unknown
1657            8) min = minutes; sec = seconds */
1658
1659         p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
1660                      driver_version,
1661                      (apm_info.bios.version >> 8) & 0xff,
1662                      apm_info.bios.version & 0xff,
1663                      apm_info.bios.flags,
1664                      ac_line_status,
1665                      battery_status,
1666                      battery_flag,
1667                      percentage,
1668                      time_units,
1669                      units);
1670
1671         return p - buf;
1672 }
1673
1674 static int apm(void *unused)
1675 {
1676         unsigned short  bx;
1677         unsigned short  cx;
1678         unsigned short  dx;
1679         int             error;
1680         char *          power_stat;
1681         char *          bat_stat;
1682
1683         kapmd_running = 1;
1684
1685         daemonize();
1686
1687         strcpy(current->comm, "kapm-idled");
1688         sigfillset(&current->blocked);
1689         current->tty = NULL;    /* get rid of controlling tty */
1690
1691         if (apm_info.connection_version == 0) {
1692                 apm_info.connection_version = apm_info.bios.version;
1693                 if (apm_info.connection_version > 0x100) {
1694                         /*
1695                          * We only support BIOSs up to version 1.2
1696                          */
1697                         if (apm_info.connection_version > 0x0102)
1698                                 apm_info.connection_version = 0x0102;
1699                         error = apm_driver_version(&apm_info.connection_version);
1700                         if (error != APM_SUCCESS) {
1701                                 apm_error("driver version", error);
1702                                 /* Fall back to an APM 1.0 connection. */
1703                                 apm_info.connection_version = 0x100;
1704                         }
1705                 }
1706         }
1707
1708         if (debug)
1709                 printk(KERN_INFO "apm: Connection version %d.%d\n",
1710                         (apm_info.connection_version >> 8) & 0xff,
1711                         apm_info.connection_version & 0xff);
1712
1713 #ifdef CONFIG_APM_DO_ENABLE
1714         if (apm_info.bios.flags & APM_BIOS_DISABLED) {
1715                 /*
1716                  * This call causes my NEC UltraLite Versa 33/C to hang if it
1717                  * is booted with PM disabled but not in the docking station.
1718                  * Unfortunate ...
1719                  */
1720                 error = apm_enable_power_management(1);
1721                 if (error) {
1722                         apm_error("enable power management", error);
1723                         return -1;
1724                 }
1725         }
1726 #endif
1727
1728         if ((apm_info.bios.flags & APM_BIOS_DISENGAGED)
1729             && (apm_info.connection_version > 0x0100)) {
1730                 error = apm_engage_power_management(APM_DEVICE_ALL, 1);
1731                 if (error) {
1732                         apm_error("engage power management", error);
1733                         return -1;
1734                 }
1735         }
1736
1737         if (debug && (smp_num_cpus == 1)) {
1738                 error = apm_get_power_status(&bx, &cx, &dx);
1739                 if (error)
1740                         printk(KERN_INFO "apm: power status not available\n");
1741                 else {
1742                         switch ((bx >> 8) & 0xff) {
1743                         case 0: power_stat = "off line"; break;
1744                         case 1: power_stat = "on line"; break;
1745                         case 2: power_stat = "on backup power"; break;
1746                         default: power_stat = "unknown"; break;
1747                         }
1748                         switch (bx & 0xff) {
1749                         case 0: bat_stat = "high"; break;
1750                         case 1: bat_stat = "low"; break;
1751                         case 2: bat_stat = "critical"; break;
1752                         case 3: bat_stat = "charging"; break;
1753                         default: bat_stat = "unknown"; break;
1754                         }
1755                         printk(KERN_INFO
1756                                "apm: AC %s, battery status %s, battery life ",
1757                                power_stat, bat_stat);
1758                         if ((cx & 0xff) == 0xff)
1759                                 printk("unknown\n");
1760                         else
1761                                 printk("%d%%\n", cx & 0xff);
1762                         if (apm_info.connection_version > 0x100) {
1763                                 printk(KERN_INFO
1764                                        "apm: battery flag 0x%02x, battery life ",
1765                                        (cx >> 8) & 0xff);
1766                                 if (dx == 0xffff)
1767                                         printk("unknown\n");
1768                                 else
1769                                         printk("%d %s\n", dx & 0x7fff,
1770                                                 (dx & 0x8000) ?
1771                                                 "minutes" : "seconds");
1772                         }
1773                 }
1774         }
1775
1776         /* Install our power off handler.. */
1777         if (power_off)
1778                 pm_power_off = apm_power_off;
1779         register_sysrq_key('o', &sysrq_poweroff_op);
1780
1781         if (smp_num_cpus == 1) {
1782 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1783                 console_blank_hook = apm_console_blank;
1784 #endif
1785                 apm_mainloop();
1786 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1787                 console_blank_hook = NULL;
1788 #endif
1789         }
1790         kapmd_running = 0;
1791
1792         return 0;
1793 }
1794
1795 #ifndef MODULE
1796 static int __init apm_setup(char *str)
1797 {
1798         int     invert;
1799
1800         while ((str != NULL) && (*str != '\0')) {
1801                 if (strncmp(str, "off", 3) == 0)
1802                         apm_disabled = 1;
1803                 if (strncmp(str, "on", 2) == 0)
1804                         apm_disabled = 0;
1805                 if ((strncmp(str, "bounce-interval=", 16) == 0) ||
1806                     (strncmp(str, "bounce_interval=", 16) == 0))
1807                         bounce_interval = simple_strtol(str + 16, NULL, 0);
1808                 invert = (strncmp(str, "no-", 3) == 0);
1809                 if (invert)
1810                         str += 3;
1811                 if (strncmp(str, "debug", 5) == 0)
1812                         debug = !invert;
1813                 if ((strncmp(str, "power-off", 9) == 0) ||
1814                     (strncmp(str, "power_off", 9) == 0))
1815                         power_off = !invert;
1816                 if ((strncmp(str, "allow-ints", 10) == 0) ||
1817                     (strncmp(str, "allow_ints", 10) == 0))
1818                         apm_info.allow_ints = !invert;
1819                 if ((strncmp(str, "broken-psr", 10) == 0) ||
1820                     (strncmp(str, "broken_psr", 10) == 0))
1821                         apm_info.get_power_status_broken = !invert;
1822                 if ((strncmp(str, "realmode-power-off", 18) == 0) ||
1823                     (strncmp(str, "realmode_power_off", 18) == 0))
1824                         apm_info.realmode_power_off = !invert;
1825                 str = strchr(str, ',');
1826                 if (str != NULL)
1827                         str += strspn(str, ", \t");
1828         }
1829         return 1;
1830 }
1831
1832 __setup("apm=", apm_setup);
1833 #endif
1834
1835 static struct file_operations apm_bios_fops = {
1836         owner:          THIS_MODULE,
1837         read:           do_read,
1838         poll:           do_poll,
1839         ioctl:          do_ioctl,
1840         open:           do_open,
1841         release:        do_release,
1842 };
1843
1844 static struct miscdevice apm_device = {
1845         APM_MINOR_DEV,
1846         "apm_bios",
1847         &apm_bios_fops
1848 };
1849
1850 /*
1851  * Just start the APM thread. We do NOT want to do APM BIOS
1852  * calls from anything but the APM thread, if for no other reason
1853  * than the fact that we don't trust the APM BIOS. This way,
1854  * most common APM BIOS problems that lead to protection errors
1855  * etc will have at least some level of being contained...
1856  *
1857  * In short, if something bad happens, at least we have a choice
1858  * of just killing the apm thread..
1859  */
1860 static int __init apm_init(void)
1861 {
1862         struct proc_dir_entry *apm_proc;
1863
1864         if (apm_info.bios.version == 0) {
1865                 printk(KERN_INFO "apm: BIOS not found.\n");
1866                 return -ENODEV;
1867         }
1868         printk(KERN_INFO
1869                 "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
1870                 ((apm_info.bios.version >> 8) & 0xff),
1871                 (apm_info.bios.version & 0xff),
1872                 apm_info.bios.flags,
1873                 driver_version);
1874         if ((apm_info.bios.flags & APM_32_BIT_SUPPORT) == 0) {
1875                 printk(KERN_INFO "apm: no 32 bit BIOS support\n");
1876                 return -ENODEV;
1877         }
1878
1879         if (allow_ints)
1880                 apm_info.allow_ints = 1;
1881         if (broken_psr)
1882                 apm_info.get_power_status_broken = 1;
1883         if (realmode_power_off)
1884                 apm_info.realmode_power_off = 1;
1885         /* User can override, but default is to trust DMI */
1886         if (apm_disabled != -1)
1887                 apm_info.disabled = apm_disabled;
1888
1889         /*
1890          * Fix for the Compaq Contura 3/25c which reports BIOS version 0.1
1891          * but is reportedly a 1.0 BIOS.
1892          */
1893         if (apm_info.bios.version == 0x001)
1894                 apm_info.bios.version = 0x100;
1895
1896         /* BIOS < 1.2 doesn't set cseg_16_len */
1897         if (apm_info.bios.version < 0x102)
1898                 apm_info.bios.cseg_16_len = 0; /* 64k */
1899
1900         if (debug) {
1901                 printk(KERN_INFO "apm: entry %x:%lx cseg16 %x dseg %x",
1902                         apm_info.bios.cseg, apm_info.bios.offset,
1903                         apm_info.bios.cseg_16, apm_info.bios.dseg);
1904                 if (apm_info.bios.version > 0x100)
1905                         printk(" cseg len %x, dseg len %x",
1906                                 apm_info.bios.cseg_len,
1907                                 apm_info.bios.dseg_len);
1908                 if (apm_info.bios.version > 0x101)
1909                         printk(" cseg16 len %x", apm_info.bios.cseg_16_len);
1910                 printk("\n");
1911         }
1912
1913         if (apm_info.disabled) {
1914                 printk(KERN_NOTICE "apm: disabled on user request.\n");
1915                 return -ENODEV;
1916         }
1917         if ((smp_num_cpus > 1) && !power_off) {
1918                 printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
1919                 return -ENODEV;
1920         }
1921         if (PM_IS_ACTIVE()) {
1922                 printk(KERN_NOTICE "apm: overridden by ACPI.\n");
1923                 return -ENODEV;
1924         }
1925         pm_active = 1;
1926
1927         /*
1928          * Set up a segment that references the real mode segment 0x40
1929          * that extends up to the end of page zero (that we have reserved).
1930          * This is for buggy BIOS's that refer to (real mode) segment 0x40
1931          * even though they are called in protected mode.
1932          */
1933         set_base(gdt[APM_40 >> 3],
1934                  __va((unsigned long)0x40 << 4));
1935         _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4));
1936
1937         apm_bios_entry.offset = apm_info.bios.offset;
1938         apm_bios_entry.segment = APM_CS;
1939         set_base(gdt[APM_CS >> 3],
1940                  __va((unsigned long)apm_info.bios.cseg << 4));
1941         set_base(gdt[APM_CS_16 >> 3],
1942                  __va((unsigned long)apm_info.bios.cseg_16 << 4));
1943         set_base(gdt[APM_DS >> 3],
1944                  __va((unsigned long)apm_info.bios.dseg << 4));
1945 #ifndef APM_RELAX_SEGMENTS
1946         if (apm_info.bios.version == 0x100) {
1947 #endif
1948                 /* For ASUS motherboard, Award BIOS rev 110 (and others?) */
1949                 _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
1950                 /* For some unknown machine. */
1951                 _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
1952                 /* For the DEC Hinote Ultra CT475 (and others?) */
1953                 _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
1954 #ifndef APM_RELAX_SEGMENTS
1955         } else {
1956                 _set_limit((char *)&gdt[APM_CS >> 3],
1957                         (apm_info.bios.cseg_len - 1) & 0xffff);
1958                 _set_limit((char *)&gdt[APM_CS_16 >> 3],
1959                         (apm_info.bios.cseg_16_len - 1) & 0xffff);
1960                 _set_limit((char *)&gdt[APM_DS >> 3],
1961                         (apm_info.bios.dseg_len - 1) & 0xffff);
1962         }
1963 #endif
1964
1965         apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
1966         if (apm_proc)
1967                 SET_MODULE_OWNER(apm_proc);
1968
1969         kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
1970
1971         if (smp_num_cpus > 1) {
1972                 printk(KERN_NOTICE
1973                    "apm: disabled - APM is not SMP safe (power off active).\n");
1974                 return 0;
1975         }
1976
1977         misc_register(&apm_device);
1978
1979         return 0;
1980 }
1981
1982 static void __exit apm_exit(void)
1983 {
1984         int     error;
1985
1986         if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
1987             && (apm_info.connection_version > 0x0100)) {
1988                 error = apm_engage_power_management(APM_DEVICE_ALL, 0);
1989                 if (error)
1990                         apm_error("disengage power management", error);
1991         }
1992         misc_deregister(&apm_device);
1993         remove_proc_entry("apm", NULL);
1994         unregister_sysrq_key('o',&sysrq_poweroff_op);
1995         if (power_off)
1996                 pm_power_off = NULL;
1997         exit_kapmd = 1;
1998         while (kapmd_running)
1999                 schedule();
2000         pm_active = 0;
2001 }
2002
2003 module_init(apm_init);
2004 module_exit(apm_exit);
2005
2006 MODULE_AUTHOR("Stephen Rothwell");
2007 MODULE_DESCRIPTION("Advanced Power Management");
2008 MODULE_LICENSE("GPL");
2009 MODULE_PARM(debug, "i");
2010 MODULE_PARM_DESC(debug, "Enable debug mode");
2011 MODULE_PARM(power_off, "i");
2012 MODULE_PARM_DESC(power_off, "Enable power off");
2013 MODULE_PARM(bounce_interval, "i");
2014 MODULE_PARM_DESC(bounce_interval,
2015                 "Set the number of ticks to ignore suspend bounces");
2016 MODULE_PARM(allow_ints, "i");
2017 MODULE_PARM_DESC(allow_ints, "Allow interrupts during BIOS calls");
2018 MODULE_PARM(broken_psr, "i");
2019 MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call");
2020 MODULE_PARM(realmode_power_off, "i");
2021 MODULE_PARM_DESC(realmode_power_off,
2022                 "Switch to real mode before powering off");
2023
2024 EXPORT_NO_SYMBOLS;