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