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