xref: /linux/arch/x86/kernel/apm_32.c (revision 07f2961235ac26da12479535cf19a82cde529865)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* -*- linux-c -*-
3  * APM BIOS driver for Linux
4  * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
5  *
6  * Initial development of this driver was funded by NEC Australia P/L
7  *	and NEC Corporation
8  *
9  * October 1995, Rik Faith (faith@cs.unc.edu):
10  *    Minor enhancements and updates (to the patch set) for 1.3.x
11  *    Documentation
12  * January 1996, Rik Faith (faith@cs.unc.edu):
13  *    Make /proc/apm easy to format (bump driver version)
14  * March 1996, Rik Faith (faith@cs.unc.edu):
15  *    Prohibit APM BIOS calls unless apm_enabled.
16  *    (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>)
17  * April 1996, Stephen Rothwell (sfr@canb.auug.org.au)
18  *    Version 1.0 and 1.1
19  * May 1996, Version 1.2
20  * Feb 1998, Version 1.3
21  * Feb 1998, Version 1.4
22  * Aug 1998, Version 1.5
23  * Sep 1998, Version 1.6
24  * Nov 1998, Version 1.7
25  * Jan 1999, Version 1.8
26  * Jan 1999, Version 1.9
27  * Oct 1999, Version 1.10
28  * Nov 1999, Version 1.11
29  * Jan 2000, Version 1.12
30  * Feb 2000, Version 1.13
31  * Nov 2000, Version 1.14
32  * Oct 2001, Version 1.15
33  * Jan 2002, Version 1.16
34  * Oct 2002, Version 1.16ac
35  *
36  * History:
37  *    0.6b: first version in official kernel, Linux 1.3.46
38  *    0.7: changed /proc/apm format, Linux 1.3.58
39  *    0.8: fixed gcc 2.7.[12] compilation problems, Linux 1.3.59
40  *    0.9: only call bios if bios is present, Linux 1.3.72
41  *    1.0: use fixed device number, consolidate /proc/apm into this file,
42  *         Linux 1.3.85
43  *    1.1: support user-space standby and suspend, power off after system
44  *         halted, Linux 1.3.98
45  *    1.2: When resetting RTC after resume, take care so that the time
46  *         is only incorrect by 30-60mS (vs. 1S previously) (Gabor J. Toth
47  *         <jtoth@princeton.edu>); improve interaction between
48  *         screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
49  *    1.2a:Simple change to stop mysterious bug reports with SMP also added
50  *	   levels to the printk calls. APM is not defined for SMP machines.
51  *         The new replacement for it is, but Linux doesn't yet support this.
52  *         Alan Cox Linux 2.1.55
53  *    1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
54  *    1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by
55  *         Dean Gaudet <dgaudet@arctic.org>.
56  *         C. Scott Ananian <cananian@alumni.princeton.edu> Linux 2.1.87
57  *    1.5: Fix segment register reloading (in case of bad segments saved
58  *         across BIOS call).
59  *         Stephen Rothwell
60  *    1.6: Cope with compiler/assembler differences.
61  *         Only try to turn off the first display device.
62  *         Fix OOPS at power off with no APM BIOS by Jan Echternach
63  *                   <echter@informatik.uni-rostock.de>
64  *         Stephen Rothwell
65  *    1.7: Modify driver's cached copy of the disabled/disengaged flags
66  *         to reflect current state of APM BIOS.
67  *         Chris Rankin <rankinc@bellsouth.net>
68  *         Reset interrupt 0 timer to 100Hz after suspend
69  *         Chad Miller <cmiller@surfsouth.com>
70  *         Add CONFIG_APM_IGNORE_SUSPEND_BOUNCE
71  *         Richard Gooch <rgooch@atnf.csiro.au>
72  *         Allow boot time disabling of APM
73  *         Make boot messages far less verbose by default
74  *         Make asm safer
75  *         Stephen Rothwell
76  *    1.8: Add CONFIG_APM_RTC_IS_GMT
77  *         Richard Gooch <rgooch@atnf.csiro.au>
78  *         change APM_NOINTS to CONFIG_APM_ALLOW_INTS
79  *         remove dependency on CONFIG_PROC_FS
80  *         Stephen Rothwell
81  *    1.9: Fix small typo.  <laslo@wodip.opole.pl>
82  *         Try to cope with BIOS's that need to have all display
83  *         devices blanked and not just the first one.
84  *         Ross Paterson <ross@soi.city.ac.uk>
85  *         Fix segment limit setting it has always been wrong as
86  *         the segments needed to have byte granularity.
87  *         Mark a few things __init.
88  *         Add hack to allow power off of SMP systems by popular request.
89  *         Use CONFIG_SMP instead of __SMP__
90  *         Ignore BOUNCES for three seconds.
91  *         Stephen Rothwell
92  *   1.10: Fix for Thinkpad return code.
93  *         Merge 2.2 and 2.3 drivers.
94  *         Remove APM dependencies in arch/i386/kernel/process.c
95  *         Remove APM dependencies in drivers/char/sysrq.c
96  *         Reset time across standby.
97  *         Allow more initialisation on SMP.
98  *         Remove CONFIG_APM_POWER_OFF and make it boot time
99  *         configurable (default on).
100  *         Make debug only a boot time parameter (remove APM_DEBUG).
101  *         Try to blank all devices on any error.
102  *   1.11: Remove APM dependencies in drivers/char/console.c
103  *         Check nr_running to detect if we are idle (from
104  *         Borislav Deianov <borislav@lix.polytechnique.fr>)
105  *         Fix for bioses that don't zero the top part of the
106  *         entrypoint offset (Mario Sitta <sitta@al.unipmn.it>)
107  *         (reported by Panos Katsaloulis <teras@writeme.com>).
108  *         Real mode power off patch (Walter Hofmann
109  *         <Walter.Hofmann@physik.stud.uni-erlangen.de>).
110  *   1.12: Remove CONFIG_SMP as the compiler will optimize
111  *         the code away anyway (smp_num_cpus == 1 in UP)
112  *         noted by Artur Skawina <skawina@geocities.com>.
113  *         Make power off under SMP work again.
114  *         Fix thinko with initial engaging of BIOS.
115  *         Make sure power off only happens on CPU 0
116  *         (Paul "Rusty" Russell <rusty@rustcorp.com.au>).
117  *         Do error notification to user mode if BIOS calls fail.
118  *         Move entrypoint offset fix to ...boot/setup.S
119  *         where it belongs (Cosmos <gis88564@cis.nctu.edu.tw>).
120  *         Remove smp-power-off. SMP users must now specify
121  *         "apm=power-off" on the kernel command line. Suggested
122  *         by Jim Avera <jima@hal.com>, modified by Alan Cox
123  *         <alan@lxorguk.ukuu.org.uk>.
124  *         Register the /proc/apm entry even on SMP so that
125  *         scripts that check for it before doing power off
126  *         work (Jim Avera <jima@hal.com>).
127  *   1.13: Changes for new pm_ interfaces (Andy Henroid
128  *         <andy_henroid@yahoo.com>).
129  *         Modularize the code.
130  *         Fix the Thinkpad (again) :-( (CONFIG_APM_IGNORE_MULTIPLE_SUSPENDS
131  *         is now the way life works).
132  *         Fix thinko in suspend() (wrong return).
133  *         Notify drivers on critical suspend.
134  *         Make kapmd absorb more idle time (Pavel Machek <pavel@ucw.cz>
135  *         modified by sfr).
136  *         Disable interrupts while we are suspended (Andy Henroid
137  *         <andy_henroid@yahoo.com> fixed by sfr).
138  *         Make power off work on SMP again (Tony Hoyle
139  *         <tmh@magenta-logic.com> and <zlatko@iskon.hr>) modified by sfr.
140  *         Remove CONFIG_APM_SUSPEND_BOUNCE.  The bounce ignore
141  *         interval is now configurable.
142  *   1.14: Make connection version persist across module unload/load.
143  *         Enable and engage power management earlier.
144  *         Disengage power management on module unload.
145  *         Changed to use the sysrq-register hack for registering the
146  *         power off function called by magic sysrq based upon discussions
147  *         in irc://irc.openprojects.net/#kernelnewbies
148  *         (Crutcher Dunnavant <crutcher+kernel@datastacks.com>).
149  *         Make CONFIG_APM_REAL_MODE_POWER_OFF run time configurable.
150  *         (Arjan van de Ven <arjanv@redhat.com>) modified by sfr.
151  *         Work around byte swap bug in one of the Vaio's BIOS's
152  *         (Marc Boucher <marc@mbsi.ca>).
153  *         Exposed the disable flag to dmi so that we can handle known
154  *         broken APM (Alan Cox <alan@lxorguk.ukuu.org.uk>).
155  *   1.14ac: If the BIOS says "I slowed the CPU down" then don't spin
156  *         calling it - instead idle. (Alan Cox <alan@lxorguk.ukuu.org.uk>)
157  *         If an APM idle fails log it and idle sensibly
158  *   1.15: Don't queue events to clients who open the device O_WRONLY.
159  *         Don't expect replies from clients who open the device O_RDONLY.
160  *         (Idea from Thomas Hood)
161  *         Minor waitqueue cleanups. (John Fremlin <chief@bandits.org>)
162  *   1.16: Fix idle calling. (Andreas Steinmetz <ast@domdv.de> et al.)
163  *         Notify listeners of standby or suspend events before notifying
164  *         drivers. Return EBUSY to ioctl() if suspend is rejected.
165  *         (Russell King <rmk@arm.linux.org.uk> and Thomas Hood)
166  *         Ignore first resume after we generate our own resume event
167  *         after a suspend (Thomas Hood)
168  *         Daemonize now gets rid of our controlling terminal (sfr).
169  *         CONFIG_APM_CPU_IDLE now just affects the default value of
170  *         idle_threshold (sfr).
171  *         Change name of kernel apm daemon (as it no longer idles) (sfr).
172  *   1.16ac: Fix up SMP support somewhat. You can now force SMP on and we
173  *	   make _all_ APM calls on the CPU#0. Fix unsafe sign bug.
174  *	   TODO: determine if its "boot CPU" or "CPU0" we want to lock to.
175  *
176  * APM 1.1 Reference:
177  *
178  *   Intel Corporation, Microsoft Corporation. Advanced Power Management
179  *   (APM) BIOS Interface Specification, Revision 1.1, September 1993.
180  *   Intel Order Number 241704-001.  Microsoft Part Number 781-110-X01.
181  *
182  * [This document is available free from Intel by calling 800.628.8686 (fax
183  * 916.356.6100) or 800.548.4725; or from
184  * http://www.microsoft.com/whdc/archive/amp_12.mspx  It is also
185  * available from Microsoft by calling 206.882.8080.]
186  *
187  * APM 1.2 Reference:
188  *   Intel Corporation, Microsoft Corporation. Advanced Power Management
189  *   (APM) BIOS Interface Specification, Revision 1.2, February 1996.
190  *
191  * [This document is available from Microsoft at:
192  *    http://www.microsoft.com/whdc/archive/amp_12.mspx]
193  */
194 
195 #define pr_fmt(fmt) "apm: " fmt
196 
197 #include <linux/module.h>
198 
199 #include <linux/poll.h>
200 #include <linux/types.h>
201 #include <linux/stddef.h>
202 #include <linux/timer.h>
203 #include <linux/fcntl.h>
204 #include <linux/slab.h>
205 #include <linux/stat.h>
206 #include <linux/proc_fs.h>
207 #include <linux/seq_file.h>
208 #include <linux/miscdevice.h>
209 #include <linux/apm_bios.h>
210 #include <linux/init.h>
211 #include <linux/time.h>
212 #include <linux/sched/signal.h>
213 #include <linux/sched/cputime.h>
214 #include <linux/pm.h>
215 #include <linux/capability.h>
216 #include <linux/device.h>
217 #include <linux/kernel.h>
218 #include <linux/freezer.h>
219 #include <linux/smp.h>
220 #include <linux/dmi.h>
221 #include <linux/suspend.h>
222 #include <linux/kthread.h>
223 #include <linux/jiffies.h>
224 #include <linux/acpi.h>
225 #include <linux/syscore_ops.h>
226 #include <linux/i8253.h>
227 #include <linux/cpuidle.h>
228 
229 #include <linux/uaccess.h>
230 #include <asm/desc.h>
231 #include <asm/olpc.h>
232 #include <asm/reboot.h>
233 #include <asm/nospec-branch.h>
234 #include <asm/ibt.h>
235 
236 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
237 extern int (*console_blank_hook)(int);
238 #endif
239 
240 /*
241  * Various options can be changed at boot time as follows:
242  * (We allow underscores for compatibility with the modules code)
243  *	apm=on/off			enable/disable APM
244  *	    [no-]allow[-_]ints		allow interrupts during BIOS calls
245  *	    [no-]broken[-_]psr		BIOS has a broken GetPowerStatus call
246  *	    [no-]realmode[-_]power[-_]off	switch to real mode before
247  *	    					powering off
248  *	    [no-]debug			log some debugging messages
249  *	    [no-]power[-_]off		power off on shutdown
250  *	    [no-]smp			Use apm even on an SMP box
251  *	    bounce[-_]interval=<n>	number of ticks to ignore suspend
252  *	    				bounces
253  *          idle[-_]threshold=<n>       System idle percentage above which to
254  *                                      make APM BIOS idle calls. Set it to
255  *                                      100 to disable.
256  *          idle[-_]period=<n>          Period (in 1/100s of a second) over
257  *                                      which the idle percentage is
258  *                                      calculated.
259  */
260 
261 /* KNOWN PROBLEM MACHINES:
262  *
263  * U: TI 4000M TravelMate: BIOS is *NOT* APM compliant
264  *                         [Confirmed by TI representative]
265  * ?: ACER 486DX4/75: uses dseg 0040, in violation of APM specification
266  *                    [Confirmed by BIOS disassembly]
267  *                    [This may work now ...]
268  * P: Toshiba 1950S: battery life information only gets updated after resume
269  * P: Midwest Micro Soundbook Elite DX2/66 monochrome: screen blanking
270  * 	broken in BIOS [Reported by Garst R. Reese <reese@isn.net>]
271  * ?: AcerNote-950: oops on reading /proc/apm - workaround is a WIP
272  * 	Neale Banks <neale@lowendale.com.au> December 2000
273  *
274  * Legend: U = unusable with APM patches
275  *         P = partially usable with APM patches
276  */
277 
278 /*
279  * Define as 1 to make the driver always call the APM BIOS busy
280  * routine even if the clock was not reported as slowed by the
281  * idle routine.  Otherwise, define as 0.
282  */
283 #define ALWAYS_CALL_BUSY   1
284 
285 /*
286  * Define to make the APM BIOS calls zero all data segment registers (so
287  * that an incorrect BIOS implementation will cause a kernel panic if it
288  * tries to write to arbitrary memory).
289  */
290 #define APM_ZERO_SEGS
291 
292 #include <asm/apm.h>
293 
294 /*
295  * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
296  * This patched by Chad Miller <cmiller@surfsouth.com>, original code by
297  * David Chen <chen@ctpa04.mit.edu>
298  */
299 #undef INIT_TIMER_AFTER_SUSPEND
300 
301 #ifdef INIT_TIMER_AFTER_SUSPEND
302 #include <linux/timex.h>
303 #include <asm/io.h>
304 #include <linux/delay.h>
305 #endif
306 
307 /*
308  * Need to poll the APM BIOS every second
309  */
310 #define APM_CHECK_TIMEOUT	(HZ)
311 
312 /*
313  * Ignore suspend events for this amount of time after a resume
314  */
315 #define DEFAULT_BOUNCE_INTERVAL	(3 * HZ)
316 
317 /*
318  * Maximum number of events stored
319  */
320 #define APM_MAX_EVENTS		20
321 
322 /*
323  * The per-file APM data
324  */
325 struct apm_user {
326 	int		magic;
327 	struct apm_user *next;
328 	unsigned int	suser: 1;
329 	unsigned int	writer: 1;
330 	unsigned int	reader: 1;
331 	unsigned int	suspend_wait: 1;
332 	int		suspend_result;
333 	int		suspends_pending;
334 	int		standbys_pending;
335 	int		suspends_read;
336 	int		standbys_read;
337 	int		event_head;
338 	int		event_tail;
339 	apm_event_t	events[APM_MAX_EVENTS];
340 };
341 
342 /*
343  * The magic number in apm_user
344  */
345 #define APM_BIOS_MAGIC		0x4101
346 
347 /*
348  * idle percentage above which bios idle calls are done
349  */
350 #ifdef CONFIG_APM_CPU_IDLE
351 #define DEFAULT_IDLE_THRESHOLD	95
352 #else
353 #define DEFAULT_IDLE_THRESHOLD	100
354 #endif
355 #define DEFAULT_IDLE_PERIOD	(100 / 3)
356 
357 static int apm_cpu_idle(struct cpuidle_device *dev,
358 			struct cpuidle_driver *drv, int index);
359 
360 static struct cpuidle_driver apm_idle_driver = {
361 	.name = "apm_idle",
362 	.owner = THIS_MODULE,
363 	.states = {
364 		{ /* entry 0 is for polling */ },
365 		{ /* entry 1 is for APM idle */
366 			.name = "APM",
367 			.desc = "APM idle",
368 			.exit_latency = 250,	/* WAG */
369 			.target_residency = 500,	/* WAG */
370 			.enter = &apm_cpu_idle
371 		},
372 	},
373 	.state_count = 2,
374 };
375 
376 static struct cpuidle_device apm_cpuidle_device;
377 
378 /*
379  * Local variables
380  */
381 __visible struct {
382 	unsigned long	offset;
383 	unsigned short	segment;
384 } apm_bios_entry;
385 static int clock_slowed;
386 static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD;
387 static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD;
388 static int suspends_pending;
389 static int standbys_pending;
390 static int ignore_sys_suspend;
391 static int ignore_normal_resume;
392 static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL;
393 
394 static bool debug __read_mostly;
395 static bool smp __read_mostly;
396 static int apm_disabled = -1;
397 #ifdef CONFIG_SMP
398 static bool power_off;
399 #else
400 static bool power_off = 1;
401 #endif
402 static bool realmode_power_off;
403 #ifdef CONFIG_APM_ALLOW_INTS
404 static bool allow_ints = 1;
405 #else
406 static bool allow_ints;
407 #endif
408 static bool broken_psr;
409 
410 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
411 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
412 static struct apm_user *user_list;
413 static DEFINE_SPINLOCK(user_list_lock);
414 static DEFINE_MUTEX(apm_mutex);
415 
416 /*
417  * Set up a segment that references the real mode segment 0x40
418  * that extends up to the end of page zero (that we have reserved).
419  * This is for buggy BIOS's that refer to (real mode) segment 0x40
420  * even though they are called in protected mode.
421  */
422 static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(DESC_DATA32_BIOS,
423 			(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
424 
425 static const char driver_version[] = "1.16ac";	/* no spaces */
426 
427 static struct task_struct *kapmd_task;
428 
429 /*
430  *	APM event names taken from the APM 1.2 specification. These are
431  *	the message codes that the BIOS uses to tell us about events
432  */
433 static const char * const apm_event_name[] = {
434 	"system standby",
435 	"system suspend",
436 	"normal resume",
437 	"critical resume",
438 	"low battery",
439 	"power status change",
440 	"update time",
441 	"critical suspend",
442 	"user standby",
443 	"user suspend",
444 	"system standby resume",
445 	"capabilities change"
446 };
447 #define NR_APM_EVENT_NAME ARRAY_SIZE(apm_event_name)
448 
449 typedef struct lookup_t {
450 	int	key;
451 	char 	*msg;
452 } lookup_t;
453 
454 /*
455  *	The BIOS returns a set of standard error codes in AX when the
456  *	carry flag is set.
457  */
458 
459 static const lookup_t error_table[] = {
460 /* N/A	{ APM_SUCCESS,		"Operation succeeded" }, */
461 	{ APM_DISABLED,		"Power management disabled" },
462 	{ APM_CONNECTED,	"Real mode interface already connected" },
463 	{ APM_NOT_CONNECTED,	"Interface not connected" },
464 	{ APM_16_CONNECTED,	"16 bit interface already connected" },
465 /* N/A	{ APM_16_UNSUPPORTED,	"16 bit interface not supported" }, */
466 	{ APM_32_CONNECTED,	"32 bit interface already connected" },
467 	{ APM_32_UNSUPPORTED,	"32 bit interface not supported" },
468 	{ APM_BAD_DEVICE,	"Unrecognized device ID" },
469 	{ APM_BAD_PARAM,	"Parameter out of range" },
470 	{ APM_NOT_ENGAGED,	"Interface not engaged" },
471 	{ APM_BAD_FUNCTION,     "Function not supported" },
472 	{ APM_RESUME_DISABLED,	"Resume timer disabled" },
473 	{ APM_BAD_STATE,	"Unable to enter requested state" },
474 /* N/A	{ APM_NO_EVENTS,	"No events pending" }, */
475 	{ APM_NO_ERROR,		"BIOS did not set a return code" },
476 	{ APM_NOT_PRESENT,	"No APM present" }
477 };
478 #define ERROR_COUNT	ARRAY_SIZE(error_table)
479 
480 /**
481  *	apm_error	-	display an APM error
482  *	@str: information string
483  *	@err: APM BIOS return code
484  *
485  *	Write a meaningful log entry to the kernel log in the event of
486  *	an APM error.  Note that this also handles (negative) kernel errors.
487  */
488 
489 static void apm_error(char *str, int err)
490 {
491 	int i;
492 
493 	for (i = 0; i < ERROR_COUNT; i++)
494 		if (error_table[i].key == err)
495 			break;
496 	if (i < ERROR_COUNT)
497 		pr_notice("%s: %s\n", str, error_table[i].msg);
498 	else if (err < 0)
499 		pr_notice("%s: linux error code %i\n", str, err);
500 	else
501 		pr_notice("%s: unknown error code %#2.2x\n",
502 		       str, err);
503 }
504 
505 /*
506  * These are the actual BIOS calls.  Depending on APM_ZERO_SEGS and
507  * apm_info.allow_ints, we are being really paranoid here!  Not only
508  * are interrupts disabled, but all the segment registers (except SS)
509  * are saved and zeroed this means that if the BIOS tries to reference
510  * any data without explicitly loading the segment registers, the kernel
511  * will fault immediately rather than have some unforeseen circumstances
512  * for the rest of the kernel.  And it will be very obvious!  :-) Doing
513  * this depends on CS referring to the same physical memory as DS so that
514  * DS can be zeroed before the call. Unfortunately, we can't do anything
515  * about the stack segment/pointer.  Also, we tell the compiler that
516  * everything could change.
517  *
518  * Also, we KNOW that for the non error case of apm_bios_call, there
519  * is no useful data returned in the low order 8 bits of eax.
520  */
521 
522 static inline unsigned long __apm_irq_save(void)
523 {
524 	unsigned long flags;
525 	local_save_flags(flags);
526 	if (apm_info.allow_ints) {
527 		if (irqs_disabled_flags(flags))
528 			local_irq_enable();
529 	} else
530 		local_irq_disable();
531 
532 	return flags;
533 }
534 
535 #define apm_irq_save(flags) \
536 	do { flags = __apm_irq_save(); } while (0)
537 
538 static inline void apm_irq_restore(unsigned long flags)
539 {
540 	if (irqs_disabled_flags(flags))
541 		local_irq_disable();
542 	else if (irqs_disabled())
543 		local_irq_enable();
544 }
545 
546 #ifdef APM_ZERO_SEGS
547 #	define APM_DECL_SEGS \
548 		unsigned int saved_fs; unsigned int saved_gs;
549 #	define APM_DO_SAVE_SEGS \
550 		savesegment(fs, saved_fs); savesegment(gs, saved_gs)
551 #	define APM_DO_RESTORE_SEGS \
552 		loadsegment(fs, saved_fs); loadsegment(gs, saved_gs)
553 #else
554 #	define APM_DECL_SEGS
555 #	define APM_DO_SAVE_SEGS
556 #	define APM_DO_RESTORE_SEGS
557 #endif
558 
559 struct apm_bios_call {
560 	u32 func;
561 	/* In and out */
562 	u32 ebx;
563 	u32 ecx;
564 	/* Out only */
565 	u32 eax;
566 	u32 edx;
567 	u32 esi;
568 
569 	/* Error: -ENOMEM, or bits 8-15 of eax */
570 	int err;
571 };
572 
573 /**
574  *	__apm_bios_call - Make an APM BIOS 32bit call
575  *	@_call: pointer to struct apm_bios_call.
576  *
577  *	Make an APM call using the 32bit protected mode interface. The
578  *	caller is responsible for knowing if APM BIOS is configured and
579  *	enabled. This call can disable interrupts for a long period of
580  *	time on some laptops.  The return value is in AH and the carry
581  *	flag is loaded into AL.  If there is an error, then the error
582  *	code is returned in AH (bits 8-15 of eax) and this function
583  *	returns non-zero.
584  *
585  *	Note: this makes the call on the current CPU.
586  */
587 static long __apm_bios_call(void *_call)
588 {
589 	APM_DECL_SEGS
590 	unsigned long		flags;
591 	int			cpu;
592 	struct desc_struct	save_desc_40;
593 	struct desc_struct	*gdt;
594 	struct apm_bios_call	*call = _call;
595 	u64			ibt;
596 
597 	cpu = get_cpu();
598 	BUG_ON(cpu != 0);
599 	gdt = get_cpu_gdt_rw(cpu);
600 	save_desc_40 = gdt[0x40 / 8];
601 	gdt[0x40 / 8] = bad_bios_desc;
602 
603 	apm_irq_save(flags);
604 	firmware_restrict_branch_speculation_start();
605 	ibt = ibt_save(true);
606 	APM_DO_SAVE_SEGS;
607 	apm_bios_call_asm(call->func, call->ebx, call->ecx,
608 			  &call->eax, &call->ebx, &call->ecx, &call->edx,
609 			  &call->esi);
610 	APM_DO_RESTORE_SEGS;
611 	ibt_restore(ibt);
612 	firmware_restrict_branch_speculation_end();
613 	apm_irq_restore(flags);
614 	gdt[0x40 / 8] = save_desc_40;
615 	put_cpu();
616 
617 	return call->eax & 0xff;
618 }
619 
620 /* Run __apm_bios_call or __apm_bios_call_simple on CPU 0 */
621 static int on_cpu0(long (*fn)(void *), struct apm_bios_call *call)
622 {
623 	int ret;
624 
625 	/* Don't bother with work_on_cpu in the common case, so we don't
626 	 * have to worry about OOM or overhead. */
627 	if (get_cpu() == 0) {
628 		ret = fn(call);
629 		put_cpu();
630 	} else {
631 		put_cpu();
632 		ret = work_on_cpu(0, fn, call);
633 	}
634 
635 	/* work_on_cpu can fail with -ENOMEM */
636 	if (ret < 0)
637 		call->err = ret;
638 	else
639 		call->err = (call->eax >> 8) & 0xff;
640 
641 	return ret;
642 }
643 
644 /**
645  *	apm_bios_call	-	Make an APM BIOS 32bit call (on CPU 0)
646  *	@call: the apm_bios_call registers.
647  *
648  *	If there is an error, it is returned in @call.err.
649  */
650 static int apm_bios_call(struct apm_bios_call *call)
651 {
652 	return on_cpu0(__apm_bios_call, call);
653 }
654 
655 /**
656  *	__apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0)
657  *	@_call: pointer to struct apm_bios_call.
658  *
659  *	Make a BIOS call that returns one value only, or just status.
660  *	If there is an error, then the error code is returned in AH
661  *	(bits 8-15 of eax) and this function returns non-zero (it can
662  *	also return -ENOMEM). This is used for simpler BIOS operations.
663  *	This call may hold interrupts off for a long time on some laptops.
664  *
665  *	Note: this makes the call on the current CPU.
666  */
667 static long __apm_bios_call_simple(void *_call)
668 {
669 	u8			error;
670 	APM_DECL_SEGS
671 	unsigned long		flags;
672 	int			cpu;
673 	struct desc_struct	save_desc_40;
674 	struct desc_struct	*gdt;
675 	struct apm_bios_call	*call = _call;
676 	u64			ibt;
677 
678 	cpu = get_cpu();
679 	BUG_ON(cpu != 0);
680 	gdt = get_cpu_gdt_rw(cpu);
681 	save_desc_40 = gdt[0x40 / 8];
682 	gdt[0x40 / 8] = bad_bios_desc;
683 
684 	apm_irq_save(flags);
685 	firmware_restrict_branch_speculation_start();
686 	ibt = ibt_save(true);
687 	APM_DO_SAVE_SEGS;
688 	error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
689 					 &call->eax);
690 	APM_DO_RESTORE_SEGS;
691 	ibt_restore(ibt);
692 	firmware_restrict_branch_speculation_end();
693 	apm_irq_restore(flags);
694 	gdt[0x40 / 8] = save_desc_40;
695 	put_cpu();
696 	return error;
697 }
698 
699 /**
700  *	apm_bios_call_simple	-	make a simple APM BIOS 32bit call
701  *	@func: APM function to invoke
702  *	@ebx_in: EBX register value for BIOS call
703  *	@ecx_in: ECX register value for BIOS call
704  *	@eax: EAX register on return from the BIOS call
705  *	@err: bits
706  *
707  *	Make a BIOS call that returns one value only, or just status.
708  *	If there is an error, then the error code is returned in @err
709  *	and this function returns non-zero. This is used for simpler
710  *	BIOS operations.  This call may hold interrupts off for a long
711  *	time on some laptops.
712  */
713 static int apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax,
714 				int *err)
715 {
716 	struct apm_bios_call call;
717 	int ret;
718 
719 	call.func = func;
720 	call.ebx = ebx_in;
721 	call.ecx = ecx_in;
722 
723 	ret = on_cpu0(__apm_bios_call_simple, &call);
724 	*eax = call.eax;
725 	*err = call.err;
726 	return ret;
727 }
728 
729 /**
730  *	apm_driver_version	-	APM driver version
731  *	@val:	loaded with the APM version on return
732  *
733  *	Retrieve the APM version supported by the BIOS. This is only
734  *	supported for APM 1.1 or higher. An error indicates APM 1.0 is
735  *	probably present.
736  *
737  *	On entry val should point to a value indicating the APM driver
738  *	version with the high byte being the major and the low byte the
739  *	minor number both in BCD
740  *
741  *	On return it will hold the BIOS revision supported in the
742  *	same format.
743  */
744 
745 static int apm_driver_version(u_short *val)
746 {
747 	u32 eax;
748 	int err;
749 
750 	if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax, &err))
751 		return err;
752 	*val = eax;
753 	return APM_SUCCESS;
754 }
755 
756 /**
757  *	apm_get_event	-	get an APM event from the BIOS
758  *	@event: pointer to the event
759  *	@info: point to the event information
760  *
761  *	The APM BIOS provides a polled information for event
762  *	reporting. The BIOS expects to be polled at least every second
763  *	when events are pending. When a message is found the caller should
764  *	poll until no more messages are present.  However, this causes
765  *	problems on some laptops where a suspend event notification is
766  *	not cleared until it is acknowledged.
767  *
768  *	Additional information is returned in the info pointer, providing
769  *	that APM 1.2 is in use. If no messages are pending the value 0x80
770  *	is returned (No power management events pending).
771  */
772 static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
773 {
774 	struct apm_bios_call call;
775 
776 	call.func = APM_FUNC_GET_EVENT;
777 	call.ebx = call.ecx = 0;
778 
779 	if (apm_bios_call(&call))
780 		return call.err;
781 
782 	*event = call.ebx;
783 	if (apm_info.connection_version < 0x0102)
784 		*info = ~0; /* indicate info not valid */
785 	else
786 		*info = call.ecx;
787 	return APM_SUCCESS;
788 }
789 
790 /**
791  *	set_power_state	-	set the power management state
792  *	@what: which items to transition
793  *	@state: state to transition to
794  *
795  *	Request an APM change of state for one or more system devices. The
796  *	processor state must be transitioned last of all. what holds the
797  *	class of device in the upper byte and the device number (0xFF for
798  *	all) for the object to be transitioned.
799  *
800  *	The state holds the state to transition to, which may in fact
801  *	be an acceptance of a BIOS requested state change.
802  */
803 
804 static int set_power_state(u_short what, u_short state)
805 {
806 	u32 eax;
807 	int err;
808 
809 	if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax, &err))
810 		return err;
811 	return APM_SUCCESS;
812 }
813 
814 /**
815  *	set_system_power_state - set system wide power state
816  *	@state: which state to enter
817  *
818  *	Transition the entire system into a new APM power state.
819  */
820 
821 static int set_system_power_state(u_short state)
822 {
823 	return set_power_state(APM_DEVICE_ALL, state);
824 }
825 
826 /**
827  *	apm_do_idle	-	perform power saving
828  *
829  *	This function notifies the BIOS that the processor is (in the view
830  *	of the OS) idle. It returns -1 in the event that the BIOS refuses
831  *	to handle the idle request. On a success the function returns 1
832  *	if the BIOS did clock slowing or 0 otherwise.
833  */
834 
835 static int apm_do_idle(void)
836 {
837 	u32 eax;
838 	u8 ret = 0;
839 	int idled = 0;
840 	int err = 0;
841 
842 	if (!need_resched()) {
843 		idled = 1;
844 		ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
845 	}
846 
847 	if (!idled)
848 		return 0;
849 
850 	if (ret) {
851 		static unsigned long t;
852 
853 		/* This always fails on some SMP boards running UP kernels.
854 		 * Only report the failure the first 5 times.
855 		 */
856 		if (++t < 5) {
857 			printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
858 			t = jiffies;
859 		}
860 		return -1;
861 	}
862 	clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
863 	return clock_slowed;
864 }
865 
866 /**
867  *	apm_do_busy	-	inform the BIOS the CPU is busy
868  *
869  *	Request that the BIOS brings the CPU back to full performance.
870  */
871 
872 static void apm_do_busy(void)
873 {
874 	u32 dummy;
875 	int err;
876 
877 	if (clock_slowed || ALWAYS_CALL_BUSY) {
878 		(void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
879 		clock_slowed = 0;
880 	}
881 }
882 
883 /*
884  * If no process has really been interested in
885  * the CPU for some time, we want to call BIOS
886  * power management - we probably want
887  * to conserve power.
888  */
889 #define IDLE_CALC_LIMIT	(HZ * 100)
890 #define IDLE_LEAKY_MAX	16
891 
892 /**
893  * apm_cpu_idle		-	cpu idling for APM capable Linux
894  *
895  * This is the idling function the kernel executes when APM is available. It
896  * tries to do BIOS powermanagement based on the average system idle time.
897  * Furthermore it calls the system default idle routine.
898  */
899 
900 static int apm_cpu_idle(struct cpuidle_device *dev,
901 	struct cpuidle_driver *drv, int index)
902 {
903 	static int use_apm_idle; /* = 0 */
904 	static unsigned int last_jiffies; /* = 0 */
905 	static u64 last_stime; /* = 0 */
906 	u64 stime, utime;
907 
908 	int apm_idle_done = 0;
909 	unsigned int jiffies_since_last_check = jiffies - last_jiffies;
910 	unsigned int bucket;
911 
912 recalc:
913 	task_cputime(current, &utime, &stime);
914 	if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
915 		use_apm_idle = 0;
916 	} else if (jiffies_since_last_check > idle_period) {
917 		unsigned int idle_percentage;
918 
919 		idle_percentage = nsecs_to_jiffies(stime - last_stime);
920 		idle_percentage *= 100;
921 		idle_percentage /= jiffies_since_last_check;
922 		use_apm_idle = (idle_percentage > idle_threshold);
923 		if (apm_info.forbid_idle)
924 			use_apm_idle = 0;
925 	}
926 
927 	last_jiffies = jiffies;
928 	last_stime = stime;
929 
930 	bucket = IDLE_LEAKY_MAX;
931 
932 	while (!need_resched()) {
933 		if (use_apm_idle) {
934 			unsigned int t;
935 
936 			t = jiffies;
937 			switch (apm_do_idle()) {
938 			case 0:
939 				apm_idle_done = 1;
940 				if (t != jiffies) {
941 					if (bucket) {
942 						bucket = IDLE_LEAKY_MAX;
943 						continue;
944 					}
945 				} else if (bucket) {
946 					bucket--;
947 					continue;
948 				}
949 				break;
950 			case 1:
951 				apm_idle_done = 1;
952 				break;
953 			default: /* BIOS refused */
954 				break;
955 			}
956 		}
957 		default_idle();
958 		local_irq_disable();
959 		jiffies_since_last_check = jiffies - last_jiffies;
960 		if (jiffies_since_last_check > idle_period)
961 			goto recalc;
962 	}
963 
964 	if (apm_idle_done)
965 		apm_do_busy();
966 
967 	return index;
968 }
969 
970 /**
971  *	apm_power_off	-	ask the BIOS to power off
972  *
973  *	Handle the power off sequence. This is the one piece of code we
974  *	will execute even on SMP machines. In order to deal with BIOS
975  *	bugs we support real mode APM BIOS power off calls. We also make
976  *	the SMP call on CPU0 as some systems will only honour this call
977  *	on their first cpu.
978  */
979 
980 static void apm_power_off(void)
981 {
982 	/* Some bioses don't like being called from CPU != 0 */
983 	if (apm_info.realmode_power_off) {
984 		set_cpus_allowed_ptr(current, cpumask_of(0));
985 		machine_real_restart(MRR_APM);
986 	} else {
987 		(void)set_system_power_state(APM_STATE_OFF);
988 	}
989 }
990 
991 #ifdef CONFIG_APM_DO_ENABLE
992 
993 /**
994  *	apm_enable_power_management - enable BIOS APM power management
995  *	@enable: enable yes/no
996  *
997  *	Enable or disable the APM BIOS power services.
998  */
999 
1000 static int apm_enable_power_management(int enable)
1001 {
1002 	u32 eax;
1003 	int err;
1004 
1005 	if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED))
1006 		return APM_NOT_ENGAGED;
1007 	if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
1008 				 enable, &eax, &err))
1009 		return err;
1010 	if (enable)
1011 		apm_info.bios.flags &= ~APM_BIOS_DISABLED;
1012 	else
1013 		apm_info.bios.flags |= APM_BIOS_DISABLED;
1014 	return APM_SUCCESS;
1015 }
1016 #endif
1017 
1018 /**
1019  *	apm_get_power_status	-	get current power state
1020  *	@status: returned status
1021  *	@bat: battery info
1022  *	@life: estimated life
1023  *
1024  *	Obtain the current power status from the APM BIOS. We return a
1025  *	status which gives the rough battery status, and current power
1026  *	source. The bat value returned give an estimate as a percentage
1027  *	of life and a status value for the battery. The estimated life
1028  *	if reported is a lifetime in seconds/minutes at current power
1029  *	consumption.
1030  */
1031 
1032 static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
1033 {
1034 	struct apm_bios_call call;
1035 
1036 	call.func = APM_FUNC_GET_STATUS;
1037 	call.ebx = APM_DEVICE_ALL;
1038 	call.ecx = 0;
1039 
1040 	if (apm_info.get_power_status_broken)
1041 		return APM_32_UNSUPPORTED;
1042 	if (apm_bios_call(&call)) {
1043 		if (!call.err)
1044 			return APM_NO_ERROR;
1045 		return call.err;
1046 	}
1047 	*status = call.ebx;
1048 	*bat = call.ecx;
1049 	if (apm_info.get_power_status_swabinminutes) {
1050 		*life = swab16((u16)call.edx);
1051 		*life |= 0x8000;
1052 	} else
1053 		*life = call.edx;
1054 	return APM_SUCCESS;
1055 }
1056 
1057 /**
1058  *	apm_engage_power_management	-	enable PM on a device
1059  *	@device: identity of device
1060  *	@enable: on/off
1061  *
1062  *	Activate or deactivate power management on either a specific device
1063  *	or the entire system (%APM_DEVICE_ALL).
1064  */
1065 
1066 static int apm_engage_power_management(u_short device, int enable)
1067 {
1068 	u32 eax;
1069 	int err;
1070 
1071 	if ((enable == 0) && (device == APM_DEVICE_ALL)
1072 	    && (apm_info.bios.flags & APM_BIOS_DISABLED))
1073 		return APM_DISABLED;
1074 	if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable,
1075 				 &eax, &err))
1076 		return err;
1077 	if (device == APM_DEVICE_ALL) {
1078 		if (enable)
1079 			apm_info.bios.flags &= ~APM_BIOS_DISENGAGED;
1080 		else
1081 			apm_info.bios.flags |= APM_BIOS_DISENGAGED;
1082 	}
1083 	return APM_SUCCESS;
1084 }
1085 
1086 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1087 
1088 /**
1089  *	apm_console_blank	-	blank the display
1090  *	@blank: on/off
1091  *
1092  *	Attempt to blank the console, firstly by blanking just video device
1093  *	zero, and if that fails (some BIOSes don't support it) then it blanks
1094  *	all video devices. Typically the BIOS will do laptop backlight and
1095  *	monitor powerdown for us.
1096  */
1097 
1098 static int apm_console_blank(int blank)
1099 {
1100 	int error = APM_NOT_ENGAGED; /* silence gcc */
1101 	int i;
1102 	u_short state;
1103 	static const u_short dev[3] = { 0x100, 0x1FF, 0x101 };
1104 
1105 	state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
1106 
1107 	for (i = 0; i < ARRAY_SIZE(dev); i++) {
1108 		error = set_power_state(dev[i], state);
1109 
1110 		if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
1111 			return 1;
1112 
1113 		if (error == APM_NOT_ENGAGED)
1114 			break;
1115 	}
1116 
1117 	if (error == APM_NOT_ENGAGED) {
1118 		static int tried;
1119 		int eng_error;
1120 		if (tried++ == 0) {
1121 			eng_error = apm_engage_power_management(APM_DEVICE_ALL, 1);
1122 			if (eng_error) {
1123 				apm_error("set display", error);
1124 				apm_error("engage interface", eng_error);
1125 				return 0;
1126 			} else
1127 				return apm_console_blank(blank);
1128 		}
1129 	}
1130 	apm_error("set display", error);
1131 	return 0;
1132 }
1133 #endif
1134 
1135 static int queue_empty(struct apm_user *as)
1136 {
1137 	return as->event_head == as->event_tail;
1138 }
1139 
1140 static apm_event_t get_queued_event(struct apm_user *as)
1141 {
1142 	if (++as->event_tail >= APM_MAX_EVENTS)
1143 		as->event_tail = 0;
1144 	return as->events[as->event_tail];
1145 }
1146 
1147 static void queue_event(apm_event_t event, struct apm_user *sender)
1148 {
1149 	struct apm_user *as;
1150 
1151 	spin_lock(&user_list_lock);
1152 	if (user_list == NULL)
1153 		goto out;
1154 	for (as = user_list; as != NULL; as = as->next) {
1155 		if ((as == sender) || (!as->reader))
1156 			continue;
1157 		if (++as->event_head >= APM_MAX_EVENTS)
1158 			as->event_head = 0;
1159 
1160 		if (as->event_head == as->event_tail) {
1161 			static int notified;
1162 
1163 			if (notified++ == 0)
1164 				pr_err("an event queue overflowed\n");
1165 			if (++as->event_tail >= APM_MAX_EVENTS)
1166 				as->event_tail = 0;
1167 		}
1168 		as->events[as->event_head] = event;
1169 		if (!as->suser || !as->writer)
1170 			continue;
1171 		switch (event) {
1172 		case APM_SYS_SUSPEND:
1173 		case APM_USER_SUSPEND:
1174 			as->suspends_pending++;
1175 			suspends_pending++;
1176 			break;
1177 
1178 		case APM_SYS_STANDBY:
1179 		case APM_USER_STANDBY:
1180 			as->standbys_pending++;
1181 			standbys_pending++;
1182 			break;
1183 		}
1184 	}
1185 	wake_up_interruptible(&apm_waitqueue);
1186 out:
1187 	spin_unlock(&user_list_lock);
1188 }
1189 
1190 static void reinit_timer(void)
1191 {
1192 #ifdef INIT_TIMER_AFTER_SUSPEND
1193 	unsigned long flags;
1194 
1195 	raw_spin_lock_irqsave(&i8253_lock, flags);
1196 	/* set the clock to HZ */
1197 	outb_p(0x34, PIT_MODE);		/* binary, mode 2, LSB/MSB, ch 0 */
1198 	udelay(10);
1199 	outb_p(LATCH & 0xff, PIT_CH0);	/* LSB */
1200 	udelay(10);
1201 	outb_p(LATCH >> 8, PIT_CH0);	/* MSB */
1202 	udelay(10);
1203 	raw_spin_unlock_irqrestore(&i8253_lock, flags);
1204 #endif
1205 }
1206 
1207 static int suspend(int vetoable)
1208 {
1209 	int err;
1210 	struct apm_user	*as;
1211 
1212 	dpm_suspend_start(PMSG_SUSPEND);
1213 	dpm_suspend_end(PMSG_SUSPEND);
1214 
1215 	local_irq_disable();
1216 	syscore_suspend();
1217 
1218 	local_irq_enable();
1219 
1220 	save_processor_state();
1221 	err = set_system_power_state(APM_STATE_SUSPEND);
1222 	ignore_normal_resume = 1;
1223 	restore_processor_state();
1224 
1225 	local_irq_disable();
1226 	reinit_timer();
1227 
1228 	if (err == APM_NO_ERROR)
1229 		err = APM_SUCCESS;
1230 	if (err != APM_SUCCESS)
1231 		apm_error("suspend", err);
1232 	err = (err == APM_SUCCESS) ? 0 : -EIO;
1233 
1234 	syscore_resume();
1235 	local_irq_enable();
1236 
1237 	dpm_resume_start(PMSG_RESUME);
1238 	dpm_resume_end(PMSG_RESUME);
1239 
1240 	queue_event(APM_NORMAL_RESUME, NULL);
1241 	spin_lock(&user_list_lock);
1242 	for (as = user_list; as != NULL; as = as->next) {
1243 		as->suspend_wait = 0;
1244 		as->suspend_result = err;
1245 	}
1246 	spin_unlock(&user_list_lock);
1247 	wake_up_interruptible(&apm_suspend_waitqueue);
1248 	return err;
1249 }
1250 
1251 static void standby(void)
1252 {
1253 	int err;
1254 
1255 	dpm_suspend_end(PMSG_SUSPEND);
1256 
1257 	local_irq_disable();
1258 	syscore_suspend();
1259 	local_irq_enable();
1260 
1261 	err = set_system_power_state(APM_STATE_STANDBY);
1262 	if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
1263 		apm_error("standby", err);
1264 
1265 	local_irq_disable();
1266 	syscore_resume();
1267 	local_irq_enable();
1268 
1269 	dpm_resume_start(PMSG_RESUME);
1270 }
1271 
1272 static apm_event_t get_event(void)
1273 {
1274 	int error;
1275 	apm_event_t event = APM_NO_EVENTS; /* silence gcc */
1276 	apm_eventinfo_t	info;
1277 
1278 	static int notified;
1279 
1280 	/* we don't use the eventinfo */
1281 	error = apm_get_event(&event, &info);
1282 	if (error == APM_SUCCESS)
1283 		return event;
1284 
1285 	if ((error != APM_NO_EVENTS) && (notified++ == 0))
1286 		apm_error("get_event", error);
1287 
1288 	return 0;
1289 }
1290 
1291 static void check_events(void)
1292 {
1293 	apm_event_t event;
1294 	static unsigned long last_resume;
1295 	static int ignore_bounce;
1296 
1297 	while ((event = get_event()) != 0) {
1298 		if (debug) {
1299 			if (event <= NR_APM_EVENT_NAME)
1300 				printk(KERN_DEBUG "apm: received %s notify\n",
1301 				       apm_event_name[event - 1]);
1302 			else
1303 				printk(KERN_DEBUG "apm: received unknown "
1304 				       "event 0x%02x\n", event);
1305 		}
1306 		if (ignore_bounce
1307 		    && (time_after(jiffies, last_resume + bounce_interval)))
1308 			ignore_bounce = 0;
1309 
1310 		switch (event) {
1311 		case APM_SYS_STANDBY:
1312 		case APM_USER_STANDBY:
1313 			queue_event(event, NULL);
1314 			if (standbys_pending <= 0)
1315 				standby();
1316 			break;
1317 
1318 		case APM_USER_SUSPEND:
1319 #ifdef CONFIG_APM_IGNORE_USER_SUSPEND
1320 			if (apm_info.connection_version > 0x100)
1321 				set_system_power_state(APM_STATE_REJECT);
1322 			break;
1323 #endif
1324 		case APM_SYS_SUSPEND:
1325 			if (ignore_bounce) {
1326 				if (apm_info.connection_version > 0x100)
1327 					set_system_power_state(APM_STATE_REJECT);
1328 				break;
1329 			}
1330 			/*
1331 			 * If we are already processing a SUSPEND,
1332 			 * then further SUSPEND events from the BIOS
1333 			 * will be ignored.  We also return here to
1334 			 * cope with the fact that the Thinkpads keep
1335 			 * sending a SUSPEND event until something else
1336 			 * happens!
1337 			 */
1338 			if (ignore_sys_suspend)
1339 				return;
1340 			ignore_sys_suspend = 1;
1341 			queue_event(event, NULL);
1342 			if (suspends_pending <= 0)
1343 				(void) suspend(1);
1344 			break;
1345 
1346 		case APM_NORMAL_RESUME:
1347 		case APM_CRITICAL_RESUME:
1348 		case APM_STANDBY_RESUME:
1349 			ignore_sys_suspend = 0;
1350 			last_resume = jiffies;
1351 			ignore_bounce = 1;
1352 			if ((event != APM_NORMAL_RESUME)
1353 			    || (ignore_normal_resume == 0)) {
1354 				dpm_resume_end(PMSG_RESUME);
1355 				queue_event(event, NULL);
1356 			}
1357 			ignore_normal_resume = 0;
1358 			break;
1359 
1360 		case APM_CAPABILITY_CHANGE:
1361 		case APM_LOW_BATTERY:
1362 		case APM_POWER_STATUS_CHANGE:
1363 			queue_event(event, NULL);
1364 			/* If needed, notify drivers here */
1365 			break;
1366 
1367 		case APM_UPDATE_TIME:
1368 			break;
1369 
1370 		case APM_CRITICAL_SUSPEND:
1371 			/*
1372 			 * We are not allowed to reject a critical suspend.
1373 			 */
1374 			(void)suspend(0);
1375 			break;
1376 		}
1377 	}
1378 }
1379 
1380 static void apm_event_handler(void)
1381 {
1382 	static int pending_count = 4;
1383 	int err;
1384 
1385 	if ((standbys_pending > 0) || (suspends_pending > 0)) {
1386 		if ((apm_info.connection_version > 0x100) &&
1387 		    (pending_count-- <= 0)) {
1388 			pending_count = 4;
1389 			if (debug)
1390 				printk(KERN_DEBUG "apm: setting state busy\n");
1391 			err = set_system_power_state(APM_STATE_BUSY);
1392 			if (err)
1393 				apm_error("busy", err);
1394 		}
1395 	} else
1396 		pending_count = 4;
1397 	check_events();
1398 }
1399 
1400 /*
1401  * This is the APM thread main loop.
1402  */
1403 
1404 static void apm_mainloop(void)
1405 {
1406 	DECLARE_WAITQUEUE(wait, current);
1407 
1408 	add_wait_queue(&apm_waitqueue, &wait);
1409 	set_current_state(TASK_INTERRUPTIBLE);
1410 	for (;;) {
1411 		schedule_timeout(APM_CHECK_TIMEOUT);
1412 		if (kthread_should_stop())
1413 			break;
1414 		/*
1415 		 * Ok, check all events, check for idle (and mark us sleeping
1416 		 * so as not to count towards the load average)..
1417 		 */
1418 		set_current_state(TASK_INTERRUPTIBLE);
1419 		apm_event_handler();
1420 	}
1421 	remove_wait_queue(&apm_waitqueue, &wait);
1422 }
1423 
1424 static int check_apm_user(struct apm_user *as, const char *func)
1425 {
1426 	if (as == NULL || as->magic != APM_BIOS_MAGIC) {
1427 		pr_err("%s passed bad filp\n", func);
1428 		return 1;
1429 	}
1430 	return 0;
1431 }
1432 
1433 static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
1434 {
1435 	struct apm_user *as;
1436 	int i;
1437 	apm_event_t event;
1438 
1439 	as = fp->private_data;
1440 	if (check_apm_user(as, "read"))
1441 		return -EIO;
1442 	if ((int)count < sizeof(apm_event_t))
1443 		return -EINVAL;
1444 	if ((queue_empty(as)) && (fp->f_flags & O_NONBLOCK))
1445 		return -EAGAIN;
1446 	wait_event_interruptible(apm_waitqueue, !queue_empty(as));
1447 	i = count;
1448 	while ((i >= sizeof(event)) && !queue_empty(as)) {
1449 		event = get_queued_event(as);
1450 		if (copy_to_user(buf, &event, sizeof(event))) {
1451 			if (i < count)
1452 				break;
1453 			return -EFAULT;
1454 		}
1455 		switch (event) {
1456 		case APM_SYS_SUSPEND:
1457 		case APM_USER_SUSPEND:
1458 			as->suspends_read++;
1459 			break;
1460 
1461 		case APM_SYS_STANDBY:
1462 		case APM_USER_STANDBY:
1463 			as->standbys_read++;
1464 			break;
1465 		}
1466 		buf += sizeof(event);
1467 		i -= sizeof(event);
1468 	}
1469 	if (i < count)
1470 		return count - i;
1471 	if (signal_pending(current))
1472 		return -ERESTARTSYS;
1473 	return 0;
1474 }
1475 
1476 static __poll_t do_poll(struct file *fp, poll_table *wait)
1477 {
1478 	struct apm_user *as;
1479 
1480 	as = fp->private_data;
1481 	if (check_apm_user(as, "poll"))
1482 		return 0;
1483 	poll_wait(fp, &apm_waitqueue, wait);
1484 	if (!queue_empty(as))
1485 		return EPOLLIN | EPOLLRDNORM;
1486 	return 0;
1487 }
1488 
1489 static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
1490 {
1491 	struct apm_user *as;
1492 	int ret;
1493 
1494 	as = filp->private_data;
1495 	if (check_apm_user(as, "ioctl"))
1496 		return -EIO;
1497 	if (!as->suser || !as->writer)
1498 		return -EPERM;
1499 	switch (cmd) {
1500 	case APM_IOC_STANDBY:
1501 		mutex_lock(&apm_mutex);
1502 		if (as->standbys_read > 0) {
1503 			as->standbys_read--;
1504 			as->standbys_pending--;
1505 			standbys_pending--;
1506 		} else
1507 			queue_event(APM_USER_STANDBY, as);
1508 		if (standbys_pending <= 0)
1509 			standby();
1510 		mutex_unlock(&apm_mutex);
1511 		break;
1512 	case APM_IOC_SUSPEND:
1513 		mutex_lock(&apm_mutex);
1514 		if (as->suspends_read > 0) {
1515 			as->suspends_read--;
1516 			as->suspends_pending--;
1517 			suspends_pending--;
1518 		} else
1519 			queue_event(APM_USER_SUSPEND, as);
1520 		if (suspends_pending <= 0) {
1521 			ret = suspend(1);
1522 			mutex_unlock(&apm_mutex);
1523 		} else {
1524 			as->suspend_wait = 1;
1525 			mutex_unlock(&apm_mutex);
1526 			wait_event_interruptible(apm_suspend_waitqueue,
1527 					as->suspend_wait == 0);
1528 			ret = as->suspend_result;
1529 		}
1530 		return ret;
1531 	default:
1532 		return -ENOTTY;
1533 	}
1534 	return 0;
1535 }
1536 
1537 static int do_release(struct inode *inode, struct file *filp)
1538 {
1539 	struct apm_user *as;
1540 
1541 	as = filp->private_data;
1542 	if (check_apm_user(as, "release"))
1543 		return 0;
1544 	filp->private_data = NULL;
1545 	if (as->standbys_pending > 0) {
1546 		standbys_pending -= as->standbys_pending;
1547 		if (standbys_pending <= 0)
1548 			standby();
1549 	}
1550 	if (as->suspends_pending > 0) {
1551 		suspends_pending -= as->suspends_pending;
1552 		if (suspends_pending <= 0)
1553 			(void) suspend(1);
1554 	}
1555 	spin_lock(&user_list_lock);
1556 	if (user_list == as)
1557 		user_list = as->next;
1558 	else {
1559 		struct apm_user *as1;
1560 
1561 		for (as1 = user_list;
1562 		     (as1 != NULL) && (as1->next != as);
1563 		     as1 = as1->next)
1564 			;
1565 		if (as1 == NULL)
1566 			pr_err("filp not in user list\n");
1567 		else
1568 			as1->next = as->next;
1569 	}
1570 	spin_unlock(&user_list_lock);
1571 	kfree(as);
1572 	return 0;
1573 }
1574 
1575 static int do_open(struct inode *inode, struct file *filp)
1576 {
1577 	struct apm_user *as;
1578 
1579 	as = kmalloc(sizeof(*as), GFP_KERNEL);
1580 	if (as == NULL)
1581 		return -ENOMEM;
1582 
1583 	as->magic = APM_BIOS_MAGIC;
1584 	as->event_tail = as->event_head = 0;
1585 	as->suspends_pending = as->standbys_pending = 0;
1586 	as->suspends_read = as->standbys_read = 0;
1587 	/*
1588 	 * XXX - this is a tiny bit broken, when we consider BSD
1589 	 * process accounting. If the device is opened by root, we
1590 	 * instantly flag that we used superuser privs. Who knows,
1591 	 * we might close the device immediately without doing a
1592 	 * privileged operation -- cevans
1593 	 */
1594 	as->suser = capable(CAP_SYS_ADMIN);
1595 	as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
1596 	as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
1597 	spin_lock(&user_list_lock);
1598 	as->next = user_list;
1599 	user_list = as;
1600 	spin_unlock(&user_list_lock);
1601 	filp->private_data = as;
1602 	return 0;
1603 }
1604 
1605 #ifdef CONFIG_PROC_FS
1606 static int proc_apm_show(struct seq_file *m, void *v)
1607 {
1608 	unsigned short	bx;
1609 	unsigned short	cx;
1610 	unsigned short	dx;
1611 	int		error;
1612 	unsigned short  ac_line_status = 0xff;
1613 	unsigned short  battery_status = 0xff;
1614 	unsigned short  battery_flag   = 0xff;
1615 	int		percentage     = -1;
1616 	int             time_units     = -1;
1617 	char            *units         = "?";
1618 
1619 	if ((num_online_cpus() == 1) &&
1620 	    !(error = apm_get_power_status(&bx, &cx, &dx))) {
1621 		ac_line_status = (bx >> 8) & 0xff;
1622 		battery_status = bx & 0xff;
1623 		if ((cx & 0xff) != 0xff)
1624 			percentage = cx & 0xff;
1625 
1626 		if (apm_info.connection_version > 0x100) {
1627 			battery_flag = (cx >> 8) & 0xff;
1628 			if (dx != 0xffff) {
1629 				units = (dx & 0x8000) ? "min" : "sec";
1630 				time_units = dx & 0x7fff;
1631 			}
1632 		}
1633 	}
1634 	/* Arguments, with symbols from linux/apm_bios.h.  Information is
1635 	   from the Get Power Status (0x0a) call unless otherwise noted.
1636 
1637 	   0) Linux driver version (this will change if format changes)
1638 	   1) APM BIOS Version.  Usually 1.0, 1.1 or 1.2.
1639 	   2) APM flags from APM Installation Check (0x00):
1640 	      bit 0: APM_16_BIT_SUPPORT
1641 	      bit 1: APM_32_BIT_SUPPORT
1642 	      bit 2: APM_IDLE_SLOWS_CLOCK
1643 	      bit 3: APM_BIOS_DISABLED
1644 	      bit 4: APM_BIOS_DISENGAGED
1645 	   3) AC line status
1646 	      0x00: Off-line
1647 	      0x01: On-line
1648 	      0x02: On backup power (BIOS >= 1.1 only)
1649 	      0xff: Unknown
1650 	   4) Battery status
1651 	      0x00: High
1652 	      0x01: Low
1653 	      0x02: Critical
1654 	      0x03: Charging
1655 	      0x04: Selected battery not present (BIOS >= 1.2 only)
1656 	      0xff: Unknown
1657 	   5) Battery flag
1658 	      bit 0: High
1659 	      bit 1: Low
1660 	      bit 2: Critical
1661 	      bit 3: Charging
1662 	      bit 7: No system battery
1663 	      0xff: Unknown
1664 	   6) Remaining battery life (percentage of charge):
1665 	      0-100: valid
1666 	      -1: Unknown
1667 	   7) Remaining battery life (time units):
1668 	      Number of remaining minutes or seconds
1669 	      -1: Unknown
1670 	   8) min = minutes; sec = seconds */
1671 
1672 	seq_printf(m, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
1673 		   driver_version,
1674 		   (apm_info.bios.version >> 8) & 0xff,
1675 		   apm_info.bios.version & 0xff,
1676 		   apm_info.bios.flags,
1677 		   ac_line_status,
1678 		   battery_status,
1679 		   battery_flag,
1680 		   percentage,
1681 		   time_units,
1682 		   units);
1683 	return 0;
1684 }
1685 #endif
1686 
1687 static int apm(void *unused)
1688 {
1689 	unsigned short	bx;
1690 	unsigned short	cx;
1691 	unsigned short	dx;
1692 	int		error;
1693 	char 		*power_stat;
1694 	char 		*bat_stat;
1695 
1696 	/* 2002/08/01 - WT
1697 	 * This is to avoid random crashes at boot time during initialization
1698 	 * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
1699 	 * Some bioses don't like being called from CPU != 0.
1700 	 * Method suggested by Ingo Molnar.
1701 	 */
1702 	set_cpus_allowed_ptr(current, cpumask_of(0));
1703 	BUG_ON(smp_processor_id() != 0);
1704 
1705 	if (apm_info.connection_version == 0) {
1706 		apm_info.connection_version = apm_info.bios.version;
1707 		if (apm_info.connection_version > 0x100) {
1708 			/*
1709 			 * We only support BIOSs up to version 1.2
1710 			 */
1711 			if (apm_info.connection_version > 0x0102)
1712 				apm_info.connection_version = 0x0102;
1713 			error = apm_driver_version(&apm_info.connection_version);
1714 			if (error != APM_SUCCESS) {
1715 				apm_error("driver version", error);
1716 				/* Fall back to an APM 1.0 connection. */
1717 				apm_info.connection_version = 0x100;
1718 			}
1719 		}
1720 	}
1721 
1722 	if (debug)
1723 		printk(KERN_INFO "apm: Connection version %d.%d\n",
1724 			(apm_info.connection_version >> 8) & 0xff,
1725 			apm_info.connection_version & 0xff);
1726 
1727 #ifdef CONFIG_APM_DO_ENABLE
1728 	if (apm_info.bios.flags & APM_BIOS_DISABLED) {
1729 		/*
1730 		 * This call causes my NEC UltraLite Versa 33/C to hang if it
1731 		 * is booted with PM disabled but not in the docking station.
1732 		 * Unfortunate ...
1733 		 */
1734 		error = apm_enable_power_management(1);
1735 		if (error) {
1736 			apm_error("enable power management", error);
1737 			return -1;
1738 		}
1739 	}
1740 #endif
1741 
1742 	if ((apm_info.bios.flags & APM_BIOS_DISENGAGED)
1743 	    && (apm_info.connection_version > 0x0100)) {
1744 		error = apm_engage_power_management(APM_DEVICE_ALL, 1);
1745 		if (error) {
1746 			apm_error("engage power management", error);
1747 			return -1;
1748 		}
1749 	}
1750 
1751 	if (debug && (num_online_cpus() == 1 || smp)) {
1752 		error = apm_get_power_status(&bx, &cx, &dx);
1753 		if (error)
1754 			printk(KERN_INFO "apm: power status not available\n");
1755 		else {
1756 			switch ((bx >> 8) & 0xff) {
1757 			case 0:
1758 				power_stat = "off line";
1759 				break;
1760 			case 1:
1761 				power_stat = "on line";
1762 				break;
1763 			case 2:
1764 				power_stat = "on backup power";
1765 				break;
1766 			default:
1767 				power_stat = "unknown";
1768 				break;
1769 			}
1770 			switch (bx & 0xff) {
1771 			case 0:
1772 				bat_stat = "high";
1773 				break;
1774 			case 1:
1775 				bat_stat = "low";
1776 				break;
1777 			case 2:
1778 				bat_stat = "critical";
1779 				break;
1780 			case 3:
1781 				bat_stat = "charging";
1782 				break;
1783 			default:
1784 				bat_stat = "unknown";
1785 				break;
1786 			}
1787 			printk(KERN_INFO
1788 			       "apm: AC %s, battery status %s, battery life ",
1789 			       power_stat, bat_stat);
1790 			if ((cx & 0xff) == 0xff)
1791 				printk("unknown\n");
1792 			else
1793 				printk("%d%%\n", cx & 0xff);
1794 			if (apm_info.connection_version > 0x100) {
1795 				printk(KERN_INFO
1796 				       "apm: battery flag 0x%02x, battery life ",
1797 				       (cx >> 8) & 0xff);
1798 				if (dx == 0xffff)
1799 					printk("unknown\n");
1800 				else
1801 					printk("%d %s\n", dx & 0x7fff,
1802 					       (dx & 0x8000) ?
1803 					       "minutes" : "seconds");
1804 			}
1805 		}
1806 	}
1807 
1808 	/* Install our power off handler.. */
1809 	if (power_off)
1810 		pm_power_off = apm_power_off;
1811 
1812 	if (num_online_cpus() == 1 || smp) {
1813 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1814 		console_blank_hook = apm_console_blank;
1815 #endif
1816 		apm_mainloop();
1817 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
1818 		console_blank_hook = NULL;
1819 #endif
1820 	}
1821 
1822 	return 0;
1823 }
1824 
1825 #ifndef MODULE
1826 static int __init apm_setup(char *str)
1827 {
1828 	int invert;
1829 
1830 	while ((str != NULL) && (*str != '\0')) {
1831 		if (strncmp(str, "off", 3) == 0)
1832 			apm_disabled = 1;
1833 		if (strncmp(str, "on", 2) == 0)
1834 			apm_disabled = 0;
1835 		if ((strncmp(str, "bounce-interval=", 16) == 0) ||
1836 		    (strncmp(str, "bounce_interval=", 16) == 0))
1837 			bounce_interval = simple_strtol(str + 16, NULL, 0);
1838 		if ((strncmp(str, "idle-threshold=", 15) == 0) ||
1839 		    (strncmp(str, "idle_threshold=", 15) == 0))
1840 			idle_threshold = simple_strtol(str + 15, NULL, 0);
1841 		if ((strncmp(str, "idle-period=", 12) == 0) ||
1842 		    (strncmp(str, "idle_period=", 12) == 0))
1843 			idle_period = simple_strtol(str + 12, NULL, 0);
1844 		invert = (strncmp(str, "no-", 3) == 0) ||
1845 			(strncmp(str, "no_", 3) == 0);
1846 		if (invert)
1847 			str += 3;
1848 		if (strncmp(str, "debug", 5) == 0)
1849 			debug = !invert;
1850 		if ((strncmp(str, "power-off", 9) == 0) ||
1851 		    (strncmp(str, "power_off", 9) == 0))
1852 			power_off = !invert;
1853 		if (strncmp(str, "smp", 3) == 0) {
1854 			smp = !invert;
1855 			idle_threshold = 100;
1856 		}
1857 		if ((strncmp(str, "allow-ints", 10) == 0) ||
1858 		    (strncmp(str, "allow_ints", 10) == 0))
1859 			apm_info.allow_ints = !invert;
1860 		if ((strncmp(str, "broken-psr", 10) == 0) ||
1861 		    (strncmp(str, "broken_psr", 10) == 0))
1862 			apm_info.get_power_status_broken = !invert;
1863 		if ((strncmp(str, "realmode-power-off", 18) == 0) ||
1864 		    (strncmp(str, "realmode_power_off", 18) == 0))
1865 			apm_info.realmode_power_off = !invert;
1866 		str = strchr(str, ',');
1867 		if (str != NULL)
1868 			str += strspn(str, ", \t");
1869 	}
1870 	return 1;
1871 }
1872 
1873 __setup("apm=", apm_setup);
1874 #endif
1875 
1876 static const struct file_operations apm_bios_fops = {
1877 	.owner		= THIS_MODULE,
1878 	.read		= do_read,
1879 	.poll		= do_poll,
1880 	.unlocked_ioctl	= do_ioctl,
1881 	.open		= do_open,
1882 	.release	= do_release,
1883 	.llseek		= noop_llseek,
1884 };
1885 
1886 static struct miscdevice apm_device = {
1887 	APM_MINOR_DEV,
1888 	"apm_bios",
1889 	&apm_bios_fops
1890 };
1891 
1892 
1893 /* Simple "print if true" callback */
1894 static int __init print_if_true(const struct dmi_system_id *d)
1895 {
1896 	printk("%s\n", d->ident);
1897 	return 0;
1898 }
1899 
1900 /*
1901  * Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it was
1902  * disabled before the suspend. Linux used to get terribly confused by that.
1903  */
1904 static int __init broken_ps2_resume(const struct dmi_system_id *d)
1905 {
1906 	printk(KERN_INFO "%s machine detected. Mousepad Resume Bug "
1907 	       "workaround hopefully not needed.\n", d->ident);
1908 	return 0;
1909 }
1910 
1911 /* Some bioses have a broken protected mode poweroff and need to use realmode */
1912 static int __init set_realmode_power_off(const struct dmi_system_id *d)
1913 {
1914 	if (apm_info.realmode_power_off == 0) {
1915 		apm_info.realmode_power_off = 1;
1916 		printk(KERN_INFO "%s bios detected. "
1917 		       "Using realmode poweroff only.\n", d->ident);
1918 	}
1919 	return 0;
1920 }
1921 
1922 /* Some laptops require interrupts to be enabled during APM calls */
1923 static int __init set_apm_ints(const struct dmi_system_id *d)
1924 {
1925 	if (apm_info.allow_ints == 0) {
1926 		apm_info.allow_ints = 1;
1927 		printk(KERN_INFO "%s machine detected. "
1928 		       "Enabling interrupts during APM calls.\n", d->ident);
1929 	}
1930 	return 0;
1931 }
1932 
1933 /* Some APM bioses corrupt memory or just plain do not work */
1934 static int __init apm_is_horked(const struct dmi_system_id *d)
1935 {
1936 	if (apm_info.disabled == 0) {
1937 		apm_info.disabled = 1;
1938 		printk(KERN_INFO "%s machine detected. "
1939 		       "Disabling APM.\n", d->ident);
1940 	}
1941 	return 0;
1942 }
1943 
1944 static int __init apm_is_horked_d850md(const struct dmi_system_id *d)
1945 {
1946 	if (apm_info.disabled == 0) {
1947 		apm_info.disabled = 1;
1948 		printk(KERN_INFO "%s machine detected. "
1949 		       "Disabling APM.\n", d->ident);
1950 		printk(KERN_INFO "This bug is fixed in bios P15 which is available for\n");
1951 		printk(KERN_INFO "download from support.intel.com\n");
1952 	}
1953 	return 0;
1954 }
1955 
1956 /* Some APM bioses hang on APM idle calls */
1957 static int __init apm_likes_to_melt(const struct dmi_system_id *d)
1958 {
1959 	if (apm_info.forbid_idle == 0) {
1960 		apm_info.forbid_idle = 1;
1961 		printk(KERN_INFO "%s machine detected. "
1962 		       "Disabling APM idle calls.\n", d->ident);
1963 	}
1964 	return 0;
1965 }
1966 
1967 /*
1968  *  Check for clue free BIOS implementations who use
1969  *  the following QA technique
1970  *
1971  *      [ Write BIOS Code ]<------
1972  *               |                ^
1973  *      < Does it Compile >----N--
1974  *               |Y               ^
1975  *	< Does it Boot Win98 >-N--
1976  *               |Y
1977  *           [Ship It]
1978  *
1979  *	Phoenix A04  08/24/2000 is known bad (Dell Inspiron 5000e)
1980  *	Phoenix A07  09/29/2000 is known good (Dell Inspiron 5000)
1981  */
1982 static int __init broken_apm_power(const struct dmi_system_id *d)
1983 {
1984 	apm_info.get_power_status_broken = 1;
1985 	printk(KERN_WARNING "BIOS strings suggest APM bugs, "
1986 	       "disabling power status reporting.\n");
1987 	return 0;
1988 }
1989 
1990 /*
1991  * This bios swaps the APM minute reporting bytes over (Many sony laptops
1992  * have this problem).
1993  */
1994 static int __init swab_apm_power_in_minutes(const struct dmi_system_id *d)
1995 {
1996 	apm_info.get_power_status_swabinminutes = 1;
1997 	printk(KERN_WARNING "BIOS strings suggest APM reports battery life "
1998 	       "in minutes and wrong byte order.\n");
1999 	return 0;
2000 }
2001 
2002 static const struct dmi_system_id apm_dmi_table[] __initconst = {
2003 	{
2004 		print_if_true,
2005 		KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
2006 		{	DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
2007 			DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), },
2008 	},
2009 	{	/* Handle problems with APM on the C600 */
2010 		broken_ps2_resume, "Dell Latitude C600",
2011 		{	DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
2012 			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), },
2013 	},
2014 	{	/* Allow interrupts during suspend on Dell Latitude laptops*/
2015 		set_apm_ints, "Dell Latitude",
2016 		{	DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
2017 			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }
2018 	},
2019 	{	/* APM crashes */
2020 		apm_is_horked, "Dell Inspiron 2500",
2021 		{	DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
2022 			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
2023 			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2024 			DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
2025 	},
2026 	{	/* Allow interrupts during suspend on Dell Inspiron laptops*/
2027 		set_apm_ints, "Dell Inspiron", {
2028 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
2029 			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), },
2030 	},
2031 	{	/* Handle problems with APM on Inspiron 5000e */
2032 		broken_apm_power, "Dell Inspiron 5000e",
2033 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2034 			DMI_MATCH(DMI_BIOS_VERSION, "A04"),
2035 			DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), },
2036 	},
2037 	{	/* Handle problems with APM on Inspiron 2500 */
2038 		broken_apm_power, "Dell Inspiron 2500",
2039 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2040 			DMI_MATCH(DMI_BIOS_VERSION, "A12"),
2041 			DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), },
2042 	},
2043 	{	/* APM crashes */
2044 		apm_is_horked, "Dell Dimension 4100",
2045 		{	DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
2046 			DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
2047 			DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
2048 			DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
2049 	},
2050 	{	/* Allow interrupts during suspend on Compaq Laptops*/
2051 		set_apm_ints, "Compaq 12XL125",
2052 		{	DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
2053 			DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
2054 			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2055 			DMI_MATCH(DMI_BIOS_VERSION, "4.06"), },
2056 	},
2057 	{	/* Allow interrupts during APM or the clock goes slow */
2058 		set_apm_ints, "ASUSTeK",
2059 		{	DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
2060 			DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), },
2061 	},
2062 	{	/* APM blows on shutdown */
2063 		apm_is_horked, "ABIT KX7-333[R]",
2064 		{	DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"),
2065 			DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
2066 	},
2067 	{	/* APM crashes */
2068 		apm_is_horked, "Trigem Delhi3",
2069 		{	DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
2070 			DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), },
2071 	},
2072 	{	/* APM crashes */
2073 		apm_is_horked, "Fujitsu-Siemens",
2074 		{	DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
2075 			DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), },
2076 	},
2077 	{	/* APM crashes */
2078 		apm_is_horked_d850md, "Intel D850MD",
2079 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
2080 			DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), },
2081 	},
2082 	{	/* APM crashes */
2083 		apm_is_horked, "Intel D810EMO",
2084 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
2085 			DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), },
2086 	},
2087 	{	/* APM crashes */
2088 		apm_is_horked, "Dell XPS-Z",
2089 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
2090 			DMI_MATCH(DMI_BIOS_VERSION, "A11"),
2091 			DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
2092 	},
2093 	{	/* APM crashes */
2094 		apm_is_horked, "Sharp PC-PJ/AX",
2095 		{	DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
2096 			DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
2097 			DMI_MATCH(DMI_BIOS_VENDOR, "SystemSoft"),
2098 			DMI_MATCH(DMI_BIOS_VERSION, "Version R2.08"), },
2099 	},
2100 	{	/* APM crashes */
2101 		apm_is_horked, "Dell Inspiron 2500",
2102 		{	DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
2103 			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
2104 			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2105 			DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
2106 	},
2107 	{	/* APM idle hangs */
2108 		apm_likes_to_melt, "Jabil AMD",
2109 		{	DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
2110 			DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
2111 	},
2112 	{	/* APM idle hangs */
2113 		apm_likes_to_melt, "AMI Bios",
2114 		{	DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
2115 			DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
2116 	},
2117 	{	/* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
2118 		swab_apm_power_in_minutes, "Sony VAIO",
2119 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2120 			DMI_MATCH(DMI_BIOS_VERSION, "R0206H"),
2121 			DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), },
2122 	},
2123 	{	/* Handle problems with APM on Sony Vaio PCG-N505VX */
2124 		swab_apm_power_in_minutes, "Sony VAIO",
2125 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2126 			DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"),
2127 			DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), },
2128 	},
2129 	{	/* Handle problems with APM on Sony Vaio PCG-XG29 */
2130 		swab_apm_power_in_minutes, "Sony VAIO",
2131 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2132 			DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"),
2133 			DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), },
2134 	},
2135 	{	/* Handle problems with APM on Sony Vaio PCG-Z600NE */
2136 		swab_apm_power_in_minutes, "Sony VAIO",
2137 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2138 			DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"),
2139 			DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), },
2140 	},
2141 	{	/* Handle problems with APM on Sony Vaio PCG-Z600NE */
2142 		swab_apm_power_in_minutes, "Sony VAIO",
2143 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2144 			DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"),
2145 			DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), },
2146 	},
2147 	{	/* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
2148 		swab_apm_power_in_minutes, "Sony VAIO",
2149 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2150 			DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"),
2151 			DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), },
2152 	},
2153 	{	/* Handle problems with APM on Sony Vaio PCG-Z505LS */
2154 		swab_apm_power_in_minutes, "Sony VAIO",
2155 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2156 			DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"),
2157 			DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), },
2158 	},
2159 	{	/* Handle problems with APM on Sony Vaio PCG-Z505LS */
2160 		swab_apm_power_in_minutes, "Sony VAIO",
2161 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2162 			DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"),
2163 			DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), },
2164 	},
2165 	{	/* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
2166 		swab_apm_power_in_minutes, "Sony VAIO",
2167 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2168 			DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"),
2169 			DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), },
2170 	},
2171 	{	/* Handle problems with APM on Sony Vaio PCG-F104K */
2172 		swab_apm_power_in_minutes, "Sony VAIO",
2173 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2174 			DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"),
2175 			DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), },
2176 	},
2177 
2178 	{	/* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
2179 		swab_apm_power_in_minutes, "Sony VAIO",
2180 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2181 			DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"),
2182 			DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), },
2183 	},
2184 	{	/* Handle problems with APM on Sony Vaio PCG-C1VE */
2185 		swab_apm_power_in_minutes, "Sony VAIO",
2186 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2187 			DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"),
2188 			DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), },
2189 	},
2190 	{	/* Handle problems with APM on Sony Vaio PCG-C1VE */
2191 		swab_apm_power_in_minutes, "Sony VAIO",
2192 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
2193 			DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
2194 			DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), },
2195 	},
2196 	{	/* broken PM poweroff bios */
2197 		set_realmode_power_off, "Award Software v4.60 PGMA",
2198 		{	DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
2199 			DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
2200 			DMI_MATCH(DMI_BIOS_DATE, "134526184"), },
2201 	},
2202 
2203 	/* Generic per vendor APM settings  */
2204 
2205 	{	/* Allow interrupts during suspend on IBM laptops */
2206 		set_apm_ints, "IBM",
2207 		{	DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
2208 	},
2209 
2210 	{ }
2211 };
2212 
2213 /*
2214  * Just start the APM thread. We do NOT want to do APM BIOS
2215  * calls from anything but the APM thread, if for no other reason
2216  * than the fact that we don't trust the APM BIOS. This way,
2217  * most common APM BIOS problems that lead to protection errors
2218  * etc will have at least some level of being contained...
2219  *
2220  * In short, if something bad happens, at least we have a choice
2221  * of just killing the apm thread..
2222  */
2223 static int __init apm_init(void)
2224 {
2225 	struct desc_struct *gdt;
2226 	int err;
2227 
2228 	dmi_check_system(apm_dmi_table);
2229 
2230 	if (apm_info.bios.version == 0 || machine_is_olpc()) {
2231 		printk(KERN_INFO "apm: BIOS not found.\n");
2232 		return -ENODEV;
2233 	}
2234 	printk(KERN_INFO
2235 	       "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
2236 	       ((apm_info.bios.version >> 8) & 0xff),
2237 	       (apm_info.bios.version & 0xff),
2238 	       apm_info.bios.flags,
2239 	       driver_version);
2240 	if ((apm_info.bios.flags & APM_32_BIT_SUPPORT) == 0) {
2241 		printk(KERN_INFO "apm: no 32 bit BIOS support\n");
2242 		return -ENODEV;
2243 	}
2244 
2245 	if (allow_ints)
2246 		apm_info.allow_ints = 1;
2247 	if (broken_psr)
2248 		apm_info.get_power_status_broken = 1;
2249 	if (realmode_power_off)
2250 		apm_info.realmode_power_off = 1;
2251 	/* User can override, but default is to trust DMI */
2252 	if (apm_disabled != -1)
2253 		apm_info.disabled = apm_disabled;
2254 
2255 	/*
2256 	 * Fix for the Compaq Contura 3/25c which reports BIOS version 0.1
2257 	 * but is reportedly a 1.0 BIOS.
2258 	 */
2259 	if (apm_info.bios.version == 0x001)
2260 		apm_info.bios.version = 0x100;
2261 
2262 	/* BIOS < 1.2 doesn't set cseg_16_len */
2263 	if (apm_info.bios.version < 0x102)
2264 		apm_info.bios.cseg_16_len = 0; /* 64k */
2265 
2266 	if (debug) {
2267 		printk(KERN_INFO "apm: entry %x:%x cseg16 %x dseg %x",
2268 			apm_info.bios.cseg, apm_info.bios.offset,
2269 			apm_info.bios.cseg_16, apm_info.bios.dseg);
2270 		if (apm_info.bios.version > 0x100)
2271 			printk(" cseg len %x, dseg len %x",
2272 				apm_info.bios.cseg_len,
2273 				apm_info.bios.dseg_len);
2274 		if (apm_info.bios.version > 0x101)
2275 			printk(" cseg16 len %x", apm_info.bios.cseg_16_len);
2276 		printk("\n");
2277 	}
2278 
2279 	if (apm_info.disabled) {
2280 		pr_notice("disabled on user request.\n");
2281 		return -ENODEV;
2282 	}
2283 	if ((num_online_cpus() > 1) && !power_off && !smp) {
2284 		pr_notice("disabled - APM is not SMP safe.\n");
2285 		apm_info.disabled = 1;
2286 		return -ENODEV;
2287 	}
2288 	if (!acpi_disabled) {
2289 		pr_notice("overridden by ACPI.\n");
2290 		apm_info.disabled = 1;
2291 		return -ENODEV;
2292 	}
2293 
2294 	/*
2295 	 * Set up the long jump entry point to the APM BIOS, which is called
2296 	 * from inline assembly.
2297 	 */
2298 	apm_bios_entry.offset = apm_info.bios.offset;
2299 	apm_bios_entry.segment = APM_CS;
2300 
2301 	/*
2302 	 * The APM 1.1 BIOS is supposed to provide limit information that it
2303 	 * recognizes.  Many machines do this correctly, but many others do
2304 	 * not restrict themselves to their claimed limit.  When this happens,
2305 	 * they will cause a segmentation violation in the kernel at boot time.
2306 	 * Most BIOS's, however, will respect a 64k limit, so we use that.
2307 	 *
2308 	 * Note we only set APM segments on CPU zero, since we pin the APM
2309 	 * code to that CPU.
2310 	 */
2311 	gdt = get_cpu_gdt_rw(0);
2312 	set_desc_base(&gdt[APM_CS >> 3],
2313 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
2314 	set_desc_base(&gdt[APM_CS_16 >> 3],
2315 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
2316 	set_desc_base(&gdt[APM_DS >> 3],
2317 		 (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
2318 
2319 	proc_create_single("apm", 0, NULL, proc_apm_show);
2320 
2321 	kapmd_task = kthread_create(apm, NULL, "kapmd");
2322 	if (IS_ERR(kapmd_task)) {
2323 		pr_err("disabled - Unable to start kernel thread\n");
2324 		err = PTR_ERR(kapmd_task);
2325 		kapmd_task = NULL;
2326 		remove_proc_entry("apm", NULL);
2327 		return err;
2328 	}
2329 	wake_up_process(kapmd_task);
2330 
2331 	if (num_online_cpus() > 1 && !smp) {
2332 		printk(KERN_NOTICE
2333 		       "apm: disabled - APM is not SMP safe (power off active).\n");
2334 		return 0;
2335 	}
2336 
2337 	/*
2338 	 * Note we don't actually care if the misc_device cannot be registered.
2339 	 * this driver can do its job without it, even if userspace can't
2340 	 * control it.  just log the error
2341 	 */
2342 	if (misc_register(&apm_device))
2343 		printk(KERN_WARNING "apm: Could not register misc device.\n");
2344 
2345 	if (HZ != 100)
2346 		idle_period = (idle_period * HZ) / 100;
2347 	if (idle_threshold < 100) {
2348 		cpuidle_poll_state_init(&apm_idle_driver);
2349 		if (!cpuidle_register_driver(&apm_idle_driver))
2350 			if (cpuidle_register_device(&apm_cpuidle_device))
2351 				cpuidle_unregister_driver(&apm_idle_driver);
2352 	}
2353 
2354 	return 0;
2355 }
2356 
2357 static void __exit apm_exit(void)
2358 {
2359 	int error;
2360 
2361 	cpuidle_unregister_device(&apm_cpuidle_device);
2362 	cpuidle_unregister_driver(&apm_idle_driver);
2363 
2364 	if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
2365 	    && (apm_info.connection_version > 0x0100)) {
2366 		error = apm_engage_power_management(APM_DEVICE_ALL, 0);
2367 		if (error)
2368 			apm_error("disengage power management", error);
2369 	}
2370 	misc_deregister(&apm_device);
2371 	remove_proc_entry("apm", NULL);
2372 	if (power_off)
2373 		pm_power_off = NULL;
2374 	if (kapmd_task) {
2375 		kthread_stop(kapmd_task);
2376 		kapmd_task = NULL;
2377 	}
2378 }
2379 
2380 module_init(apm_init);
2381 module_exit(apm_exit);
2382 
2383 MODULE_AUTHOR("Stephen Rothwell");
2384 MODULE_DESCRIPTION("Advanced Power Management");
2385 MODULE_LICENSE("GPL");
2386 module_param(debug, bool, 0644);
2387 MODULE_PARM_DESC(debug, "Enable debug mode");
2388 module_param(power_off, bool, 0444);
2389 MODULE_PARM_DESC(power_off, "Enable power off");
2390 module_param(bounce_interval, int, 0444);
2391 MODULE_PARM_DESC(bounce_interval,
2392 		"Set the number of ticks to ignore suspend bounces");
2393 module_param(allow_ints, bool, 0444);
2394 MODULE_PARM_DESC(allow_ints, "Allow interrupts during BIOS calls");
2395 module_param(broken_psr, bool, 0444);
2396 MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call");
2397 module_param(realmode_power_off, bool, 0444);
2398 MODULE_PARM_DESC(realmode_power_off,
2399 		"Switch to real mode before powering off");
2400 module_param(idle_threshold, int, 0444);
2401 MODULE_PARM_DESC(idle_threshold,
2402 	"System idle percentage above which to make APM BIOS idle calls");
2403 module_param(idle_period, int, 0444);
2404 MODULE_PARM_DESC(idle_period,
2405 	"Period (in sec/100) over which to calculate the idle percentage");
2406 module_param(smp, bool, 0444);
2407 MODULE_PARM_DESC(smp,
2408 	"Set this to enable APM use on an SMP platform. Use with caution on older systems");
2409 MODULE_ALIAS_MISCDEV(APM_MINOR_DEV);
2410