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