2 * APM BIOS driver for Linux
3 * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
5 * Initial development of this driver was funded by NEC Australia P/L
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
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.
18 * October 1995, Rik Faith (faith@cs.unc.edu):
19 * Minor enhancements and updates (to the patch set) for 1.3.x
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)
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
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,
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
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>
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
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
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.
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>
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>)
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.
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.]
182 * Intel Corporation, Microsoft Corporation. Advanced Power Management
183 * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
185 * [This document is available from Microsoft at:
186 * http://www.microsoft.com/hwdev/busbios/amp_12.htm]
189 #include <linux/config.h>
190 #include <linux/module.h>
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>
208 #include <asm/system.h>
209 #include <asm/uaccess.h>
210 #include <asm/desc.h>
212 #include <linux/sysrq.h>
214 extern unsigned long get_cmos_time(void);
215 extern void machine_real_restart(unsigned char *, int);
217 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
218 extern int (*console_blank_hook)(int);
222 * The apm_bios device is one of the misc char devices.
223 * This is its minor number.
225 #define APM_MINOR_DEV 134
228 * See Documentation/Config.help for the configuration options.
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
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
243 /* KNOWN PROBLEM MACHINES:
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
256 * Legend: U = unusable with APM patches
257 * P = partially usable with APM patches
261 * Define to always call the APM BIOS busy routine even if the clock was
262 * not slowed by the idle routine.
264 #define ALWAYS_CALL_BUSY
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).
271 #define APM_ZERO_SEGS
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.
282 #define APM_RELAX_SEGMENTS
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>
289 #undef INIT_TIMER_AFTER_SUSPEND
291 #ifdef INIT_TIMER_AFTER_SUSPEND
292 #include <linux/timex.h>
294 #include <linux/delay.h>
298 * Need to poll the APM BIOS every second
300 #define APM_CHECK_TIMEOUT (HZ)
303 * Ignore suspend events for this amount of time after a resume
305 #define DEFAULT_BOUNCE_INTERVAL (3 * HZ)
308 * Save a segment register away
310 #define savesegment(seg, where) \
311 __asm__ __volatile__("movl %%" #seg ",%0" : "=m" (where))
314 * Maximum number of events stored
316 #define APM_MAX_EVENTS 20
319 * The per-file APM data
323 struct apm_user * next;
329 int suspends_pending;
330 int standbys_pending;
335 apm_event_t events[APM_MAX_EVENTS];
339 * The magic number in apm_user
341 #define APM_BIOS_MAGIC 0x4101
347 unsigned long offset;
348 unsigned short segment;
350 #ifdef CONFIG_APM_CPU_IDLE
351 static int clock_slowed;
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;
359 #ifdef CONFIG_APM_RTC_IS_GMT
360 # define clock_cmos_diff 0
361 # define got_clock_diff 1
363 static long clock_cmos_diff;
364 static int got_clock_diff;
367 static int apm_disabled = -1;
369 static int power_off;
371 static int power_off = 1;
373 #ifdef CONFIG_APM_REAL_MODE_POWER_OFF
374 static int realmode_power_off = 1;
376 static int realmode_power_off;
378 static int exit_kapmd;
379 static int kapmd_running;
380 #ifdef CONFIG_APM_ALLOW_INTS
381 static int allow_ints = 1;
383 static int allow_ints;
385 static int broken_psr;
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;
392 static char driver_version[] = "1.15"; /* no spaces */
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
398 static char * apm_event_name[] = {
404 "power status change",
409 "system standby resume",
410 "capabilities change"
412 #define NR_APM_EVENT_NAME \
413 (sizeof(apm_event_name) / sizeof(apm_event_name[0]))
415 typedef struct lookup_t {
421 * The BIOS returns a set of standard error codes in AX when the
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" }
444 #define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
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.
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.
463 if (apm_info.allow_ints) \
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 \
476 "xorl %%edx, %%edx\n\t" \
477 "mov %%dx, %%ds\n\t" \
478 "mov %%dx, %%es\n\t" \
479 "mov %%dx, %%fs\n\t" \
481 # define APM_DO_POP_SEGS \
484 # define APM_DO_RESTORE_SEGS \
485 loadsegment(fs, saved_fs); loadsegment(gs, saved_gs)
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
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
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
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)
524 * N.B. We do NOT need a cld after the BIOS call
525 * because we always save and restore the flags.
527 __asm__ __volatile__(APM_DO_ZERO_SEGS
530 "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
535 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
537 : "a" (func), "b" (ebx_in), "c" (ecx_in)
540 __restore_flags(flags);
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
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.
558 static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
571 * N.B. We do NOT need a cld after the BIOS call
572 * because we always save and restore the flags.
574 __asm__ __volatile__(APM_DO_ZERO_SEGS
577 "lcall *%%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
582 : "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
584 : "a" (func), "b" (ebx_in), "c" (ecx_in)
588 __restore_flags(flags);
593 * apm_driver_version - APM driver version
594 * @val: loaded with the APM version on return
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
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
604 * On return it will hold the BIOS revision supported in the
608 static int __init apm_driver_version(u_short *val)
612 if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
613 return (eax >> 8) & 0xff;
619 * apm_get_event - get an APM event from the BIOS
620 * @event: pointer to the event
621 * @info: point to the event information
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.
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).
635 static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
642 if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
644 return (eax >> 8) & 0xff;
646 if (apm_info.connection_version < 0x0102)
647 *info = ~0; /* indicate info not valid */
654 * set_power_state - set the power management state
655 * @what: which items to transition
656 * @state: state to transition to
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.
663 * The state holds the state to transition to, which may in fact
664 * be an acceptance of a BIOS requested state change.
667 static int set_power_state(u_short what, u_short state)
671 if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
672 return (eax >> 8) & 0xff;
677 * apm_set_power_state - set system wide power state
678 * @state: which state to enter
680 * Transition the entire system into a new APM power state.
683 static int apm_set_power_state(u_short state)
685 return set_power_state(APM_DEVICE_ALL, state);
688 #ifdef CONFIG_APM_CPU_IDLE
691 * apm_do_idle - perform power saving
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.
699 static int apm_do_idle(void)
704 if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) {
705 static unsigned long t;
707 if (time_after(jiffies, t + 10 * HZ)) {
708 printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
714 slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
715 #ifdef ALWAYS_CALL_BUSY
718 clock_slowed = slowed;
724 * apm_do_busy - inform the BIOS the CPU is busy
726 * Request that the BIOS brings the CPU back to full performance.
729 static void apm_do_busy(void)
734 (void) apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
740 extern int hlt_counter;
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
748 #define HARD_IDLE_TIMEOUT (HZ/3)
750 /* This should wake up kapmd and ask it to slow the CPU */
751 #define powermanagement_idle() do { } while (0)
754 * apm_cpu_idle - cpu idling for APM capable Linux
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.
760 * N.B. This is curently not used for kernels 2.4.x.
763 static void apm_cpu_idle(void)
765 unsigned int start_idle;
767 start_idle = jiffies;
769 if (!current->need_resched) {
770 if (jiffies - start_idle < HARD_IDLE_TIMEOUT) {
771 if (!current_cpu_data.hlt_works_ok)
776 if (!current->need_resched)
784 * Ok, do some power management - we've been idle for too long
786 powermanagement_idle();
791 start_idle = jiffies;
798 static int apm_magic(void * unused)
806 * apm_power_off - ask the BIOS to power off
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.
815 static void apm_power_off(void)
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 */
828 * This may be called on an SMP machine.
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);
838 if (apm_info.realmode_power_off)
839 machine_real_restart(po_bios_call, sizeof(po_bios_call));
841 (void) apm_set_power_state(APM_STATE_OFF);
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)
851 * When the user hits Sys-Rq o to power down the machine this is the
855 void handle_poweroff (int key, struct pt_regs *pt_regs,
856 struct kbd_struct *kbd, struct tty_struct *tty) {
860 struct sysrq_key_op sysrq_poweroff_op = {
861 handler: handle_poweroff,
863 action_msg: "Power Off\n"
867 #ifdef CONFIG_APM_DO_ENABLE
870 * apm_enable_power_management - enable BIOS APM power management
871 * @enable: enable yes/no
873 * Enable or disable the APM BIOS power services.
876 static int apm_enable_power_management(int enable)
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,
884 return (eax >> 8) & 0xff;
886 apm_info.bios.flags &= ~APM_BIOS_DISABLED;
888 apm_info.bios.flags |= APM_BIOS_DISABLED;
894 * apm_get_power_status - get current power state
895 * @status: returned status
897 * @life: estimated life
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
907 static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
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;
922 if (apm_info.get_power_status_swabinminutes) {
923 *life = swab16((u16)edx);
931 static int apm_get_battery_status(u_short which, u_short *status,
932 u_short *bat, u_short *life, u_short *nbat)
940 if (apm_info.connection_version < 0x0102) {
941 /* pretend we only have one battery. */
943 return APM_BAD_DEVICE;
945 return apm_get_power_status(status, bat, life);
948 if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax,
949 &ebx, &ecx, &edx, &esi))
950 return (eax >> 8) & 0xff;
960 * apm_engage_power_management - enable PM on a device
961 * @device: identity of device
964 * Activate or deactive power management on either a specific device
965 * or the entire system (%APM_DEVICE_ALL).
968 static int apm_engage_power_management(u_short device, int enable)
972 if ((enable == 0) && (device == APM_DEVICE_ALL)
973 && (apm_info.bios.flags & APM_BIOS_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) {
979 apm_info.bios.flags &= ~APM_BIOS_DISENGAGED;
981 apm_info.bios.flags |= APM_BIOS_DISENGAGED;
987 * apm_error - display an APM error
988 * @str: information string
989 * @err: APM BIOS return code
991 * Write a meaningful log entry to the kernel log in the event of
995 static void apm_error(char *str, int err)
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);
1004 printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
1008 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1011 * apm_console_blank - blank the display
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.
1020 static int apm_console_blank(int blank)
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);
1035 if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
1037 apm_error("set display", error);
1042 static int queue_empty(struct apm_user *as)
1044 return as->event_head == as->event_tail;
1047 static apm_event_t get_queued_event(struct apm_user *as)
1049 as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
1050 return as->events[as->event_tail];
1053 static void queue_event(apm_event_t event, struct apm_user *sender)
1055 struct apm_user * as;
1057 spin_lock(&user_list_lock);
1058 if (user_list == NULL)
1060 for (as = user_list; as != NULL; as = as->next) {
1061 if ((as == sender) || (!as->reader))
1063 as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
1064 if (as->event_head == as->event_tail) {
1065 static int notified;
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;
1071 as->events[as->event_head] = event;
1072 if ((!as->suser) || (!as->writer))
1075 case APM_SYS_SUSPEND:
1076 case APM_USER_SUSPEND:
1077 as->suspends_pending++;
1081 case APM_SYS_STANDBY:
1082 case APM_USER_STANDBY:
1083 as->standbys_pending++;
1088 wake_up_interruptible(&apm_waitqueue);
1090 spin_unlock(&user_list_lock);
1093 static void set_time(void)
1095 unsigned long flags;
1097 if (got_clock_diff) { /* Must know time zone in order to set clock */
1100 CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
1101 restore_flags(flags);
1105 static void get_time_diff(void)
1107 #ifndef CONFIG_APM_RTC_IS_GMT
1108 unsigned long flags;
1111 * Estimate time zone so that set_time can update the clock
1114 clock_cmos_diff = -get_cmos_time();
1116 clock_cmos_diff += CURRENT_TIME;
1118 restore_flags(flags);
1122 static void reinit_timer(void)
1124 #ifdef INIT_TIMER_AFTER_SUSPEND
1125 unsigned long flags;
1129 /* set the clock to 100 Hz */
1130 outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
1132 outb_p(LATCH & 0xff , 0x40); /* LSB */
1134 outb(LATCH >> 8 , 0x40); /* MSB */
1136 restore_flags(flags);
1140 static int send_event(apm_event_t 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) {
1150 "apm: Critical suspend was vetoed, "
1151 "expect armageddon\n" );
1154 if (apm_info.connection_version > 0x100)
1155 apm_set_power_state(APM_STATE_REJECT);
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);
1169 static int suspend(void)
1172 struct apm_user *as;
1176 err = apm_set_power_state(APM_STATE_SUSPEND);
1179 if (err == APM_NO_ERROR)
1181 if (err != APM_SUCCESS)
1182 apm_error("suspend", err);
1183 send_event(APM_NORMAL_RESUME);
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);
1191 spin_unlock(&user_list_lock);
1192 ignore_normal_resume = 1;
1193 wake_up_interruptible(&apm_suspend_waitqueue);
1197 static void standby(void)
1202 err = apm_set_power_state(APM_STATE_STANDBY);
1203 if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
1204 apm_error("standby", err);
1207 static apm_event_t get_event(void)
1211 apm_eventinfo_t info;
1213 static int notified;
1215 /* we don't use the eventinfo */
1216 error = apm_get_event(&event, &info);
1217 if (error == APM_SUCCESS)
1220 if ((error != APM_NO_EVENTS) && (notified++ == 0))
1221 apm_error("get_event", error);
1226 static void check_events(void)
1229 static unsigned long last_resume;
1230 static int ignore_bounce;
1232 while ((event = get_event()) != 0) {
1234 if (event <= NR_APM_EVENT_NAME)
1235 printk(KERN_DEBUG "apm: received %s notify\n",
1236 apm_event_name[event - 1]);
1238 printk(KERN_DEBUG "apm: received unknown "
1239 "event 0x%02x\n", event);
1242 && ((jiffies - last_resume) > bounce_interval))
1244 if (ignore_normal_resume && (event != APM_NORMAL_RESUME))
1245 ignore_normal_resume = 0;
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)
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);
1263 case APM_SYS_SUSPEND:
1264 if (ignore_bounce) {
1265 if (apm_info.connection_version > 0x100)
1266 apm_set_power_state(APM_STATE_REJECT);
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
1277 if (waiting_for_resume)
1279 if (send_event(event)) {
1280 queue_event(event, NULL);
1281 waiting_for_resume = 1;
1282 if (suspends_pending <= 0)
1287 case APM_NORMAL_RESUME:
1288 case APM_CRITICAL_RESUME:
1289 case APM_STANDBY_RESUME:
1290 waiting_for_resume = 0;
1291 last_resume = jiffies;
1293 if ((event != APM_NORMAL_RESUME)
1294 || (ignore_normal_resume == 0)) {
1297 queue_event(event, NULL);
1301 case APM_CAPABILITY_CHANGE:
1302 case APM_LOW_BATTERY:
1303 case APM_POWER_STATUS_CHANGE:
1305 queue_event(event, NULL);
1308 case APM_UPDATE_TIME:
1312 case APM_CRITICAL_SUSPEND:
1315 * We can only hope it worked - we are not allowed
1316 * to reject a critical suspend.
1324 static void apm_event_handler(void)
1326 static int pending_count = 4;
1329 if ((standbys_pending > 0) || (suspends_pending > 0)) {
1330 if ((apm_info.connection_version > 0x100) &&
1331 (pending_count-- <= 0)) {
1334 printk(KERN_DEBUG "apm: setting state busy\n");
1335 err = apm_set_power_state(APM_STATE_BUSY);
1337 apm_error("busy", err);
1345 * This is the APM thread main loop.
1347 * Check whether we're the only running process to
1348 * decide if we should just power down.
1351 #define system_idle() (nr_running == 1)
1353 static void apm_mainloop(void)
1356 DECLARE_WAITQUEUE(wait, current);
1358 add_wait_queue(&apm_waitqueue, &wait);
1359 set_current_state(TASK_INTERRUPTIBLE);
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);
1370 * Ok, check all events, check for idle (and mark us sleeping
1371 * so as not to count towards the load average)..
1373 set_current_state(TASK_INTERRUPTIBLE);
1374 apm_event_handler();
1375 #ifdef CONFIG_APM_CPU_IDLE
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);
1393 if ((jiffies - start) > APM_CHECK_TIMEOUT) {
1394 apm_event_handler();
1399 apm_event_handler();
1404 remove_wait_queue(&apm_waitqueue, &wait);
1407 static int check_apm_user(struct apm_user *as, const char *func)
1409 if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
1410 printk(KERN_ERR "apm: %s passed bad filp\n", func);
1416 static ssize_t do_read(struct file *fp, char *buf, size_t count, loff_t *ppos)
1418 struct apm_user * as;
1422 as = fp->private_data;
1423 if (check_apm_user(as, "read"))
1425 if (count < sizeof(apm_event_t))
1427 if ((queue_empty(as)) && (fp->f_flags & O_NONBLOCK))
1429 wait_event_interruptible(apm_waitqueue, !queue_empty(as));
1431 while ((i >= sizeof(event)) && !queue_empty(as)) {
1432 event = get_queued_event(as);
1433 if (copy_to_user(buf, &event, sizeof(event))) {
1439 case APM_SYS_SUSPEND:
1440 case APM_USER_SUSPEND:
1441 as->suspends_read++;
1444 case APM_SYS_STANDBY:
1445 case APM_USER_STANDBY:
1446 as->standbys_read++;
1449 buf += sizeof(event);
1454 if (signal_pending(current))
1455 return -ERESTARTSYS;
1459 static unsigned int do_poll(struct file *fp, poll_table * wait)
1461 struct apm_user * as;
1463 as = fp->private_data;
1464 if (check_apm_user(as, "poll"))
1466 poll_wait(fp, &apm_waitqueue, wait);
1467 if (!queue_empty(as))
1468 return POLLIN | POLLRDNORM;
1472 static int do_ioctl(struct inode * inode, struct file *filp,
1473 u_int cmd, u_long arg)
1475 struct apm_user * as;
1477 as = filp->private_data;
1478 if (check_apm_user(as, "ioctl"))
1480 if ((!as->suser) || (!as->writer))
1483 case APM_IOC_STANDBY:
1484 if (as->standbys_read > 0) {
1485 as->standbys_read--;
1486 as->standbys_pending--;
1488 } else if (!send_event(APM_USER_STANDBY))
1491 queue_event(APM_USER_STANDBY, as);
1492 if (standbys_pending <= 0)
1495 case APM_IOC_SUSPEND:
1496 if (as->suspends_read > 0) {
1497 as->suspends_read--;
1498 as->suspends_pending--;
1500 } else if (!send_event(APM_USER_SUSPEND))
1503 queue_event(APM_USER_SUSPEND, as);
1504 if (suspends_pending <= 0) {
1505 if (suspend() != APM_SUCCESS)
1508 as->suspend_wait = 1;
1509 wait_event_interruptible(apm_suspend_waitqueue,
1510 as->suspend_wait == 0);
1511 return as->suspend_result;
1520 static int do_release(struct inode * inode, struct file * filp)
1522 struct apm_user * as;
1524 as = filp->private_data;
1525 if (check_apm_user(as, "release"))
1527 filp->private_data = NULL;
1528 if (as->standbys_pending > 0) {
1529 standbys_pending -= as->standbys_pending;
1530 if (standbys_pending <= 0)
1533 if (as->suspends_pending > 0) {
1534 suspends_pending -= as->suspends_pending;
1535 if (suspends_pending <= 0)
1538 spin_lock(&user_list_lock);
1539 if (user_list == as)
1540 user_list = as->next;
1542 struct apm_user * as1;
1544 for (as1 = user_list;
1545 (as1 != NULL) && (as1->next != as);
1549 printk(KERN_ERR "apm: filp not in user list\n");
1551 as1->next = as->next;
1553 spin_unlock(&user_list_lock);
1558 static int do_open(struct inode * inode, struct file * filp)
1560 struct apm_user * as;
1562 as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
1564 printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
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;
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
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;
1585 spin_unlock(&user_list_lock);
1586 filp->private_data = as;
1590 static int apm_get_info(char *buf, char **start, off_t fpos, int length)
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;
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;
1613 if (apm_info.connection_version > 0x100) {
1614 battery_flag = (cx >> 8) & 0xff;
1616 units = (dx & 0x8000) ? "min" : "sec";
1617 time_units = dx & 0x7fff;
1621 /* Arguments, with symbols from linux/apm_bios.h. Information is
1622 from the Get Power Status (0x0a) call unless otherwise noted.
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
1635 0x02: On backup power (BIOS >= 1.1 only)
1642 0x04: Selected battery not present (BIOS >= 1.2 only)
1649 bit 7: No system battery
1651 6) Remaining battery life (percentage of charge):
1654 7) Remaining battery life (time units):
1655 Number of remaining minutes or seconds
1657 8) min = minutes; sec = seconds */
1659 p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
1661 (apm_info.bios.version >> 8) & 0xff,
1662 apm_info.bios.version & 0xff,
1663 apm_info.bios.flags,
1674 static int apm(void *unused)
1687 strcpy(current->comm, "kapm-idled");
1688 sigfillset(¤t->blocked);
1689 current->tty = NULL; /* get rid of controlling tty */
1691 if (apm_info.connection_version == 0) {
1692 apm_info.connection_version = apm_info.bios.version;
1693 if (apm_info.connection_version > 0x100) {
1695 * We only support BIOSs up to version 1.2
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;
1709 printk(KERN_INFO "apm: Connection version %d.%d\n",
1710 (apm_info.connection_version >> 8) & 0xff,
1711 apm_info.connection_version & 0xff);
1713 #ifdef CONFIG_APM_DO_ENABLE
1714 if (apm_info.bios.flags & APM_BIOS_DISABLED) {
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.
1720 error = apm_enable_power_management(1);
1722 apm_error("enable power management", error);
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);
1732 apm_error("engage power management", error);
1737 if (debug && (smp_num_cpus == 1)) {
1738 error = apm_get_power_status(&bx, &cx, &dx);
1740 printk(KERN_INFO "apm: power status not available\n");
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;
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;
1756 "apm: AC %s, battery status %s, battery life ",
1757 power_stat, bat_stat);
1758 if ((cx & 0xff) == 0xff)
1759 printk("unknown\n");
1761 printk("%d%%\n", cx & 0xff);
1762 if (apm_info.connection_version > 0x100) {
1764 "apm: battery flag 0x%02x, battery life ",
1767 printk("unknown\n");
1769 printk("%d %s\n", dx & 0x7fff,
1771 "minutes" : "seconds");
1776 /* Install our power off handler.. */
1778 pm_power_off = apm_power_off;
1779 register_sysrq_key('o', &sysrq_poweroff_op);
1781 if (smp_num_cpus == 1) {
1782 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1783 console_blank_hook = apm_console_blank;
1786 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1787 console_blank_hook = NULL;
1796 static int __init apm_setup(char *str)
1800 while ((str != NULL) && (*str != '\0')) {
1801 if (strncmp(str, "off", 3) == 0)
1803 if (strncmp(str, "on", 2) == 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);
1811 if (strncmp(str, "debug", 5) == 0)
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, ',');
1827 str += strspn(str, ", \t");
1832 __setup("apm=", apm_setup);
1835 static struct file_operations apm_bios_fops = {
1841 release: do_release,
1844 static struct miscdevice apm_device = {
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...
1857 * In short, if something bad happens, at least we have a choice
1858 * of just killing the apm thread..
1860 static int __init apm_init(void)
1862 struct proc_dir_entry *apm_proc;
1864 if (apm_info.bios.version == 0) {
1865 printk(KERN_INFO "apm: BIOS not found.\n");
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,
1874 if ((apm_info.bios.flags & APM_32_BIT_SUPPORT) == 0) {
1875 printk(KERN_INFO "apm: no 32 bit BIOS support\n");
1880 apm_info.allow_ints = 1;
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;
1890 * Fix for the Compaq Contura 3/25c which reports BIOS version 0.1
1891 * but is reportedly a 1.0 BIOS.
1893 if (apm_info.bios.version == 0x001)
1894 apm_info.bios.version = 0x100;
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 */
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);
1913 if (apm_info.disabled) {
1914 printk(KERN_NOTICE "apm: disabled on user request.\n");
1917 if ((smp_num_cpus > 1) && !power_off) {
1918 printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
1921 if (PM_IS_ACTIVE()) {
1922 printk(KERN_NOTICE "apm: overridden by ACPI.\n");
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.
1933 set_base(gdt[APM_40 >> 3],
1934 __va((unsigned long)0x40 << 4));
1935 _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4));
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) {
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
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);
1965 apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
1967 SET_MODULE_OWNER(apm_proc);
1969 kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
1971 if (smp_num_cpus > 1) {
1973 "apm: disabled - APM is not SMP safe (power off active).\n");
1977 misc_register(&apm_device);
1982 static void __exit apm_exit(void)
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);
1990 apm_error("disengage power management", error);
1992 misc_deregister(&apm_device);
1993 remove_proc_entry("apm", NULL);
1994 unregister_sysrq_key('o',&sysrq_poweroff_op);
1996 pm_power_off = NULL;
1998 while (kapmd_running)
2003 module_init(apm_init);
2004 module_exit(apm_exit);
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");