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