linux/drivers/acpi/battery.c
<<
>>
Prefs
   1/*
   2 *  battery.c - ACPI Battery Driver (Revision: 2.0)
   3 *
   4 *  Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
   5 *  Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
   6 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
   7 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
   8 *
   9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; either version 2 of the License, or (at
  14 *  your option) any later version.
  15 *
  16 *  This program is distributed in the hope that it will be useful, but
  17 *  WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19 *  General Public License for more details.
  20 *
  21 *  You should have received a copy of the GNU General Public License along
  22 *  with this program; if not, write to the Free Software Foundation, Inc.,
  23 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  24 *
  25 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  26 */
  27
  28#include <linux/kernel.h>
  29#include <linux/module.h>
  30#include <linux/init.h>
  31#include <linux/types.h>
  32#include <linux/jiffies.h>
  33#include <linux/async.h>
  34#include <linux/dmi.h>
  35#include <linux/slab.h>
  36#include <linux/suspend.h>
  37#include <asm/unaligned.h>
  38
  39#ifdef CONFIG_ACPI_PROCFS_POWER
  40#include <linux/proc_fs.h>
  41#include <linux/seq_file.h>
  42#include <asm/uaccess.h>
  43#endif
  44
  45#include <acpi/acpi_bus.h>
  46#include <acpi/acpi_drivers.h>
  47#include <linux/power_supply.h>
  48
  49#define PREFIX "ACPI: "
  50
  51#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
  52
  53#define ACPI_BATTERY_CLASS              "battery"
  54#define ACPI_BATTERY_DEVICE_NAME        "Battery"
  55#define ACPI_BATTERY_NOTIFY_STATUS      0x80
  56#define ACPI_BATTERY_NOTIFY_INFO        0x81
  57#define ACPI_BATTERY_NOTIFY_THRESHOLD   0x82
  58
  59/* Battery power unit: 0 means mW, 1 means mA */
  60#define ACPI_BATTERY_POWER_UNIT_MA      1
  61
  62#define _COMPONENT              ACPI_BATTERY_COMPONENT
  63
  64ACPI_MODULE_NAME("battery");
  65
  66MODULE_AUTHOR("Paul Diefenbaugh");
  67MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
  68MODULE_DESCRIPTION("ACPI Battery Driver");
  69MODULE_LICENSE("GPL");
  70
  71static unsigned int cache_time = 1000;
  72module_param(cache_time, uint, 0644);
  73MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
  74
  75#ifdef CONFIG_ACPI_PROCFS_POWER
  76extern struct proc_dir_entry *acpi_lock_battery_dir(void);
  77extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
  78
  79enum acpi_battery_files {
  80        info_tag = 0,
  81        state_tag,
  82        alarm_tag,
  83        ACPI_BATTERY_NUMFILES,
  84};
  85
  86#endif
  87
  88static const struct acpi_device_id battery_device_ids[] = {
  89        {"PNP0C0A", 0},
  90        {"", 0},
  91};
  92
  93MODULE_DEVICE_TABLE(acpi, battery_device_ids);
  94
  95enum {
  96        ACPI_BATTERY_ALARM_PRESENT,
  97        ACPI_BATTERY_XINFO_PRESENT,
  98        ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
  99        /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
 100           switches between mWh and mAh depending on whether the system
 101           is running on battery or not.  When mAh is the unit, most
 102           reported values are incorrect and need to be adjusted by
 103           10000/design_voltage.  Verified on x201, t410, t410s, and x220.
 104           Pre-2010 and 2012 models appear to always report in mWh and
 105           are thus unaffected (tested with t42, t61, t500, x200, x300,
 106           and x230).  Also, in mid-2012 Lenovo issued a BIOS update for
 107           the 2011 models that fixes the issue (tested on x220 with a
 108           post-1.29 BIOS), but as of Nov. 2012, no such update is
 109           available for the 2010 models.  */
 110        ACPI_BATTERY_QUIRK_THINKPAD_MAH,
 111};
 112
 113struct acpi_battery {
 114        struct mutex lock;
 115        struct mutex sysfs_lock;
 116        struct power_supply bat;
 117        struct acpi_device *device;
 118        struct notifier_block pm_nb;
 119        unsigned long update_time;
 120        int rate_now;
 121        int capacity_now;
 122        int voltage_now;
 123        int design_capacity;
 124        int full_charge_capacity;
 125        int technology;
 126        int design_voltage;
 127        int design_capacity_warning;
 128        int design_capacity_low;
 129        int cycle_count;
 130        int measurement_accuracy;
 131        int max_sampling_time;
 132        int min_sampling_time;
 133        int max_averaging_interval;
 134        int min_averaging_interval;
 135        int capacity_granularity_1;
 136        int capacity_granularity_2;
 137        int alarm;
 138        char model_number[32];
 139        char serial_number[32];
 140        char type[32];
 141        char oem_info[32];
 142        int state;
 143        int power_unit;
 144        unsigned long flags;
 145};
 146
 147#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
 148
 149inline int acpi_battery_present(struct acpi_battery *battery)
 150{
 151        return battery->device->status.battery_present;
 152}
 153
 154static int acpi_battery_technology(struct acpi_battery *battery)
 155{
 156        if (!strcasecmp("NiCd", battery->type))
 157                return POWER_SUPPLY_TECHNOLOGY_NiCd;
 158        if (!strcasecmp("NiMH", battery->type))
 159                return POWER_SUPPLY_TECHNOLOGY_NiMH;
 160        if (!strcasecmp("LION", battery->type))
 161                return POWER_SUPPLY_TECHNOLOGY_LION;
 162        if (!strncasecmp("LI-ION", battery->type, 6))
 163                return POWER_SUPPLY_TECHNOLOGY_LION;
 164        if (!strcasecmp("LiP", battery->type))
 165                return POWER_SUPPLY_TECHNOLOGY_LIPO;
 166        return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 167}
 168
 169static int acpi_battery_get_state(struct acpi_battery *battery);
 170
 171static int acpi_battery_is_charged(struct acpi_battery *battery)
 172{
 173        /* either charging or discharging */
 174        if (battery->state != 0)
 175                return 0;
 176
 177        /* battery not reporting charge */
 178        if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
 179            battery->capacity_now == 0)
 180                return 0;
 181
 182        /* good batteries update full_charge as the batteries degrade */
 183        if (battery->full_charge_capacity == battery->capacity_now)
 184                return 1;
 185
 186        /* fallback to using design values for broken batteries */
 187        if (battery->design_capacity == battery->capacity_now)
 188                return 1;
 189
 190        /* we don't do any sort of metric based on percentages */
 191        return 0;
 192}
 193
 194static int acpi_battery_get_property(struct power_supply *psy,
 195                                     enum power_supply_property psp,
 196                                     union power_supply_propval *val)
 197{
 198        int ret = 0;
 199        struct acpi_battery *battery = to_acpi_battery(psy);
 200
 201        if (acpi_battery_present(battery)) {
 202                /* run battery update only if it is present */
 203                acpi_battery_get_state(battery);
 204        } else if (psp != POWER_SUPPLY_PROP_PRESENT)
 205                return -ENODEV;
 206        switch (psp) {
 207        case POWER_SUPPLY_PROP_STATUS:
 208                if (battery->state & 0x01)
 209                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 210                else if (battery->state & 0x02)
 211                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
 212                else if (acpi_battery_is_charged(battery))
 213                        val->intval = POWER_SUPPLY_STATUS_FULL;
 214                else
 215                        val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
 216                break;
 217        case POWER_SUPPLY_PROP_PRESENT:
 218                val->intval = acpi_battery_present(battery);
 219                break;
 220        case POWER_SUPPLY_PROP_TECHNOLOGY:
 221                val->intval = acpi_battery_technology(battery);
 222                break;
 223        case POWER_SUPPLY_PROP_CYCLE_COUNT:
 224                val->intval = battery->cycle_count;
 225                break;
 226        case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 227                if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
 228                        ret = -ENODEV;
 229                else
 230                        val->intval = battery->design_voltage * 1000;
 231                break;
 232        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 233                if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
 234                        ret = -ENODEV;
 235                else
 236                        val->intval = battery->voltage_now * 1000;
 237                break;
 238        case POWER_SUPPLY_PROP_CURRENT_NOW:
 239        case POWER_SUPPLY_PROP_POWER_NOW:
 240                if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
 241                        ret = -ENODEV;
 242                else
 243                        val->intval = battery->rate_now * 1000;
 244                break;
 245        case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 246        case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
 247                if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 248                        ret = -ENODEV;
 249                else
 250                        val->intval = battery->design_capacity * 1000;
 251                break;
 252        case POWER_SUPPLY_PROP_CHARGE_FULL:
 253        case POWER_SUPPLY_PROP_ENERGY_FULL:
 254                if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 255                        ret = -ENODEV;
 256                else
 257                        val->intval = battery->full_charge_capacity * 1000;
 258                break;
 259        case POWER_SUPPLY_PROP_CHARGE_NOW:
 260        case POWER_SUPPLY_PROP_ENERGY_NOW:
 261                if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
 262                        ret = -ENODEV;
 263                else
 264                        val->intval = battery->capacity_now * 1000;
 265                break;
 266        case POWER_SUPPLY_PROP_CAPACITY:
 267                if (battery->capacity_now && battery->full_charge_capacity)
 268                        val->intval = battery->capacity_now * 100/
 269                                        battery->full_charge_capacity;
 270                else
 271                        val->intval = 0;
 272                break;
 273        case POWER_SUPPLY_PROP_MODEL_NAME:
 274                val->strval = battery->model_number;
 275                break;
 276        case POWER_SUPPLY_PROP_MANUFACTURER:
 277                val->strval = battery->oem_info;
 278                break;
 279        case POWER_SUPPLY_PROP_SERIAL_NUMBER:
 280                val->strval = battery->serial_number;
 281                break;
 282        default:
 283                ret = -EINVAL;
 284        }
 285        return ret;
 286}
 287
 288static enum power_supply_property charge_battery_props[] = {
 289        POWER_SUPPLY_PROP_STATUS,
 290        POWER_SUPPLY_PROP_PRESENT,
 291        POWER_SUPPLY_PROP_TECHNOLOGY,
 292        POWER_SUPPLY_PROP_CYCLE_COUNT,
 293        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 294        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 295        POWER_SUPPLY_PROP_CURRENT_NOW,
 296        POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 297        POWER_SUPPLY_PROP_CHARGE_FULL,
 298        POWER_SUPPLY_PROP_CHARGE_NOW,
 299        POWER_SUPPLY_PROP_CAPACITY,
 300        POWER_SUPPLY_PROP_MODEL_NAME,
 301        POWER_SUPPLY_PROP_MANUFACTURER,
 302        POWER_SUPPLY_PROP_SERIAL_NUMBER,
 303};
 304
 305static enum power_supply_property energy_battery_props[] = {
 306        POWER_SUPPLY_PROP_STATUS,
 307        POWER_SUPPLY_PROP_PRESENT,
 308        POWER_SUPPLY_PROP_TECHNOLOGY,
 309        POWER_SUPPLY_PROP_CYCLE_COUNT,
 310        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 311        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 312        POWER_SUPPLY_PROP_POWER_NOW,
 313        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 314        POWER_SUPPLY_PROP_ENERGY_FULL,
 315        POWER_SUPPLY_PROP_ENERGY_NOW,
 316        POWER_SUPPLY_PROP_CAPACITY,
 317        POWER_SUPPLY_PROP_MODEL_NAME,
 318        POWER_SUPPLY_PROP_MANUFACTURER,
 319        POWER_SUPPLY_PROP_SERIAL_NUMBER,
 320};
 321
 322#ifdef CONFIG_ACPI_PROCFS_POWER
 323inline char *acpi_battery_units(struct acpi_battery *battery)
 324{
 325        return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
 326                "mA" : "mW";
 327}
 328#endif
 329
 330/* --------------------------------------------------------------------------
 331                               Battery Management
 332   -------------------------------------------------------------------------- */
 333struct acpi_offsets {
 334        size_t offset;          /* offset inside struct acpi_sbs_battery */
 335        u8 mode;                /* int or string? */
 336};
 337
 338static struct acpi_offsets state_offsets[] = {
 339        {offsetof(struct acpi_battery, state), 0},
 340        {offsetof(struct acpi_battery, rate_now), 0},
 341        {offsetof(struct acpi_battery, capacity_now), 0},
 342        {offsetof(struct acpi_battery, voltage_now), 0},
 343};
 344
 345static struct acpi_offsets info_offsets[] = {
 346        {offsetof(struct acpi_battery, power_unit), 0},
 347        {offsetof(struct acpi_battery, design_capacity), 0},
 348        {offsetof(struct acpi_battery, full_charge_capacity), 0},
 349        {offsetof(struct acpi_battery, technology), 0},
 350        {offsetof(struct acpi_battery, design_voltage), 0},
 351        {offsetof(struct acpi_battery, design_capacity_warning), 0},
 352        {offsetof(struct acpi_battery, design_capacity_low), 0},
 353        {offsetof(struct acpi_battery, capacity_granularity_1), 0},
 354        {offsetof(struct acpi_battery, capacity_granularity_2), 0},
 355        {offsetof(struct acpi_battery, model_number), 1},
 356        {offsetof(struct acpi_battery, serial_number), 1},
 357        {offsetof(struct acpi_battery, type), 1},
 358        {offsetof(struct acpi_battery, oem_info), 1},
 359};
 360
 361static struct acpi_offsets extended_info_offsets[] = {
 362        {offsetof(struct acpi_battery, power_unit), 0},
 363        {offsetof(struct acpi_battery, design_capacity), 0},
 364        {offsetof(struct acpi_battery, full_charge_capacity), 0},
 365        {offsetof(struct acpi_battery, technology), 0},
 366        {offsetof(struct acpi_battery, design_voltage), 0},
 367        {offsetof(struct acpi_battery, design_capacity_warning), 0},
 368        {offsetof(struct acpi_battery, design_capacity_low), 0},
 369        {offsetof(struct acpi_battery, cycle_count), 0},
 370        {offsetof(struct acpi_battery, measurement_accuracy), 0},
 371        {offsetof(struct acpi_battery, max_sampling_time), 0},
 372        {offsetof(struct acpi_battery, min_sampling_time), 0},
 373        {offsetof(struct acpi_battery, max_averaging_interval), 0},
 374        {offsetof(struct acpi_battery, min_averaging_interval), 0},
 375        {offsetof(struct acpi_battery, capacity_granularity_1), 0},
 376        {offsetof(struct acpi_battery, capacity_granularity_2), 0},
 377        {offsetof(struct acpi_battery, model_number), 1},
 378        {offsetof(struct acpi_battery, serial_number), 1},
 379        {offsetof(struct acpi_battery, type), 1},
 380        {offsetof(struct acpi_battery, oem_info), 1},
 381};
 382
 383static int extract_package(struct acpi_battery *battery,
 384                           union acpi_object *package,
 385                           struct acpi_offsets *offsets, int num)
 386{
 387        int i;
 388        union acpi_object *element;
 389        if (package->type != ACPI_TYPE_PACKAGE)
 390                return -EFAULT;
 391        for (i = 0; i < num; ++i) {
 392                if (package->package.count <= i)
 393                        return -EFAULT;
 394                element = &package->package.elements[i];
 395                if (offsets[i].mode) {
 396                        u8 *ptr = (u8 *)battery + offsets[i].offset;
 397                        if (element->type == ACPI_TYPE_STRING ||
 398                            element->type == ACPI_TYPE_BUFFER)
 399                                strncpy(ptr, element->string.pointer, 32);
 400                        else if (element->type == ACPI_TYPE_INTEGER) {
 401                                strncpy(ptr, (u8 *)&element->integer.value,
 402                                        sizeof(u64));
 403                                ptr[sizeof(u64)] = 0;
 404                        } else
 405                                *ptr = 0; /* don't have value */
 406                } else {
 407                        int *x = (int *)((u8 *)battery + offsets[i].offset);
 408                        *x = (element->type == ACPI_TYPE_INTEGER) ?
 409                                element->integer.value : -1;
 410                }
 411        }
 412        return 0;
 413}
 414
 415static int acpi_battery_get_status(struct acpi_battery *battery)
 416{
 417        if (acpi_bus_get_status(battery->device)) {
 418                ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
 419                return -ENODEV;
 420        }
 421        return 0;
 422}
 423
 424static int acpi_battery_get_info(struct acpi_battery *battery)
 425{
 426        int result = -EFAULT;
 427        acpi_status status = 0;
 428        char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
 429                        "_BIX" : "_BIF";
 430
 431        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 432
 433        if (!acpi_battery_present(battery))
 434                return 0;
 435        mutex_lock(&battery->lock);
 436        status = acpi_evaluate_object(battery->device->handle, name,
 437                                                NULL, &buffer);
 438        mutex_unlock(&battery->lock);
 439
 440        if (ACPI_FAILURE(status)) {
 441                ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
 442                return -ENODEV;
 443        }
 444        if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
 445                result = extract_package(battery, buffer.pointer,
 446                                extended_info_offsets,
 447                                ARRAY_SIZE(extended_info_offsets));
 448        else
 449                result = extract_package(battery, buffer.pointer,
 450                                info_offsets, ARRAY_SIZE(info_offsets));
 451        kfree(buffer.pointer);
 452        if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
 453                battery->full_charge_capacity = battery->design_capacity;
 454        if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
 455            battery->power_unit && battery->design_voltage) {
 456                battery->design_capacity = battery->design_capacity *
 457                    10000 / battery->design_voltage;
 458                battery->full_charge_capacity = battery->full_charge_capacity *
 459                    10000 / battery->design_voltage;
 460                battery->design_capacity_warning =
 461                    battery->design_capacity_warning *
 462                    10000 / battery->design_voltage;
 463                /* Curiously, design_capacity_low, unlike the rest of them,
 464                   is correct.  */
 465                /* capacity_granularity_* equal 1 on the systems tested, so
 466                   it's impossible to tell if they would need an adjustment
 467                   or not if their values were higher.  */
 468        }
 469        return result;
 470}
 471
 472static int acpi_battery_get_state(struct acpi_battery *battery)
 473{
 474        int result = 0;
 475        acpi_status status = 0;
 476        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 477
 478        if (!acpi_battery_present(battery))
 479                return 0;
 480
 481        if (battery->update_time &&
 482            time_before(jiffies, battery->update_time +
 483                        msecs_to_jiffies(cache_time)))
 484                return 0;
 485
 486        mutex_lock(&battery->lock);
 487        status = acpi_evaluate_object(battery->device->handle, "_BST",
 488                                      NULL, &buffer);
 489        mutex_unlock(&battery->lock);
 490
 491        if (ACPI_FAILURE(status)) {
 492                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
 493                return -ENODEV;
 494        }
 495
 496        result = extract_package(battery, buffer.pointer,
 497                                 state_offsets, ARRAY_SIZE(state_offsets));
 498        battery->update_time = jiffies;
 499        kfree(buffer.pointer);
 500
 501        /* For buggy DSDTs that report negative 16-bit values for either
 502         * charging or discharging current and/or report 0 as 65536
 503         * due to bad math.
 504         */
 505        if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
 506                battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
 507                (s16)(battery->rate_now) < 0) {
 508                battery->rate_now = abs((s16)battery->rate_now);
 509                printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate"
 510                        " invalid.\n");
 511        }
 512
 513        if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
 514            && battery->capacity_now >= 0 && battery->capacity_now <= 100)
 515                battery->capacity_now = (battery->capacity_now *
 516                                battery->full_charge_capacity) / 100;
 517        if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
 518            battery->power_unit && battery->design_voltage) {
 519                battery->capacity_now = battery->capacity_now *
 520                    10000 / battery->design_voltage;
 521        }
 522        return result;
 523}
 524
 525static int acpi_battery_set_alarm(struct acpi_battery *battery)
 526{
 527        acpi_status status = 0;
 528        union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
 529        struct acpi_object_list arg_list = { 1, &arg0 };
 530
 531        if (!acpi_battery_present(battery) ||
 532            !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
 533                return -ENODEV;
 534
 535        arg0.integer.value = battery->alarm;
 536
 537        mutex_lock(&battery->lock);
 538        status = acpi_evaluate_object(battery->device->handle, "_BTP",
 539                                 &arg_list, NULL);
 540        mutex_unlock(&battery->lock);
 541
 542        if (ACPI_FAILURE(status))
 543                return -ENODEV;
 544
 545        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
 546        return 0;
 547}
 548
 549static int acpi_battery_init_alarm(struct acpi_battery *battery)
 550{
 551        acpi_status status = AE_OK;
 552        acpi_handle handle = NULL;
 553
 554        /* See if alarms are supported, and if so, set default */
 555        status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
 556        if (ACPI_FAILURE(status)) {
 557                clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
 558                return 0;
 559        }
 560        set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
 561        if (!battery->alarm)
 562                battery->alarm = battery->design_capacity_warning;
 563        return acpi_battery_set_alarm(battery);
 564}
 565
 566static ssize_t acpi_battery_alarm_show(struct device *dev,
 567                                        struct device_attribute *attr,
 568                                        char *buf)
 569{
 570        struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
 571        return sprintf(buf, "%d\n", battery->alarm * 1000);
 572}
 573
 574static ssize_t acpi_battery_alarm_store(struct device *dev,
 575                                        struct device_attribute *attr,
 576                                        const char *buf, size_t count)
 577{
 578        unsigned long x;
 579        struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
 580        if (sscanf(buf, "%ld\n", &x) == 1)
 581                battery->alarm = x/1000;
 582        if (acpi_battery_present(battery))
 583                acpi_battery_set_alarm(battery);
 584        return count;
 585}
 586
 587static struct device_attribute alarm_attr = {
 588        .attr = {.name = "alarm", .mode = 0644},
 589        .show = acpi_battery_alarm_show,
 590        .store = acpi_battery_alarm_store,
 591};
 592
 593static int sysfs_add_battery(struct acpi_battery *battery)
 594{
 595        int result;
 596
 597        if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
 598                battery->bat.properties = charge_battery_props;
 599                battery->bat.num_properties =
 600                        ARRAY_SIZE(charge_battery_props);
 601        } else {
 602                battery->bat.properties = energy_battery_props;
 603                battery->bat.num_properties =
 604                        ARRAY_SIZE(energy_battery_props);
 605        }
 606
 607        battery->bat.name = acpi_device_bid(battery->device);
 608        battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
 609        battery->bat.get_property = acpi_battery_get_property;
 610
 611        result = power_supply_register(&battery->device->dev, &battery->bat);
 612        if (result)
 613                return result;
 614        return device_create_file(battery->bat.dev, &alarm_attr);
 615}
 616
 617static void sysfs_remove_battery(struct acpi_battery *battery)
 618{
 619        mutex_lock(&battery->sysfs_lock);
 620        if (!battery->bat.dev) {
 621                mutex_unlock(&battery->sysfs_lock);
 622                return;
 623        }
 624
 625        device_remove_file(battery->bat.dev, &alarm_attr);
 626        power_supply_unregister(&battery->bat);
 627        battery->bat.dev = NULL;
 628        mutex_unlock(&battery->sysfs_lock);
 629}
 630
 631static void find_battery(const struct dmi_header *dm, void *private)
 632{
 633        struct acpi_battery *battery = (struct acpi_battery *)private;
 634        /* Note: the hardcoded offsets below have been extracted from
 635           the source code of dmidecode.  */
 636        if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
 637                const u8 *dmi_data = (const u8 *)(dm + 1);
 638                int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
 639                if (dm->length >= 18)
 640                        dmi_capacity *= dmi_data[17];
 641                if (battery->design_capacity * battery->design_voltage / 1000
 642                    != dmi_capacity &&
 643                    battery->design_capacity * 10 == dmi_capacity)
 644                        set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
 645                                &battery->flags);
 646        }
 647}
 648
 649/*
 650 * According to the ACPI spec, some kinds of primary batteries can
 651 * report percentage battery remaining capacity directly to OS.
 652 * In this case, it reports the Last Full Charged Capacity == 100
 653 * and BatteryPresentRate == 0xFFFFFFFF.
 654 *
 655 * Now we found some battery reports percentage remaining capacity
 656 * even if it's rechargeable.
 657 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
 658 *
 659 * Handle this correctly so that they won't break userspace.
 660 */
 661static void acpi_battery_quirks(struct acpi_battery *battery)
 662{
 663        if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
 664                return ;
 665
 666        if (battery->full_charge_capacity == 100 &&
 667            battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
 668            battery->capacity_now >=0 && battery->capacity_now <= 100) {
 669                set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
 670                battery->full_charge_capacity = battery->design_capacity;
 671                battery->capacity_now = (battery->capacity_now *
 672                                battery->full_charge_capacity) / 100;
 673        }
 674
 675        if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
 676                return ;
 677
 678        if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
 679                const char *s;
 680                s = dmi_get_system_info(DMI_PRODUCT_VERSION);
 681                if (s && !strnicmp(s, "ThinkPad", 8)) {
 682                        dmi_walk(find_battery, battery);
 683                        if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
 684                                     &battery->flags) &&
 685                            battery->design_voltage) {
 686                                battery->design_capacity =
 687                                    battery->design_capacity *
 688                                    10000 / battery->design_voltage;
 689                                battery->full_charge_capacity =
 690                                    battery->full_charge_capacity *
 691                                    10000 / battery->design_voltage;
 692                                battery->design_capacity_warning =
 693                                    battery->design_capacity_warning *
 694                                    10000 / battery->design_voltage;
 695                                battery->capacity_now = battery->capacity_now *
 696                                    10000 / battery->design_voltage;
 697                        }
 698                }
 699        }
 700}
 701
 702static int acpi_battery_update(struct acpi_battery *battery)
 703{
 704        int result, old_present = acpi_battery_present(battery);
 705        result = acpi_battery_get_status(battery);
 706        if (result)
 707                return result;
 708        if (!acpi_battery_present(battery)) {
 709                sysfs_remove_battery(battery);
 710                battery->update_time = 0;
 711                return 0;
 712        }
 713        if (!battery->update_time ||
 714            old_present != acpi_battery_present(battery)) {
 715                result = acpi_battery_get_info(battery);
 716                if (result)
 717                        return result;
 718                acpi_battery_init_alarm(battery);
 719        }
 720        if (!battery->bat.dev) {
 721                result = sysfs_add_battery(battery);
 722                if (result)
 723                        return result;
 724        }
 725        result = acpi_battery_get_state(battery);
 726        acpi_battery_quirks(battery);
 727        return result;
 728}
 729
 730static void acpi_battery_refresh(struct acpi_battery *battery)
 731{
 732        int power_unit;
 733
 734        if (!battery->bat.dev)
 735                return;
 736
 737        power_unit = battery->power_unit;
 738
 739        acpi_battery_get_info(battery);
 740
 741        if (power_unit == battery->power_unit)
 742                return;
 743
 744        /* The battery has changed its reporting units. */
 745        sysfs_remove_battery(battery);
 746        sysfs_add_battery(battery);
 747}
 748
 749/* --------------------------------------------------------------------------
 750                              FS Interface (/proc)
 751   -------------------------------------------------------------------------- */
 752
 753#ifdef CONFIG_ACPI_PROCFS_POWER
 754static struct proc_dir_entry *acpi_battery_dir;
 755
 756static int acpi_battery_print_info(struct seq_file *seq, int result)
 757{
 758        struct acpi_battery *battery = seq->private;
 759
 760        if (result)
 761                goto end;
 762
 763        seq_printf(seq, "present:                 %s\n",
 764                   acpi_battery_present(battery)?"yes":"no");
 765        if (!acpi_battery_present(battery))
 766                goto end;
 767        if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 768                seq_printf(seq, "design capacity:         unknown\n");
 769        else
 770                seq_printf(seq, "design capacity:         %d %sh\n",
 771                           battery->design_capacity,
 772                           acpi_battery_units(battery));
 773
 774        if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 775                seq_printf(seq, "last full capacity:      unknown\n");
 776        else
 777                seq_printf(seq, "last full capacity:      %d %sh\n",
 778                           battery->full_charge_capacity,
 779                           acpi_battery_units(battery));
 780
 781        seq_printf(seq, "battery technology:      %srechargeable\n",
 782                   (!battery->technology)?"non-":"");
 783
 784        if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
 785                seq_printf(seq, "design voltage:          unknown\n");
 786        else
 787                seq_printf(seq, "design voltage:          %d mV\n",
 788                           battery->design_voltage);
 789        seq_printf(seq, "design capacity warning: %d %sh\n",
 790                   battery->design_capacity_warning,
 791                   acpi_battery_units(battery));
 792        seq_printf(seq, "design capacity low:     %d %sh\n",
 793                   battery->design_capacity_low,
 794                   acpi_battery_units(battery));
 795        seq_printf(seq, "cycle count:             %i\n", battery->cycle_count);
 796        seq_printf(seq, "capacity granularity 1:  %d %sh\n",
 797                   battery->capacity_granularity_1,
 798                   acpi_battery_units(battery));
 799        seq_printf(seq, "capacity granularity 2:  %d %sh\n",
 800                   battery->capacity_granularity_2,
 801                   acpi_battery_units(battery));
 802        seq_printf(seq, "model number:            %s\n", battery->model_number);
 803        seq_printf(seq, "serial number:           %s\n", battery->serial_number);
 804        seq_printf(seq, "battery type:            %s\n", battery->type);
 805        seq_printf(seq, "OEM info:                %s\n", battery->oem_info);
 806      end:
 807        if (result)
 808                seq_printf(seq, "ERROR: Unable to read battery info\n");
 809        return result;
 810}
 811
 812static int acpi_battery_print_state(struct seq_file *seq, int result)
 813{
 814        struct acpi_battery *battery = seq->private;
 815
 816        if (result)
 817                goto end;
 818
 819        seq_printf(seq, "present:                 %s\n",
 820                   acpi_battery_present(battery)?"yes":"no");
 821        if (!acpi_battery_present(battery))
 822                goto end;
 823
 824        seq_printf(seq, "capacity state:          %s\n",
 825                        (battery->state & 0x04)?"critical":"ok");
 826        if ((battery->state & 0x01) && (battery->state & 0x02))
 827                seq_printf(seq,
 828                           "charging state:          charging/discharging\n");
 829        else if (battery->state & 0x01)
 830                seq_printf(seq, "charging state:          discharging\n");
 831        else if (battery->state & 0x02)
 832                seq_printf(seq, "charging state:          charging\n");
 833        else
 834                seq_printf(seq, "charging state:          charged\n");
 835
 836        if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
 837                seq_printf(seq, "present rate:            unknown\n");
 838        else
 839                seq_printf(seq, "present rate:            %d %s\n",
 840                           battery->rate_now, acpi_battery_units(battery));
 841
 842        if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
 843                seq_printf(seq, "remaining capacity:      unknown\n");
 844        else
 845                seq_printf(seq, "remaining capacity:      %d %sh\n",
 846                           battery->capacity_now, acpi_battery_units(battery));
 847        if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
 848                seq_printf(seq, "present voltage:         unknown\n");
 849        else
 850                seq_printf(seq, "present voltage:         %d mV\n",
 851                           battery->voltage_now);
 852      end:
 853        if (result)
 854                seq_printf(seq, "ERROR: Unable to read battery state\n");
 855
 856        return result;
 857}
 858
 859static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 860{
 861        struct acpi_battery *battery = seq->private;
 862
 863        if (result)
 864                goto end;
 865
 866        if (!acpi_battery_present(battery)) {
 867                seq_printf(seq, "present:                 no\n");
 868                goto end;
 869        }
 870        seq_printf(seq, "alarm:                   ");
 871        if (!battery->alarm)
 872                seq_printf(seq, "unsupported\n");
 873        else
 874                seq_printf(seq, "%u %sh\n", battery->alarm,
 875                                acpi_battery_units(battery));
 876      end:
 877        if (result)
 878                seq_printf(seq, "ERROR: Unable to read battery alarm\n");
 879        return result;
 880}
 881
 882static ssize_t acpi_battery_write_alarm(struct file *file,
 883                                        const char __user * buffer,
 884                                        size_t count, loff_t * ppos)
 885{
 886        int result = 0;
 887        char alarm_string[12] = { '\0' };
 888        struct seq_file *m = file->private_data;
 889        struct acpi_battery *battery = m->private;
 890
 891        if (!battery || (count > sizeof(alarm_string) - 1))
 892                return -EINVAL;
 893        if (!acpi_battery_present(battery)) {
 894                result = -ENODEV;
 895                goto end;
 896        }
 897        if (copy_from_user(alarm_string, buffer, count)) {
 898                result = -EFAULT;
 899                goto end;
 900        }
 901        alarm_string[count] = '\0';
 902        battery->alarm = simple_strtol(alarm_string, NULL, 0);
 903        result = acpi_battery_set_alarm(battery);
 904      end:
 905        if (!result)
 906                return count;
 907        return result;
 908}
 909
 910typedef int(*print_func)(struct seq_file *seq, int result);
 911
 912static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
 913        acpi_battery_print_info,
 914        acpi_battery_print_state,
 915        acpi_battery_print_alarm,
 916};
 917
 918static int acpi_battery_read(int fid, struct seq_file *seq)
 919{
 920        struct acpi_battery *battery = seq->private;
 921        int result = acpi_battery_update(battery);
 922        return acpi_print_funcs[fid](seq, result);
 923}
 924
 925#define DECLARE_FILE_FUNCTIONS(_name) \
 926static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
 927{ \
 928        return acpi_battery_read(_name##_tag, seq); \
 929} \
 930static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
 931{ \
 932        return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
 933}
 934
 935DECLARE_FILE_FUNCTIONS(info);
 936DECLARE_FILE_FUNCTIONS(state);
 937DECLARE_FILE_FUNCTIONS(alarm);
 938
 939#undef DECLARE_FILE_FUNCTIONS
 940
 941#define FILE_DESCRIPTION_RO(_name) \
 942        { \
 943        .name = __stringify(_name), \
 944        .mode = S_IRUGO, \
 945        .ops = { \
 946                .open = acpi_battery_##_name##_open_fs, \
 947                .read = seq_read, \
 948                .llseek = seq_lseek, \
 949                .release = single_release, \
 950                .owner = THIS_MODULE, \
 951                }, \
 952        }
 953
 954#define FILE_DESCRIPTION_RW(_name) \
 955        { \
 956        .name = __stringify(_name), \
 957        .mode = S_IFREG | S_IRUGO | S_IWUSR, \
 958        .ops = { \
 959                .open = acpi_battery_##_name##_open_fs, \
 960                .read = seq_read, \
 961                .llseek = seq_lseek, \
 962                .write = acpi_battery_write_##_name, \
 963                .release = single_release, \
 964                .owner = THIS_MODULE, \
 965                }, \
 966        }
 967
 968static const struct battery_file {
 969        struct file_operations ops;
 970        umode_t mode;
 971        const char *name;
 972} acpi_battery_file[] = {
 973        FILE_DESCRIPTION_RO(info),
 974        FILE_DESCRIPTION_RO(state),
 975        FILE_DESCRIPTION_RW(alarm),
 976};
 977
 978#undef FILE_DESCRIPTION_RO
 979#undef FILE_DESCRIPTION_RW
 980
 981static int acpi_battery_add_fs(struct acpi_device *device)
 982{
 983        struct proc_dir_entry *entry = NULL;
 984        int i;
 985
 986        printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
 987                        " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
 988        if (!acpi_device_dir(device)) {
 989                acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
 990                                                     acpi_battery_dir);
 991                if (!acpi_device_dir(device))
 992                        return -ENODEV;
 993        }
 994
 995        for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
 996                entry = proc_create_data(acpi_battery_file[i].name,
 997                                         acpi_battery_file[i].mode,
 998                                         acpi_device_dir(device),
 999                                         &acpi_battery_file[i].ops,
1000                                         acpi_driver_data(device));
1001                if (!entry)
1002                        return -ENODEV;
1003        }
1004        return 0;
1005}
1006
1007static void acpi_battery_remove_fs(struct acpi_device *device)
1008{
1009        int i;
1010        if (!acpi_device_dir(device))
1011                return;
1012        for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
1013                remove_proc_entry(acpi_battery_file[i].name,
1014                                  acpi_device_dir(device));
1015
1016        remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
1017        acpi_device_dir(device) = NULL;
1018}
1019
1020#endif
1021
1022/* --------------------------------------------------------------------------
1023                                 Driver Interface
1024   -------------------------------------------------------------------------- */
1025
1026static void acpi_battery_notify(struct acpi_device *device, u32 event)
1027{
1028        struct acpi_battery *battery = acpi_driver_data(device);
1029        struct device *old;
1030
1031        if (!battery)
1032                return;
1033        old = battery->bat.dev;
1034        if (event == ACPI_BATTERY_NOTIFY_INFO)
1035                acpi_battery_refresh(battery);
1036        acpi_battery_update(battery);
1037        acpi_bus_generate_proc_event(device, event,
1038                                     acpi_battery_present(battery));
1039        acpi_bus_generate_netlink_event(device->pnp.device_class,
1040                                        dev_name(&device->dev), event,
1041                                        acpi_battery_present(battery));
1042        /* acpi_battery_update could remove power_supply object */
1043        if (old && battery->bat.dev)
1044                power_supply_changed(&battery->bat);
1045}
1046
1047static int battery_notify(struct notifier_block *nb,
1048                               unsigned long mode, void *_unused)
1049{
1050        struct acpi_battery *battery = container_of(nb, struct acpi_battery,
1051                                                    pm_nb);
1052        switch (mode) {
1053        case PM_POST_HIBERNATION:
1054        case PM_POST_SUSPEND:
1055                if (battery->bat.dev) {
1056                        sysfs_remove_battery(battery);
1057                        sysfs_add_battery(battery);
1058                }
1059                break;
1060        }
1061
1062        return 0;
1063}
1064
1065static int acpi_battery_add(struct acpi_device *device)
1066{
1067        int result = 0;
1068        struct acpi_battery *battery = NULL;
1069        acpi_handle handle;
1070        if (!device)
1071                return -EINVAL;
1072        battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
1073        if (!battery)
1074                return -ENOMEM;
1075        battery->device = device;
1076        strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
1077        strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
1078        device->driver_data = battery;
1079        mutex_init(&battery->lock);
1080        mutex_init(&battery->sysfs_lock);
1081        if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
1082                        "_BIX", &handle)))
1083                set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
1084        result = acpi_battery_update(battery);
1085        if (result)
1086                goto fail;
1087#ifdef CONFIG_ACPI_PROCFS_POWER
1088        result = acpi_battery_add_fs(device);
1089#endif
1090        if (result) {
1091#ifdef CONFIG_ACPI_PROCFS_POWER
1092                acpi_battery_remove_fs(device);
1093#endif
1094                goto fail;
1095        }
1096
1097        printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
1098                ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1099                device->status.battery_present ? "present" : "absent");
1100
1101        battery->pm_nb.notifier_call = battery_notify;
1102        register_pm_notifier(&battery->pm_nb);
1103
1104        return result;
1105
1106fail:
1107        sysfs_remove_battery(battery);
1108        mutex_destroy(&battery->lock);
1109        mutex_destroy(&battery->sysfs_lock);
1110        kfree(battery);
1111        return result;
1112}
1113
1114static int acpi_battery_remove(struct acpi_device *device, int type)
1115{
1116        struct acpi_battery *battery = NULL;
1117
1118        if (!device || !acpi_driver_data(device))
1119                return -EINVAL;
1120        battery = acpi_driver_data(device);
1121        unregister_pm_notifier(&battery->pm_nb);
1122#ifdef CONFIG_ACPI_PROCFS_POWER
1123        acpi_battery_remove_fs(device);
1124#endif
1125        sysfs_remove_battery(battery);
1126        mutex_destroy(&battery->lock);
1127        mutex_destroy(&battery->sysfs_lock);
1128        kfree(battery);
1129        return 0;
1130}
1131
1132#ifdef CONFIG_PM_SLEEP
1133/* this is needed to learn about changes made in suspended state */
1134static int acpi_battery_resume(struct device *dev)
1135{
1136        struct acpi_battery *battery;
1137
1138        if (!dev)
1139                return -EINVAL;
1140
1141        battery = acpi_driver_data(to_acpi_device(dev));
1142        if (!battery)
1143                return -EINVAL;
1144
1145        battery->update_time = 0;
1146        acpi_battery_update(battery);
1147        return 0;
1148}
1149#endif
1150
1151static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
1152
1153static struct acpi_driver acpi_battery_driver = {
1154        .name = "battery",
1155        .class = ACPI_BATTERY_CLASS,
1156        .ids = battery_device_ids,
1157        .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1158        .ops = {
1159                .add = acpi_battery_add,
1160                .remove = acpi_battery_remove,
1161                .notify = acpi_battery_notify,
1162                },
1163        .drv.pm = &acpi_battery_pm,
1164};
1165
1166static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
1167{
1168        if (acpi_disabled)
1169                return;
1170#ifdef CONFIG_ACPI_PROCFS_POWER
1171        acpi_battery_dir = acpi_lock_battery_dir();
1172        if (!acpi_battery_dir)
1173                return;
1174#endif
1175        if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
1176#ifdef CONFIG_ACPI_PROCFS_POWER
1177                acpi_unlock_battery_dir(acpi_battery_dir);
1178#endif
1179                return;
1180        }
1181        return;
1182}
1183
1184static int __init acpi_battery_init(void)
1185{
1186        async_schedule(acpi_battery_init_async, NULL);
1187        return 0;
1188}
1189
1190static void __exit acpi_battery_exit(void)
1191{
1192        acpi_bus_unregister_driver(&acpi_battery_driver);
1193#ifdef CONFIG_ACPI_PROCFS_POWER
1194        acpi_unlock_battery_dir(acpi_battery_dir);
1195#endif
1196}
1197
1198module_init(acpi_battery_init);
1199module_exit(acpi_battery_exit);
1200
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.