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