linux/drivers/acpi/sbs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $)
   4 *
   5 *  Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
   6 *  Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
   7 *  Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
   8 */
   9
  10#include <linux/init.h>
  11#include <linux/slab.h>
  12#include <linux/module.h>
  13#include <linux/moduleparam.h>
  14#include <linux/kernel.h>
  15
  16#include <linux/acpi.h>
  17#include <linux/timer.h>
  18#include <linux/jiffies.h>
  19#include <linux/delay.h>
  20#include <linux/power_supply.h>
  21#include <linux/platform_data/x86/apple.h>
  22#include <acpi/battery.h>
  23
  24#include "sbshc.h"
  25
  26#define PREFIX "ACPI: "
  27
  28#define ACPI_SBS_CLASS                  "sbs"
  29#define ACPI_AC_CLASS                   "ac_adapter"
  30#define ACPI_SBS_DEVICE_NAME            "Smart Battery System"
  31#define ACPI_BATTERY_DIR_NAME           "BAT%i"
  32#define ACPI_AC_DIR_NAME                "AC0"
  33
  34#define ACPI_SBS_NOTIFY_STATUS          0x80
  35#define ACPI_SBS_NOTIFY_INFO            0x81
  36
  37MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
  38MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
  39MODULE_LICENSE("GPL");
  40
  41static unsigned int cache_time = 1000;
  42module_param(cache_time, uint, 0644);
  43MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
  44
  45#define MAX_SBS_BAT                     4
  46#define ACPI_SBS_BLOCK_MAX              32
  47
  48static const struct acpi_device_id sbs_device_ids[] = {
  49        {"ACPI0002", 0},
  50        {"", 0},
  51};
  52MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
  53
  54struct acpi_battery {
  55        struct power_supply *bat;
  56        struct power_supply_desc bat_desc;
  57        struct acpi_sbs *sbs;
  58        unsigned long update_time;
  59        char name[8];
  60        char manufacturer_name[ACPI_SBS_BLOCK_MAX];
  61        char device_name[ACPI_SBS_BLOCK_MAX];
  62        char device_chemistry[ACPI_SBS_BLOCK_MAX];
  63        u16 alarm_capacity;
  64        u16 full_charge_capacity;
  65        u16 design_capacity;
  66        u16 design_voltage;
  67        u16 serial_number;
  68        u16 cycle_count;
  69        u16 temp_now;
  70        u16 voltage_now;
  71        s16 rate_now;
  72        s16 rate_avg;
  73        u16 capacity_now;
  74        u16 state_of_charge;
  75        u16 state;
  76        u16 mode;
  77        u16 spec;
  78        u8 id;
  79        u8 present:1;
  80        u8 have_sysfs_alarm:1;
  81};
  82
  83#define to_acpi_battery(x) power_supply_get_drvdata(x)
  84
  85struct acpi_sbs {
  86        struct power_supply *charger;
  87        struct acpi_device *device;
  88        struct acpi_smb_hc *hc;
  89        struct mutex lock;
  90        struct acpi_battery battery[MAX_SBS_BAT];
  91        u8 batteries_supported:4;
  92        u8 manager_present:1;
  93        u8 charger_present:1;
  94        u8 charger_exists:1;
  95};
  96
  97#define to_acpi_sbs(x) power_supply_get_drvdata(x)
  98
  99static int acpi_sbs_remove(struct acpi_device *device);
 100static int acpi_battery_get_state(struct acpi_battery *battery);
 101
 102static inline int battery_scale(int log)
 103{
 104        int scale = 1;
 105        while (log--)
 106                scale *= 10;
 107        return scale;
 108}
 109
 110static inline int acpi_battery_vscale(struct acpi_battery *battery)
 111{
 112        return battery_scale((battery->spec & 0x0f00) >> 8);
 113}
 114
 115static inline int acpi_battery_ipscale(struct acpi_battery *battery)
 116{
 117        return battery_scale((battery->spec & 0xf000) >> 12);
 118}
 119
 120static inline int acpi_battery_mode(struct acpi_battery *battery)
 121{
 122        return (battery->mode & 0x8000);
 123}
 124
 125static inline int acpi_battery_scale(struct acpi_battery *battery)
 126{
 127        return (acpi_battery_mode(battery) ? 10 : 1) *
 128            acpi_battery_ipscale(battery);
 129}
 130
 131static int sbs_get_ac_property(struct power_supply *psy,
 132                               enum power_supply_property psp,
 133                               union power_supply_propval *val)
 134{
 135        struct acpi_sbs *sbs = to_acpi_sbs(psy);
 136        switch (psp) {
 137        case POWER_SUPPLY_PROP_ONLINE:
 138                val->intval = sbs->charger_present;
 139                break;
 140        default:
 141                return -EINVAL;
 142        }
 143        return 0;
 144}
 145
 146static int acpi_battery_technology(struct acpi_battery *battery)
 147{
 148        if (!strcasecmp("NiCd", battery->device_chemistry))
 149                return POWER_SUPPLY_TECHNOLOGY_NiCd;
 150        if (!strcasecmp("NiMH", battery->device_chemistry))
 151                return POWER_SUPPLY_TECHNOLOGY_NiMH;
 152        if (!strcasecmp("LION", battery->device_chemistry))
 153                return POWER_SUPPLY_TECHNOLOGY_LION;
 154        if (!strcasecmp("LiP", battery->device_chemistry))
 155                return POWER_SUPPLY_TECHNOLOGY_LIPO;
 156        return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 157}
 158
 159static int acpi_sbs_battery_get_property(struct power_supply *psy,
 160                                         enum power_supply_property psp,
 161                                         union power_supply_propval *val)
 162{
 163        struct acpi_battery *battery = to_acpi_battery(psy);
 164
 165        if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
 166                return -ENODEV;
 167
 168        acpi_battery_get_state(battery);
 169        switch (psp) {
 170        case POWER_SUPPLY_PROP_STATUS:
 171                if (battery->rate_now < 0)
 172                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 173                else if (battery->rate_now > 0)
 174                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
 175                else
 176                        val->intval = POWER_SUPPLY_STATUS_FULL;
 177                break;
 178        case POWER_SUPPLY_PROP_PRESENT:
 179                val->intval = battery->present;
 180                break;
 181        case POWER_SUPPLY_PROP_TECHNOLOGY:
 182                val->intval = acpi_battery_technology(battery);
 183                break;
 184        case POWER_SUPPLY_PROP_CYCLE_COUNT:
 185                val->intval = battery->cycle_count;
 186                break;
 187        case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 188                val->intval = battery->design_voltage *
 189                        acpi_battery_vscale(battery) * 1000;
 190                break;
 191        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 192                val->intval = battery->voltage_now *
 193                                acpi_battery_vscale(battery) * 1000;
 194                break;
 195        case POWER_SUPPLY_PROP_CURRENT_NOW:
 196        case POWER_SUPPLY_PROP_POWER_NOW:
 197                val->intval = abs(battery->rate_now) *
 198                                acpi_battery_ipscale(battery) * 1000;
 199                val->intval *= (acpi_battery_mode(battery)) ?
 200                                (battery->voltage_now *
 201                                acpi_battery_vscale(battery) / 1000) : 1;
 202                break;
 203        case POWER_SUPPLY_PROP_CURRENT_AVG:
 204        case POWER_SUPPLY_PROP_POWER_AVG:
 205                val->intval = abs(battery->rate_avg) *
 206                                acpi_battery_ipscale(battery) * 1000;
 207                val->intval *= (acpi_battery_mode(battery)) ?
 208                                (battery->voltage_now *
 209                                acpi_battery_vscale(battery) / 1000) : 1;
 210                break;
 211        case POWER_SUPPLY_PROP_CAPACITY:
 212                val->intval = battery->state_of_charge;
 213                break;
 214        case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 215        case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
 216                val->intval = battery->design_capacity *
 217                        acpi_battery_scale(battery) * 1000;
 218                break;
 219        case POWER_SUPPLY_PROP_CHARGE_FULL:
 220        case POWER_SUPPLY_PROP_ENERGY_FULL:
 221                val->intval = battery->full_charge_capacity *
 222                        acpi_battery_scale(battery) * 1000;
 223                break;
 224        case POWER_SUPPLY_PROP_CHARGE_NOW:
 225        case POWER_SUPPLY_PROP_ENERGY_NOW:
 226                val->intval = battery->capacity_now *
 227                                acpi_battery_scale(battery) * 1000;
 228                break;
 229        case POWER_SUPPLY_PROP_TEMP:
 230                val->intval = battery->temp_now - 2730; // dK -> dC
 231                break;
 232        case POWER_SUPPLY_PROP_MODEL_NAME:
 233                val->strval = battery->device_name;
 234                break;
 235        case POWER_SUPPLY_PROP_MANUFACTURER:
 236                val->strval = battery->manufacturer_name;
 237                break;
 238        default:
 239                return -EINVAL;
 240        }
 241        return 0;
 242}
 243
 244static enum power_supply_property sbs_ac_props[] = {
 245        POWER_SUPPLY_PROP_ONLINE,
 246};
 247
 248static enum power_supply_property sbs_charge_battery_props[] = {
 249        POWER_SUPPLY_PROP_STATUS,
 250        POWER_SUPPLY_PROP_PRESENT,
 251        POWER_SUPPLY_PROP_TECHNOLOGY,
 252        POWER_SUPPLY_PROP_CYCLE_COUNT,
 253        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 254        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 255        POWER_SUPPLY_PROP_CURRENT_NOW,
 256        POWER_SUPPLY_PROP_CURRENT_AVG,
 257        POWER_SUPPLY_PROP_CAPACITY,
 258        POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 259        POWER_SUPPLY_PROP_CHARGE_FULL,
 260        POWER_SUPPLY_PROP_CHARGE_NOW,
 261        POWER_SUPPLY_PROP_TEMP,
 262        POWER_SUPPLY_PROP_MODEL_NAME,
 263        POWER_SUPPLY_PROP_MANUFACTURER,
 264};
 265
 266static enum power_supply_property sbs_energy_battery_props[] = {
 267        POWER_SUPPLY_PROP_STATUS,
 268        POWER_SUPPLY_PROP_PRESENT,
 269        POWER_SUPPLY_PROP_TECHNOLOGY,
 270        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 271        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 272        POWER_SUPPLY_PROP_CURRENT_NOW,
 273        POWER_SUPPLY_PROP_CURRENT_AVG,
 274        POWER_SUPPLY_PROP_POWER_NOW,
 275        POWER_SUPPLY_PROP_POWER_AVG,
 276        POWER_SUPPLY_PROP_CAPACITY,
 277        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 278        POWER_SUPPLY_PROP_ENERGY_FULL,
 279        POWER_SUPPLY_PROP_ENERGY_NOW,
 280        POWER_SUPPLY_PROP_TEMP,
 281        POWER_SUPPLY_PROP_MODEL_NAME,
 282        POWER_SUPPLY_PROP_MANUFACTURER,
 283};
 284
 285static const struct power_supply_desc acpi_sbs_charger_desc = {
 286        .name           = "sbs-charger",
 287        .type           = POWER_SUPPLY_TYPE_MAINS,
 288        .properties     = sbs_ac_props,
 289        .num_properties = ARRAY_SIZE(sbs_ac_props),
 290        .get_property   = sbs_get_ac_property,
 291};
 292
 293/* --------------------------------------------------------------------------
 294                            Smart Battery System Management
 295   -------------------------------------------------------------------------- */
 296
 297struct acpi_battery_reader {
 298        u8 command;             /* command for battery */
 299        u8 mode;                /* word or block? */
 300        size_t offset;          /* offset inside struct acpi_sbs_battery */
 301};
 302
 303static struct acpi_battery_reader info_readers[] = {
 304        {0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)},
 305        {0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)},
 306        {0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)},
 307        {0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)},
 308        {0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)},
 309        {0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)},
 310        {0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)},
 311        {0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)},
 312        {0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)},
 313        {0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)},
 314        {0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)},
 315};
 316
 317static struct acpi_battery_reader state_readers[] = {
 318        {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
 319        {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
 320        {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
 321        {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
 322        {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
 323        {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
 324        {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
 325};
 326
 327static int acpi_manager_get_info(struct acpi_sbs *sbs)
 328{
 329        int result = 0;
 330        u16 battery_system_info;
 331
 332        result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
 333                                 0x04, (u8 *)&battery_system_info);
 334        if (!result)
 335                sbs->batteries_supported = battery_system_info & 0x000f;
 336        return result;
 337}
 338
 339static int acpi_battery_get_info(struct acpi_battery *battery)
 340{
 341        int i, result = 0;
 342
 343        for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
 344                result = acpi_smbus_read(battery->sbs->hc,
 345                                         info_readers[i].mode,
 346                                         ACPI_SBS_BATTERY,
 347                                         info_readers[i].command,
 348                                         (u8 *) battery +
 349                                                info_readers[i].offset);
 350                if (result)
 351                        break;
 352        }
 353        return result;
 354}
 355
 356static int acpi_battery_get_state(struct acpi_battery *battery)
 357{
 358        int i, result = 0;
 359
 360        if (battery->update_time &&
 361            time_before(jiffies, battery->update_time +
 362                                msecs_to_jiffies(cache_time)))
 363                return 0;
 364        for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
 365                result = acpi_smbus_read(battery->sbs->hc,
 366                                         state_readers[i].mode,
 367                                         ACPI_SBS_BATTERY,
 368                                         state_readers[i].command,
 369                                         (u8 *)battery +
 370                                                state_readers[i].offset);
 371                if (result)
 372                        goto end;
 373        }
 374      end:
 375        battery->update_time = jiffies;
 376        return result;
 377}
 378
 379static int acpi_battery_get_alarm(struct acpi_battery *battery)
 380{
 381        return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
 382                                 ACPI_SBS_BATTERY, 0x01,
 383                                 (u8 *)&battery->alarm_capacity);
 384}
 385
 386static int acpi_battery_set_alarm(struct acpi_battery *battery)
 387{
 388        struct acpi_sbs *sbs = battery->sbs;
 389        u16 value, sel = 1 << (battery->id + 12);
 390
 391        int ret;
 392
 393
 394        if (sbs->manager_present) {
 395                ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
 396                                0x01, (u8 *)&value);
 397                if (ret)
 398                        goto end;
 399                if ((value & 0xf000) != sel) {
 400                        value &= 0x0fff;
 401                        value |= sel;
 402                        ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD,
 403                                         ACPI_SBS_MANAGER,
 404                                         0x01, (u8 *)&value, 2);
 405                        if (ret)
 406                                goto end;
 407                }
 408        }
 409        ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
 410                                0x01, (u8 *)&battery->alarm_capacity, 2);
 411      end:
 412        return ret;
 413}
 414
 415static int acpi_ac_get_present(struct acpi_sbs *sbs)
 416{
 417        int result;
 418        u16 status;
 419
 420        result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
 421                                 0x13, (u8 *) & status);
 422
 423        if (result)
 424                return result;
 425
 426        /*
 427         * The spec requires that bit 4 always be 1. If it's not set, assume
 428         * that the implementation doesn't support an SBS charger.
 429         *
 430         * And on some MacBooks a status of 0xffff is always returned, no
 431         * matter whether the charger is plugged in or not, which is also
 432         * wrong, so ignore the SBS charger for those too.
 433         */
 434        if (!((status >> 4) & 0x1) || status == 0xffff)
 435                return -ENODEV;
 436
 437        sbs->charger_present = (status >> 15) & 0x1;
 438        return 0;
 439}
 440
 441static ssize_t acpi_battery_alarm_show(struct device *dev,
 442                                        struct device_attribute *attr,
 443                                        char *buf)
 444{
 445        struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
 446        acpi_battery_get_alarm(battery);
 447        return sprintf(buf, "%d\n", battery->alarm_capacity *
 448                                acpi_battery_scale(battery) * 1000);
 449}
 450
 451static ssize_t acpi_battery_alarm_store(struct device *dev,
 452                                        struct device_attribute *attr,
 453                                        const char *buf, size_t count)
 454{
 455        unsigned long x;
 456        struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
 457        if (sscanf(buf, "%lu\n", &x) == 1)
 458                battery->alarm_capacity = x /
 459                        (1000 * acpi_battery_scale(battery));
 460        if (battery->present)
 461                acpi_battery_set_alarm(battery);
 462        return count;
 463}
 464
 465static const struct device_attribute alarm_attr = {
 466        .attr = {.name = "alarm", .mode = 0644},
 467        .show = acpi_battery_alarm_show,
 468        .store = acpi_battery_alarm_store,
 469};
 470
 471/* --------------------------------------------------------------------------
 472                                 Driver Interface
 473   -------------------------------------------------------------------------- */
 474static int acpi_battery_read(struct acpi_battery *battery)
 475{
 476        int result = 0, saved_present = battery->present;
 477        u16 state;
 478
 479        if (battery->sbs->manager_present) {
 480                result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
 481                                ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
 482                if (!result)
 483                        battery->present = state & (1 << battery->id);
 484                state &= 0x0fff;
 485                state |= 1 << (battery->id + 12);
 486                acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
 487                                  ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
 488        } else if (battery->id == 0)
 489                battery->present = 1;
 490
 491        if (result || !battery->present)
 492                return result;
 493
 494        if (saved_present != battery->present) {
 495                battery->update_time = 0;
 496                result = acpi_battery_get_info(battery);
 497                if (result) {
 498                        battery->present = 0;
 499                        return result;
 500                }
 501        }
 502        result = acpi_battery_get_state(battery);
 503        if (result)
 504                battery->present = 0;
 505        return result;
 506}
 507
 508/* Smart Battery */
 509static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 510{
 511        struct acpi_battery *battery = &sbs->battery[id];
 512        struct power_supply_config psy_cfg = { .drv_data = battery, };
 513        int result;
 514
 515        battery->id = id;
 516        battery->sbs = sbs;
 517        result = acpi_battery_read(battery);
 518        if (result)
 519                return result;
 520
 521        sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
 522        battery->bat_desc.name = battery->name;
 523        battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
 524        if (!acpi_battery_mode(battery)) {
 525                battery->bat_desc.properties = sbs_charge_battery_props;
 526                battery->bat_desc.num_properties =
 527                    ARRAY_SIZE(sbs_charge_battery_props);
 528        } else {
 529                battery->bat_desc.properties = sbs_energy_battery_props;
 530                battery->bat_desc.num_properties =
 531                    ARRAY_SIZE(sbs_energy_battery_props);
 532        }
 533        battery->bat_desc.get_property = acpi_sbs_battery_get_property;
 534        battery->bat = power_supply_register(&sbs->device->dev,
 535                                        &battery->bat_desc, &psy_cfg);
 536        if (IS_ERR(battery->bat)) {
 537                result = PTR_ERR(battery->bat);
 538                battery->bat = NULL;
 539                goto end;
 540        }
 541
 542        result = device_create_file(&battery->bat->dev, &alarm_attr);
 543        if (result)
 544                goto end;
 545        battery->have_sysfs_alarm = 1;
 546      end:
 547        printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
 548               ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
 549               battery->name, battery->present ? "present" : "absent");
 550        return result;
 551}
 552
 553static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 554{
 555        struct acpi_battery *battery = &sbs->battery[id];
 556
 557        if (battery->bat) {
 558                if (battery->have_sysfs_alarm)
 559                        device_remove_file(&battery->bat->dev, &alarm_attr);
 560                power_supply_unregister(battery->bat);
 561        }
 562}
 563
 564static int acpi_charger_add(struct acpi_sbs *sbs)
 565{
 566        int result;
 567        struct power_supply_config psy_cfg = { .drv_data = sbs, };
 568
 569        result = acpi_ac_get_present(sbs);
 570        if (result)
 571                goto end;
 572
 573        sbs->charger_exists = 1;
 574        sbs->charger = power_supply_register(&sbs->device->dev,
 575                                        &acpi_sbs_charger_desc, &psy_cfg);
 576        if (IS_ERR(sbs->charger)) {
 577                result = PTR_ERR(sbs->charger);
 578                sbs->charger = NULL;
 579        }
 580        printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
 581               ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
 582               ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
 583      end:
 584        return result;
 585}
 586
 587static void acpi_charger_remove(struct acpi_sbs *sbs)
 588{
 589        if (sbs->charger)
 590                power_supply_unregister(sbs->charger);
 591}
 592
 593static void acpi_sbs_callback(void *context)
 594{
 595        int id;
 596        struct acpi_sbs *sbs = context;
 597        struct acpi_battery *bat;
 598        u8 saved_charger_state = sbs->charger_present;
 599        u8 saved_battery_state;
 600
 601        if (sbs->charger_exists) {
 602                acpi_ac_get_present(sbs);
 603                if (sbs->charger_present != saved_charger_state)
 604                        kobject_uevent(&sbs->charger->dev.kobj, KOBJ_CHANGE);
 605        }
 606
 607        if (sbs->manager_present) {
 608                for (id = 0; id < MAX_SBS_BAT; ++id) {
 609                        if (!(sbs->batteries_supported & (1 << id)))
 610                                continue;
 611                        bat = &sbs->battery[id];
 612                        saved_battery_state = bat->present;
 613                        acpi_battery_read(bat);
 614                        if (saved_battery_state == bat->present)
 615                                continue;
 616                        kobject_uevent(&bat->bat->dev.kobj, KOBJ_CHANGE);
 617                }
 618        }
 619}
 620
 621static int acpi_sbs_add(struct acpi_device *device)
 622{
 623        struct acpi_sbs *sbs;
 624        int result = 0;
 625        int id;
 626
 627        sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 628        if (!sbs) {
 629                result = -ENOMEM;
 630                goto end;
 631        }
 632
 633        mutex_init(&sbs->lock);
 634
 635        sbs->hc = acpi_driver_data(device->parent);
 636        sbs->device = device;
 637        strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
 638        strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
 639        device->driver_data = sbs;
 640
 641        result = acpi_charger_add(sbs);
 642        if (result && result != -ENODEV)
 643                goto end;
 644
 645        result = 0;
 646
 647        if (!x86_apple_machine) {
 648                result = acpi_manager_get_info(sbs);
 649                if (!result) {
 650                        sbs->manager_present = 1;
 651                        for (id = 0; id < MAX_SBS_BAT; ++id)
 652                                if ((sbs->batteries_supported & (1 << id)))
 653                                        acpi_battery_add(sbs, id);
 654                }
 655        }
 656
 657        if (!sbs->manager_present)
 658                acpi_battery_add(sbs, 0);
 659
 660        acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
 661      end:
 662        if (result)
 663                acpi_sbs_remove(device);
 664        return result;
 665}
 666
 667static int acpi_sbs_remove(struct acpi_device *device)
 668{
 669        struct acpi_sbs *sbs;
 670        int id;
 671
 672        if (!device)
 673                return -EINVAL;
 674        sbs = acpi_driver_data(device);
 675        if (!sbs)
 676                return -EINVAL;
 677        mutex_lock(&sbs->lock);
 678        acpi_smbus_unregister_callback(sbs->hc);
 679        for (id = 0; id < MAX_SBS_BAT; ++id)
 680                acpi_battery_remove(sbs, id);
 681        acpi_charger_remove(sbs);
 682        mutex_unlock(&sbs->lock);
 683        mutex_destroy(&sbs->lock);
 684        kfree(sbs);
 685        return 0;
 686}
 687
 688#ifdef CONFIG_PM_SLEEP
 689static int acpi_sbs_resume(struct device *dev)
 690{
 691        struct acpi_sbs *sbs;
 692        if (!dev)
 693                return -EINVAL;
 694        sbs = to_acpi_device(dev)->driver_data;
 695        acpi_sbs_callback(sbs);
 696        return 0;
 697}
 698#else
 699#define acpi_sbs_resume NULL
 700#endif
 701
 702static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume);
 703
 704static struct acpi_driver acpi_sbs_driver = {
 705        .name = "sbs",
 706        .class = ACPI_SBS_CLASS,
 707        .ids = sbs_device_ids,
 708        .ops = {
 709                .add = acpi_sbs_add,
 710                .remove = acpi_sbs_remove,
 711                },
 712        .drv.pm = &acpi_sbs_pm,
 713};
 714
 715static int __init acpi_sbs_init(void)
 716{
 717        int result = 0;
 718
 719        if (acpi_disabled)
 720                return -ENODEV;
 721
 722        result = acpi_bus_register_driver(&acpi_sbs_driver);
 723        if (result < 0)
 724                return -ENODEV;
 725
 726        return 0;
 727}
 728
 729static void __exit acpi_sbs_exit(void)
 730{
 731        acpi_bus_unregister_driver(&acpi_sbs_driver);
 732        return;
 733}
 734
 735module_init(acpi_sbs_init);
 736module_exit(acpi_sbs_exit);
 737