GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / x86 / kernel / apm_32.c
blobd579a638a61fb5cdb862a1edaa5ad33df71ca9d4
3 #include <linux/module.h>
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>
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>
38 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
39 extern int (*console_blank_hook)(int);
40 #endif
43 * The apm_bios device is one of the misc char devices.
44 * This is its minor number.
46 #define APM_MINOR_DEV 134
49 * See Documentation/Config.help for the configuration options.
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.
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.
77 #define ALWAYS_CALL_BUSY 1
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).
84 #define APM_ZERO_SEGS
86 #include <asm/apm.h>
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>
93 #undef INIT_TIMER_AFTER_SUSPEND
95 #ifdef INIT_TIMER_AFTER_SUSPEND
96 #include <linux/timex.h>
97 #include <asm/io.h>
98 #include <linux/delay.h>
99 #endif
102 * Need to poll the APM BIOS every second
104 #define APM_CHECK_TIMEOUT (HZ)
107 * Ignore suspend events for this amount of time after a resume
109 #define DEFAULT_BOUNCE_INTERVAL (3 * HZ)
112 * Maximum number of events stored
114 #define APM_MAX_EVENTS 20
117 * The per-file APM data
119 struct 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];
137 * The magic number in apm_user
139 #define APM_BIOS_MAGIC 0x4101
142 * idle percentage above which bios idle calls are done
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)
152 * Local variables
154 static struct {
155 unsigned long offset;
156 unsigned short segment;
157 } apm_bios_entry;
158 static int clock_slowed;
159 static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD;
160 static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD;
161 static int set_pm_idle;
162 static int suspends_pending;
163 static int standbys_pending;
164 static int ignore_sys_suspend;
165 static int ignore_normal_resume;
166 static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL;
168 static int debug __read_mostly;
169 static int smp __read_mostly;
170 static int apm_disabled = -1;
171 #ifdef CONFIG_SMP
172 static int power_off;
173 #else
174 static int power_off = 1;
175 #endif
176 static int realmode_power_off;
177 #ifdef CONFIG_APM_ALLOW_INTS
178 static int allow_ints = 1;
179 #else
180 static int allow_ints;
181 #endif
182 static int broken_psr;
184 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
185 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
186 static struct apm_user *user_list;
187 static DEFINE_SPINLOCK(user_list_lock);
188 static DEFINE_MUTEX(apm_mutex);
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.
196 static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
197 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
199 static const char driver_version[] = "1.16ac"; /* no spaces */
201 static struct task_struct *kapmd_task;
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
207 static 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"
221 #define NR_APM_EVENT_NAME ARRAY_SIZE(apm_event_name)
223 typedef struct lookup_t {
224 int key;
225 char *msg;
226 } lookup_t;
229 * The BIOS returns a set of standard error codes in AX when the
230 * carry flag is set.
233 static 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" }
252 #define ERROR_COUNT ARRAY_SIZE(error_table)
255 * apm_error - display an APM error
256 * @str: information string
257 * @err: APM BIOS return code
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.
263 static void apm_error(char *str, int err)
265 int i;
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);
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.
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.
296 static inline unsigned long __apm_irq_save(void)
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();
306 return flags;
309 #define apm_irq_save(flags) \
310 do { flags = __apm_irq_save(); } while (0)
312 static inline void apm_irq_restore(unsigned long flags)
314 if (irqs_disabled_flags(flags))
315 local_irq_disable();
316 else if (irqs_disabled())
317 local_irq_enable();
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
333 struct 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;
343 /* Error: -ENOMEM, or bits 8-15 of eax */
344 int err;
348 * __apm_bios_call - Make an APM BIOS 32bit call
349 * @_call: pointer to struct apm_bios_call.
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.
359 * Note: this makes the call on the current CPU.
361 static long __apm_bios_call(void *_call)
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;
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;
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();
386 return call->eax & 0xff;
389 /* Run __apm_bios_call or __apm_bios_call_simple on CPU 0 */
390 static int on_cpu0(long (*fn)(void *), struct apm_bios_call *call)
392 int ret;
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);
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;
410 return ret;
414 * apm_bios_call - Make an APM BIOS 32bit call (on CPU 0)
415 * @call: the apm_bios_call registers.
417 * If there is an error, it is returned in @call.err.
419 static int apm_bios_call(struct apm_bios_call *call)
421 return on_cpu0(__apm_bios_call, call);
425 * __apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0)
426 * @_call: pointer to struct apm_bios_call.
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.
434 * Note: this makes the call on the current CPU.
436 static long __apm_bios_call_simple(void *_call)
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;
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;
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;
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
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.
477 static int apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax,
478 int *err)
480 struct apm_bios_call call;
481 int ret;
483 call.func = func;
484 call.ebx = ebx_in;
485 call.ecx = ecx_in;
487 ret = on_cpu0(__apm_bios_call_simple, &call);
488 *eax = call.eax;
489 *err = call.err;
490 return ret;
494 * apm_driver_version - APM driver version
495 * @val: loaded with the APM version on return
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.
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
505 * On return it will hold the BIOS revision supported in the
506 * same format.
509 static int apm_driver_version(u_short *val)
511 u32 eax;
512 int err;
514 if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax, &err))
515 return err;
516 *val = eax;
517 return APM_SUCCESS;
521 * apm_get_event - get an APM event from the BIOS
522 * @event: pointer to the event
523 * @info: point to the event information
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.
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).
536 static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
538 struct apm_bios_call call;
540 call.func = APM_FUNC_GET_EVENT;
541 call.ebx = call.ecx = 0;
543 if (apm_bios_call(&call))
544 return call.err;
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;
555 * set_power_state - set the power management state
556 * @what: which items to transition
557 * @state: state to transition to
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.
564 * The state holds the state to transition to, which may in fact
565 * be an acceptance of a BIOS requested state change.
568 static int set_power_state(u_short what, u_short state)
570 u32 eax;
571 int err;
573 if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax, &err))
574 return err;
575 return APM_SUCCESS;
579 * set_system_power_state - set system wide power state
580 * @state: which state to enter
582 * Transition the entire system into a new APM power state.
585 static int set_system_power_state(u_short state)
587 return set_power_state(APM_DEVICE_ALL, state);
591 * apm_do_idle - perform power saving
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.
599 static int apm_do_idle(void)
601 u32 eax;
602 u8 ret = 0;
603 int idled = 0;
604 int polling;
605 int err = 0;
607 polling = !!(current_thread_info()->status & TS_POLLING);
608 if (polling) {
609 current_thread_info()->status &= ~TS_POLLING;
611 * TS_POLLING-cleared state must be visible before we
612 * test NEED_RESCHED:
614 smp_mb();
616 if (!need_resched()) {
617 idled = 1;
618 ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
620 if (polling)
621 current_thread_info()->status |= TS_POLLING;
623 if (!idled)
624 return 0;
626 if (ret) {
627 static unsigned long t;
629 /* This always fails on some SMP boards running UP kernels.
630 * Only report the failure the first 5 times.
632 if (++t < 5) {
633 printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
634 t = jiffies;
636 return -1;
638 clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
639 return clock_slowed;
643 * apm_do_busy - inform the BIOS the CPU is busy
645 * Request that the BIOS brings the CPU back to full performance.
648 static void apm_do_busy(void)
650 u32 dummy;
651 int err;
653 if (clock_slowed || ALWAYS_CALL_BUSY) {
654 (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
655 clock_slowed = 0;
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.
665 #define IDLE_CALC_LIMIT (HZ * 100)
666 #define IDLE_LEAKY_MAX 16
668 static void (*original_pm_idle)(void) __read_mostly;
671 * apm_cpu_idle - cpu idling for APM capable Linux
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.
678 static void apm_cpu_idle(void)
680 static int use_apm_idle; /* = 0 */
681 static unsigned int last_jiffies; /* = 0 */
682 static unsigned int last_stime; /* = 0 */
684 int apm_idle_done = 0;
685 unsigned int jiffies_since_last_check = jiffies - last_jiffies;
686 unsigned int bucket;
688 recalc:
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;
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;
706 bucket = IDLE_LEAKY_MAX;
708 while (!need_resched()) {
709 if (use_apm_idle) {
710 unsigned int t;
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;
721 } else if (bucket) {
722 bucket--;
723 continue;
725 break;
726 case 1:
727 apm_idle_done = 1;
728 break;
729 default: /* BIOS refused */
730 break;
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;
743 if (apm_idle_done)
744 apm_do_busy();
746 local_irq_enable();
750 * apm_power_off - ask the BIOS to power off
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.
759 static void apm_power_off(void)
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 */
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);
780 #ifdef CONFIG_APM_DO_ENABLE
783 * apm_enable_power_management - enable BIOS APM power management
784 * @enable: enable yes/no
786 * Enable or disable the APM BIOS power services.
789 static int apm_enable_power_management(int enable)
791 u32 eax;
792 int err;
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;
805 #endif
808 * apm_get_power_status - get current power state
809 * @status: returned status
810 * @bat: battery info
811 * @life: estimated life
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.
821 static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
823 struct apm_bios_call call;
825 call.func = APM_FUNC_GET_STATUS;
826 call.ebx = APM_DEVICE_ALL;
827 call.ecx = 0;
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;
845 * apm_engage_power_management - enable PM on a device
846 * @device: identity of device
847 * @enable: on/off
849 * Activate or deactive power management on either a specific device
850 * or the entire system (%APM_DEVICE_ALL).
853 static int apm_engage_power_management(u_short device, int enable)
855 u32 eax;
856 int err;
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;
870 return APM_SUCCESS;
873 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
876 * apm_console_blank - blank the display
877 * @blank: on/off
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.
885 static int apm_console_blank(int blank)
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 };
892 state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
894 for (i = 0; i < ARRAY_SIZE(dev); i++) {
895 error = set_power_state(dev[i], state);
897 if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
898 return 1;
900 if (error == APM_NOT_ENGAGED)
901 break;
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);
917 apm_error("set display", error);
918 return 0;
920 #endif
922 static int queue_empty(struct apm_user *as)
924 return as->event_head == as->event_tail;
927 static apm_event_t get_queued_event(struct apm_user *as)
929 if (++as->event_tail >= APM_MAX_EVENTS)
930 as->event_tail = 0;
931 return as->events[as->event_tail];
934 static void queue_event(apm_event_t event, struct apm_user *sender)
936 struct apm_user *as;
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;
947 if (as->event_head == as->event_tail) {
948 static int notified;
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;
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;
965 case APM_SYS_STANDBY:
966 case APM_USER_STANDBY:
967 as->standbys_pending++;
968 standbys_pending++;
969 break;
972 wake_up_interruptible(&apm_waitqueue);
973 out:
974 spin_unlock(&user_list_lock);
977 static void reinit_timer(void)
979 #ifdef INIT_TIMER_AFTER_SUSPEND
980 unsigned long flags;
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
994 static int suspend(int vetoable)
996 int err;
997 struct apm_user *as;
999 dpm_suspend_start(PMSG_SUSPEND);
1001 dpm_suspend_noirq(PMSG_SUSPEND);
1003 local_irq_disable();
1004 sysdev_suspend(PMSG_SUSPEND);
1006 local_irq_enable();
1008 save_processor_state();
1009 err = set_system_power_state(APM_STATE_SUSPEND);
1010 ignore_normal_resume = 1;
1011 restore_processor_state();
1013 local_irq_disable();
1014 reinit_timer();
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;
1022 sysdev_resume();
1023 local_irq_enable();
1025 dpm_resume_noirq(PMSG_RESUME);
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;
1034 spin_unlock(&user_list_lock);
1035 wake_up_interruptible(&apm_suspend_waitqueue);
1036 return err;
1039 static void standby(void)
1041 int err;
1043 dpm_suspend_noirq(PMSG_SUSPEND);
1045 local_irq_disable();
1046 sysdev_suspend(PMSG_SUSPEND);
1047 local_irq_enable();
1049 err = set_system_power_state(APM_STATE_STANDBY);
1050 if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
1051 apm_error("standby", err);
1053 local_irq_disable();
1054 sysdev_resume();
1055 local_irq_enable();
1057 dpm_resume_noirq(PMSG_RESUME);
1060 static apm_event_t get_event(void)
1062 int error;
1063 apm_event_t event = APM_NO_EVENTS; /* silence gcc */
1064 apm_eventinfo_t info;
1066 static int notified;
1068 /* we don't use the eventinfo */
1069 error = apm_get_event(&event, &info);
1070 if (error == APM_SUCCESS)
1071 return event;
1073 if ((error != APM_NO_EVENTS) && (notified++ == 0))
1074 apm_error("get_event", error);
1076 return 0;
1079 static void check_events(void)
1081 apm_event_t event;
1082 static unsigned long last_resume;
1083 static int ignore_bounce;
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);
1094 if (ignore_bounce
1095 && (time_after(jiffies, last_resume + bounce_interval)))
1096 ignore_bounce = 0;
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;
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;
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!
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;
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);
1145 ignore_normal_resume = 0;
1146 break;
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;
1155 case APM_UPDATE_TIME:
1156 break;
1158 case APM_CRITICAL_SUSPEND:
1160 * We are not allowed to reject a critical suspend.
1162 (void)suspend(0);
1163 break;
1168 static void apm_event_handler(void)
1170 static int pending_count = 4;
1171 int err;
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);
1183 } else
1184 pending_count = 4;
1185 check_events();
1189 * This is the APM thread main loop.
1192 static void apm_mainloop(void)
1194 DECLARE_WAITQUEUE(wait, current);
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;
1203 * Ok, check all events, check for idle (and mark us sleeping
1204 * so as not to count towards the load average)..
1206 set_current_state(TASK_INTERRUPTIBLE);
1207 apm_event_handler();
1209 remove_wait_queue(&apm_waitqueue, &wait);
1212 static int check_apm_user(struct apm_user *as, const char *func)
1214 if (as == NULL || as->magic != APM_BIOS_MAGIC) {
1215 printk(KERN_ERR "apm: %s passed bad filp\n", func);
1216 return 1;
1218 return 0;
1221 static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
1223 struct apm_user *as;
1224 int i;
1225 apm_event_t event;
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;
1243 switch (event) {
1244 case APM_SYS_SUSPEND:
1245 case APM_USER_SUSPEND:
1246 as->suspends_read++;
1247 break;
1249 case APM_SYS_STANDBY:
1250 case APM_USER_STANDBY:
1251 as->standbys_read++;
1252 break;
1254 buf += sizeof(event);
1255 i -= sizeof(event);
1257 if (i < count)
1258 return count - i;
1259 if (signal_pending(current))
1260 return -ERESTARTSYS;
1261 return 0;
1264 static unsigned int do_poll(struct file *fp, poll_table *wait)
1266 struct apm_user *as;
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;
1277 static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
1279 struct apm_user *as;
1280 int ret;
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;
1318 return ret;
1319 default:
1320 return -ENOTTY;
1322 return 0;
1325 static int do_release(struct inode *inode, struct file *filp)
1327 struct apm_user *as;
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();
1338 if (as->suspends_pending > 0) {
1339 suspends_pending -= as->suspends_pending;
1340 if (suspends_pending <= 0)
1341 (void) suspend(1);
1343 spin_lock(&user_list_lock);
1344 if (user_list == as)
1345 user_list = as->next;
1346 else {
1347 struct apm_user *as1;
1349 for (as1 = user_list;
1350 (as1 != NULL) && (as1->next != as);
1351 as1 = as1->next)
1353 if (as1 == NULL)
1354 printk(KERN_ERR "apm: filp not in user list\n");
1355 else
1356 as1->next = as->next;
1358 spin_unlock(&user_list_lock);
1359 kfree(as);
1360 return 0;
1363 static int do_open(struct inode *inode, struct file *filp)
1365 struct apm_user *as;
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;
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;
1388 static int proc_apm_show(struct seq_file *m, void *v)
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 = "?";
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;
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;
1416 /* Arguments, with symbols from linux/apm_bios.h. Information is
1417 from the Get Power Status (0x0a) call unless otherwise noted.
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 */
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;
1468 static int proc_apm_open(struct inode *inode, struct file *file)
1470 return single_open(file, proc_apm_show, NULL);
1473 static 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,
1481 static int apm(void *unused)
1483 unsigned short bx;
1484 unsigned short cx;
1485 unsigned short dx;
1486 int error;
1487 char *power_stat;
1488 char *bat_stat;
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.
1496 set_cpus_allowed_ptr(current, cpumask_of(0));
1497 BUG_ON(smp_processor_id() != 0);
1499 if (apm_info.connection_version == 0) {
1500 apm_info.connection_version = apm_info.bios.version;
1501 if (apm_info.connection_version > 0x100) {
1503 * We only support BIOSs up to version 1.2
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;
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);
1521 #ifdef CONFIG_APM_DO_ENABLE
1522 if (apm_info.bios.flags & APM_BIOS_DISABLED) {
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 ...
1528 error = apm_enable_power_management(1);
1529 if (error) {
1530 apm_error("enable power management", error);
1531 return -1;
1534 #endif
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;
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;
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;
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");
1602 /* Install our power off handler.. */
1603 if (power_off)
1604 pm_power_off = apm_power_off;
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
1616 return 0;
1619 #ifndef MODULE
1620 static int __init apm_setup(char *str)
1622 int invert;
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;
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");
1664 return 1;
1667 __setup("apm=", apm_setup);
1668 #endif
1670 static 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,
1679 static struct miscdevice apm_device = {
1680 APM_MINOR_DEV,
1681 "apm_bios",
1682 &apm_bios_fops
1686 /* Simple "print if true" callback */
1687 static int __init print_if_true(const struct dmi_system_id *d)
1689 printk("%s\n", d->ident);
1690 return 0;
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.
1697 static int __init broken_ps2_resume(const struct dmi_system_id *d)
1699 printk(KERN_INFO "%s machine detected. Mousepad Resume Bug "
1700 "workaround hopefully not needed.\n", d->ident);
1701 return 0;
1704 /* Some bioses have a broken protected mode poweroff and need to use realmode */
1705 static int __init set_realmode_power_off(const struct dmi_system_id *d)
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);
1712 return 0;
1715 /* Some laptops require interrupts to be enabled during APM calls */
1716 static int __init set_apm_ints(const struct dmi_system_id *d)
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);
1723 return 0;
1726 /* Some APM bioses corrupt memory or just plain do not work */
1727 static int __init apm_is_horked(const struct dmi_system_id *d)
1729 if (apm_info.disabled == 0) {
1730 apm_info.disabled = 1;
1731 printk(KERN_INFO "%s machine detected. "
1732 "Disabling APM.\n", d->ident);
1734 return 0;
1737 static int __init apm_is_horked_d850md(const struct dmi_system_id *d)
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");
1746 return 0;
1749 /* Some APM bioses hang on APM idle calls */
1750 static int __init apm_likes_to_melt(const struct dmi_system_id *d)
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);
1757 return 0;
1761 * Check for clue free BIOS implementations who use
1762 * the following QA technique
1764 * [ Write BIOS Code ]<------
1765 * | ^
1766 * < Does it Compile >----N--
1767 * |Y ^
1768 * < Does it Boot Win98 >-N--
1769 * |Y
1770 * [Ship It]
1772 * Phoenix A04 08/24/2000 is known bad (Dell Inspiron 5000e)
1773 * Phoenix A07 09/29/2000 is known good (Dell Inspiron 5000)
1775 static int __init broken_apm_power(const struct dmi_system_id *d)
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;
1784 * This bios swaps the APM minute reporting bytes over (Many sony laptops
1785 * have this problem).
1787 static int __init swab_apm_power_in_minutes(const struct dmi_system_id *d)
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;
1795 static struct dmi_system_id __initdata apm_dmi_table[] = {
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)"), },
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"), },
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"), }
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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])"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
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"), },
1996 /* Generic per vendor APM settings */
1998 { /* Allow interrupts during suspend on IBM laptops */
1999 set_apm_ints, "IBM",
2000 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
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...
2013 * In short, if something bad happens, at least we have a choice
2014 * of just killing the apm thread..
2016 static int __init apm_init(void)
2018 struct desc_struct *gdt;
2019 int err;
2021 dmi_check_system(apm_dmi_table);
2023 if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
2024 printk(KERN_INFO "apm: BIOS not found.\n");
2025 return -ENODEV;
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;
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;
2049 * Fix for the Compaq Contura 3/25c which reports BIOS version 0.1
2050 * but is reportedly a 1.0 BIOS.
2052 if (apm_info.bios.version == 0x001)
2053 apm_info.bios.version = 0x100;
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 */
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");
2072 if (apm_info.disabled) {
2073 printk(KERN_NOTICE "apm: disabled on user request.\n");
2074 return -ENODEV;
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;
2081 if (pm_flags & PM_ACPI) {
2082 printk(KERN_NOTICE "apm: overridden by ACPI.\n");
2083 apm_info.disabled = 1;
2084 return -ENODEV;
2086 pm_flags |= PM_APM;
2089 * Set up the long jump entry point to the APM BIOS, which is called
2090 * from inline assembly.
2092 apm_bios_entry.offset = apm_info.bios.offset;
2093 apm_bios_entry.segment = APM_CS;
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.
2102 * Note we only set APM segments on CPU zero, since we pin the APM
2103 * code to that CPU.
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));
2113 proc_create("apm", 0, NULL, &apm_file_ops);
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;
2124 wake_up_process(kapmd_task);
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;
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
2137 if (misc_register(&apm_device))
2138 printk(KERN_WARNING "apm: Could not register misc device.\n");
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;
2148 return 0;
2151 static void __exit apm_exit(void)
2153 int error;
2155 if (set_pm_idle) {
2156 pm_idle = original_pm_idle;
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.
2162 cpu_idle_wait();
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);
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;
2178 pm_flags &= ~PM_APM;
2181 module_init(apm_init);
2182 module_exit(apm_exit);
2184 MODULE_AUTHOR("Stephen Rothwell");
2185 MODULE_DESCRIPTION("Advanced Power Management");
2186 MODULE_LICENSE("GPL");
2187 module_param(debug, bool, 0644);
2188 MODULE_PARM_DESC(debug, "Enable debug mode");
2189 module_param(power_off, bool, 0444);
2190 MODULE_PARM_DESC(power_off, "Enable power off");
2191 module_param(bounce_interval, int, 0444);
2192 MODULE_PARM_DESC(bounce_interval,
2193 "Set the number of ticks to ignore suspend bounces");
2194 module_param(allow_ints, bool, 0444);
2195 MODULE_PARM_DESC(allow_ints, "Allow interrupts during BIOS calls");
2196 module_param(broken_psr, bool, 0444);
2197 MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call");
2198 module_param(realmode_power_off, bool, 0444);
2199 MODULE_PARM_DESC(realmode_power_off,
2200 "Switch to real mode before powering off");
2201 module_param(idle_threshold, int, 0444);
2202 MODULE_PARM_DESC(idle_threshold,
2203 "System idle percentage above which to make APM BIOS idle calls");
2204 module_param(idle_period, int, 0444);
2205 MODULE_PARM_DESC(idle_period,
2206 "Period (in sec/100) over which to caculate the idle percentage");
2207 module_param(smp, bool, 0444);
2208 MODULE_PARM_DESC(smp,
2209 "Set this to enable APM use on an SMP platform. Use with caution on older systems");
2210 MODULE_ALIAS_MISCDEV(APM_MINOR_DEV);