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