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 35 #ifdef CONFIG_ACPI_PROCFS_POWER 36 #include <linux/proc_fs.h> 37 #include <linux/seq_file.h> 38 #include <asm/uaccess.h> 39 #endif 40 41 #include <acpi/acpi_bus.h> 42 #include <acpi/acpi_drivers.h> 43 44 #ifdef CONFIG_ACPI_SYSFS_POWER 45 #include <linux/power_supply.h> 46 #endif 47 48 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF 49 50 #define ACPI_BATTERY_CLASS "battery" 51 #define ACPI_BATTERY_DEVICE_NAME "Battery" 52 #define ACPI_BATTERY_NOTIFY_STATUS 0x80 53 #define ACPI_BATTERY_NOTIFY_INFO 0x81 54 55 #define _COMPONENT ACPI_BATTERY_COMPONENT 56 57 ACPI_MODULE_NAME("battery"); 58 59 MODULE_AUTHOR("Paul Diefenbaugh"); 60 MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>"); 61 MODULE_DESCRIPTION("ACPI Battery Driver"); 62 MODULE_LICENSE("GPL"); 63 64 static unsigned int cache_time = 1000; 65 module_param(cache_time, uint, 0644); 66 MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); 67 68 #ifdef CONFIG_ACPI_PROCFS_POWER 69 extern struct proc_dir_entry *acpi_lock_battery_dir(void); 70 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 71 72 enum acpi_battery_files { 73 info_tag = 0, 74 state_tag, 75 alarm_tag, 76 ACPI_BATTERY_NUMFILES, 77 }; 78 79 #endif 80 81 static const struct acpi_device_id battery_device_ids[] = { 82 {"PNP0C0A", 0}, 83 {"", 0}, 84 }; 85 86 MODULE_DEVICE_TABLE(acpi, battery_device_ids); 87 88 89 struct acpi_battery { 90 struct mutex lock; 91 #ifdef CONFIG_ACPI_SYSFS_POWER 92 struct power_supply bat; 93 #endif 94 struct acpi_device *device; 95 unsigned long update_time; 96 int rate_now; 97 int capacity_now; 98 int voltage_now; 99 int design_capacity; 100 int full_charge_capacity; 101 int technology; 102 int design_voltage; 103 int design_capacity_warning; 104 int design_capacity_low; 105 int capacity_granularity_1; 106 int capacity_granularity_2; 107 int alarm; 108 char model_number[32]; 109 char serial_number[32]; 110 char type[32]; 111 char oem_info[32]; 112 int state; 113 int power_unit; 114 u8 alarm_present; 115 }; 116 117 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 118 119 inline int acpi_battery_present(struct acpi_battery *battery) 120 { 121 return battery->device->status.battery_present; 122 } 123 124 #ifdef CONFIG_ACPI_SYSFS_POWER 125 static int acpi_battery_technology(struct acpi_battery *battery) 126 { 127 if (!strcasecmp("NiCd", battery->type)) 128 return POWER_SUPPLY_TECHNOLOGY_NiCd; 129 if (!strcasecmp("NiMH", battery->type)) 130 return POWER_SUPPLY_TECHNOLOGY_NiMH; 131 if (!strcasecmp("LION", battery->type)) 132 return POWER_SUPPLY_TECHNOLOGY_LION; 133 if (!strncasecmp("LI-ION", battery->type, 6)) 134 return POWER_SUPPLY_TECHNOLOGY_LION; 135 if (!strcasecmp("LiP", battery->type)) 136 return POWER_SUPPLY_TECHNOLOGY_LIPO; 137 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 138 } 139 140 static int acpi_battery_get_state(struct acpi_battery *battery); 141 142 static int acpi_battery_is_charged(struct acpi_battery *battery) 143 { 144 /* either charging or discharging */ 145 if (battery->state != 0) 146 return 0; 147 148 /* battery not reporting charge */ 149 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || 150 battery->capacity_now == 0) 151 return 0; 152 153 /* good batteries update full_charge as the batteries degrade */ 154 if (battery->full_charge_capacity == battery->capacity_now) 155 return 1; 156 157 /* fallback to using design values for broken batteries */ 158 if (battery->design_capacity == battery->capacity_now) 159 return 1; 160 161 /* we don't do any sort of metric based on percentages */ 162 return 0; 163 } 164 165 static int acpi_battery_get_property(struct power_supply *psy, 166 enum power_supply_property psp, 167 union power_supply_propval *val) 168 { 169 struct acpi_battery *battery = to_acpi_battery(psy); 170 171 if (acpi_battery_present(battery)) { 172 /* run battery update only if it is present */ 173 acpi_battery_get_state(battery); 174 } else if (psp != POWER_SUPPLY_PROP_PRESENT) 175 return -ENODEV; 176 switch (psp) { 177 case POWER_SUPPLY_PROP_STATUS: 178 if (battery->state & 0x01) 179 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 180 else if (battery->state & 0x02) 181 val->intval = POWER_SUPPLY_STATUS_CHARGING; 182 else if (acpi_battery_is_charged(battery)) 183 val->intval = POWER_SUPPLY_STATUS_FULL; 184 else 185 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 186 break; 187 case POWER_SUPPLY_PROP_PRESENT: 188 val->intval = acpi_battery_present(battery); 189 break; 190 case POWER_SUPPLY_PROP_TECHNOLOGY: 191 val->intval = acpi_battery_technology(battery); 192 break; 193 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 194 val->intval = battery->design_voltage * 1000; 195 break; 196 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 197 val->intval = battery->voltage_now * 1000; 198 break; 199 case POWER_SUPPLY_PROP_CURRENT_NOW: 200 case POWER_SUPPLY_PROP_POWER_NOW: 201 val->intval = battery->rate_now * 1000; 202 break; 203 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 204 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 205 val->intval = battery->design_capacity * 1000; 206 break; 207 case POWER_SUPPLY_PROP_CHARGE_FULL: 208 case POWER_SUPPLY_PROP_ENERGY_FULL: 209 val->intval = battery->full_charge_capacity * 1000; 210 break; 211 case POWER_SUPPLY_PROP_CHARGE_NOW: 212 case POWER_SUPPLY_PROP_ENERGY_NOW: 213 val->intval = battery->capacity_now * 1000; 214 break; 215 case POWER_SUPPLY_PROP_MODEL_NAME: 216 val->strval = battery->model_number; 217 break; 218 case POWER_SUPPLY_PROP_MANUFACTURER: 219 val->strval = battery->oem_info; 220 break; 221 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 222 val->strval = battery->serial_number; 223 break; 224 default: 225 return -EINVAL; 226 } 227 return 0; 228 } 229 230 static enum power_supply_property charge_battery_props[] = { 231 POWER_SUPPLY_PROP_STATUS, 232 POWER_SUPPLY_PROP_PRESENT, 233 POWER_SUPPLY_PROP_TECHNOLOGY, 234 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 235 POWER_SUPPLY_PROP_VOLTAGE_NOW, 236 POWER_SUPPLY_PROP_CURRENT_NOW, 237 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 238 POWER_SUPPLY_PROP_CHARGE_FULL, 239 POWER_SUPPLY_PROP_CHARGE_NOW, 240 POWER_SUPPLY_PROP_MODEL_NAME, 241 POWER_SUPPLY_PROP_MANUFACTURER, 242 POWER_SUPPLY_PROP_SERIAL_NUMBER, 243 }; 244 245 static enum power_supply_property energy_battery_props[] = { 246 POWER_SUPPLY_PROP_STATUS, 247 POWER_SUPPLY_PROP_PRESENT, 248 POWER_SUPPLY_PROP_TECHNOLOGY, 249 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 250 POWER_SUPPLY_PROP_VOLTAGE_NOW, 251 POWER_SUPPLY_PROP_CURRENT_NOW, 252 POWER_SUPPLY_PROP_POWER_NOW, 253 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 254 POWER_SUPPLY_PROP_ENERGY_FULL, 255 POWER_SUPPLY_PROP_ENERGY_NOW, 256 POWER_SUPPLY_PROP_MODEL_NAME, 257 POWER_SUPPLY_PROP_MANUFACTURER, 258 POWER_SUPPLY_PROP_SERIAL_NUMBER, 259 }; 260 #endif 261 262 #ifdef CONFIG_ACPI_PROCFS_POWER 263 inline char *acpi_battery_units(struct acpi_battery *battery) 264 { 265 return (battery->power_unit)?"mA":"mW"; 266 } 267 #endif 268 269 /* -------------------------------------------------------------------------- 270 Battery Management 271 -------------------------------------------------------------------------- */ 272 struct acpi_offsets { 273 size_t offset; /* offset inside struct acpi_sbs_battery */ 274 u8 mode; /* int or string? */ 275 }; 276 277 static struct acpi_offsets state_offsets[] = { 278 {offsetof(struct acpi_battery, state), 0}, 279 {offsetof(struct acpi_battery, rate_now), 0}, 280 {offsetof(struct acpi_battery, capacity_now), 0}, 281 {offsetof(struct acpi_battery, voltage_now), 0}, 282 }; 283 284 static struct acpi_offsets info_offsets[] = { 285 {offsetof(struct acpi_battery, power_unit), 0}, 286 {offsetof(struct acpi_battery, design_capacity), 0}, 287 {offsetof(struct acpi_battery, full_charge_capacity), 0}, 288 {offsetof(struct acpi_battery, technology), 0}, 289 {offsetof(struct acpi_battery, design_voltage), 0}, 290 {offsetof(struct acpi_battery, design_capacity_warning), 0}, 291 {offsetof(struct acpi_battery, design_capacity_low), 0}, 292 {offsetof(struct acpi_battery, capacity_granularity_1), 0}, 293 {offsetof(struct acpi_battery, capacity_granularity_2), 0}, 294 {offsetof(struct acpi_battery, model_number), 1}, 295 {offsetof(struct acpi_battery, serial_number), 1}, 296 {offsetof(struct acpi_battery, type), 1}, 297 {offsetof(struct acpi_battery, oem_info), 1}, 298 }; 299 300 static int extract_package(struct acpi_battery *battery, 301 union acpi_object *package, 302 struct acpi_offsets *offsets, int num) 303 { 304 int i; 305 union acpi_object *element; 306 if (package->type != ACPI_TYPE_PACKAGE) 307 return -EFAULT; 308 for (i = 0; i < num; ++i) { 309 if (package->package.count <= i) 310 return -EFAULT; 311 element = &package->package.elements[i]; 312 if (offsets[i].mode) { 313 u8 *ptr = (u8 *)battery + offsets[i].offset; 314 if (element->type == ACPI_TYPE_STRING || 315 element->type == ACPI_TYPE_BUFFER) 316 strncpy(ptr, element->string.pointer, 32); 317 else if (element->type == ACPI_TYPE_INTEGER) { 318 strncpy(ptr, (u8 *)&element->integer.value, 319 sizeof(acpi_integer)); 320 ptr[sizeof(acpi_integer)] = 0; 321 } else 322 *ptr = 0; /* don't have value */ 323 } else { 324 int *x = (int *)((u8 *)battery + offsets[i].offset); 325 *x = (element->type == ACPI_TYPE_INTEGER) ? 326 element->integer.value : -1; 327 } 328 } 329 return 0; 330 } 331 332 static int acpi_battery_get_status(struct acpi_battery *battery) 333 { 334 if (acpi_bus_get_status(battery->device)) { 335 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); 336 return -ENODEV; 337 } 338 return 0; 339 } 340 341 static int acpi_battery_get_info(struct acpi_battery *battery) 342 { 343 int result = -EFAULT; 344 acpi_status status = 0; 345 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 346 347 if (!acpi_battery_present(battery)) 348 return 0; 349 mutex_lock(&battery->lock); 350 status = acpi_evaluate_object(battery->device->handle, "_BIF", 351 NULL, &buffer); 352 mutex_unlock(&battery->lock); 353 354 if (ACPI_FAILURE(status)) { 355 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 356 return -ENODEV; 357 } 358 359 result = extract_package(battery, buffer.pointer, 360 info_offsets, ARRAY_SIZE(info_offsets)); 361 kfree(buffer.pointer); 362 return result; 363 } 364 365 static int acpi_battery_get_state(struct acpi_battery *battery) 366 { 367 int result = 0; 368 acpi_status status = 0; 369 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 370 371 if (!acpi_battery_present(battery)) 372 return 0; 373 374 if (battery->update_time && 375 time_before(jiffies, battery->update_time + 376 msecs_to_jiffies(cache_time))) 377 return 0; 378 379 mutex_lock(&battery->lock); 380 status = acpi_evaluate_object(battery->device->handle, "_BST", 381 NULL, &buffer); 382 mutex_unlock(&battery->lock); 383 384 if (ACPI_FAILURE(status)) { 385 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 386 return -ENODEV; 387 } 388 389 result = extract_package(battery, buffer.pointer, 390 state_offsets, ARRAY_SIZE(state_offsets)); 391 battery->update_time = jiffies; 392 kfree(buffer.pointer); 393 return result; 394 } 395 396 static int acpi_battery_set_alarm(struct acpi_battery *battery) 397 { 398 acpi_status status = 0; 399 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; 400 struct acpi_object_list arg_list = { 1, &arg0 }; 401 402 if (!acpi_battery_present(battery)|| !battery->alarm_present) 403 return -ENODEV; 404 405 arg0.integer.value = battery->alarm; 406 407 mutex_lock(&battery->lock); 408 status = acpi_evaluate_object(battery->device->handle, "_BTP", 409 &arg_list, NULL); 410 mutex_unlock(&battery->lock); 411 412 if (ACPI_FAILURE(status)) 413 return -ENODEV; 414 415 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm)); 416 return 0; 417 } 418 419 static int acpi_battery_init_alarm(struct acpi_battery *battery) 420 { 421 acpi_status status = AE_OK; 422 acpi_handle handle = NULL; 423 424 /* See if alarms are supported, and if so, set default */ 425 status = acpi_get_handle(battery->device->handle, "_BTP", &handle); 426 if (ACPI_FAILURE(status)) { 427 battery->alarm_present = 0; 428 return 0; 429 } 430 battery->alarm_present = 1; 431 if (!battery->alarm) 432 battery->alarm = battery->design_capacity_warning; 433 return acpi_battery_set_alarm(battery); 434 } 435 436 #ifdef CONFIG_ACPI_SYSFS_POWER 437 static ssize_t acpi_battery_alarm_show(struct device *dev, 438 struct device_attribute *attr, 439 char *buf) 440 { 441 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); 442 return sprintf(buf, "%d\n", battery->alarm * 1000); 443 } 444 445 static ssize_t acpi_battery_alarm_store(struct device *dev, 446 struct device_attribute *attr, 447 const char *buf, size_t count) 448 { 449 unsigned long x; 450 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); 451 if (sscanf(buf, "%ld\n", &x) == 1) 452 battery->alarm = x/1000; 453 if (acpi_battery_present(battery)) 454 acpi_battery_set_alarm(battery); 455 return count; 456 } 457 458 static struct device_attribute alarm_attr = { 459 .attr = {.name = "alarm", .mode = 0644}, 460 .show = acpi_battery_alarm_show, 461 .store = acpi_battery_alarm_store, 462 }; 463 464 static int sysfs_add_battery(struct acpi_battery *battery) 465 { 466 int result; 467 468 if (battery->power_unit) { 469 battery->bat.properties = charge_battery_props; 470 battery->bat.num_properties = 471 ARRAY_SIZE(charge_battery_props); 472 } else { 473 battery->bat.properties = energy_battery_props; 474 battery->bat.num_properties = 475 ARRAY_SIZE(energy_battery_props); 476 } 477 478 battery->bat.name = acpi_device_bid(battery->device); 479 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; 480 battery->bat.get_property = acpi_battery_get_property; 481 482 result = power_supply_register(&battery->device->dev, &battery->bat); 483 if (result) 484 return result; 485 return device_create_file(battery->bat.dev, &alarm_attr); 486 } 487 488 static void sysfs_remove_battery(struct acpi_battery *battery) 489 { 490 if (!battery->bat.dev) 491 return; 492 device_remove_file(battery->bat.dev, &alarm_attr); 493 power_supply_unregister(&battery->bat); 494 battery->bat.dev = NULL; 495 } 496 #endif 497 498 static int acpi_battery_update(struct acpi_battery *battery) 499 { 500 int result, old_present = acpi_battery_present(battery); 501 result = acpi_battery_get_status(battery); 502 if (result) 503 return result; 504 #ifdef CONFIG_ACPI_SYSFS_POWER 505 if (!acpi_battery_present(battery)) { 506 sysfs_remove_battery(battery); 507 battery->update_time = 0; 508 return 0; 509 } 510 #endif 511 if (!battery->update_time || 512 old_present != acpi_battery_present(battery)) { 513 result = acpi_battery_get_info(battery); 514 if (result) 515 return result; 516 acpi_battery_init_alarm(battery); 517 } 518 #ifdef CONFIG_ACPI_SYSFS_POWER 519 if (!battery->bat.dev) 520 sysfs_add_battery(battery); 521 #endif 522 return acpi_battery_get_state(battery); 523 } 524 525 /* -------------------------------------------------------------------------- 526 FS Interface (/proc) 527 -------------------------------------------------------------------------- */ 528 529 #ifdef CONFIG_ACPI_PROCFS_POWER 530 static struct proc_dir_entry *acpi_battery_dir; 531 532 static int acpi_battery_print_info(struct seq_file *seq, int result) 533 { 534 struct acpi_battery *battery = seq->private; 535 536 if (result) 537 goto end; 538 539 seq_printf(seq, "present: %s\n", 540 acpi_battery_present(battery)?"yes":"no"); 541 if (!acpi_battery_present(battery)) 542 goto end; 543 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 544 seq_printf(seq, "design capacity: unknown\n"); 545 else 546 seq_printf(seq, "design capacity: %d %sh\n", 547 battery->design_capacity, 548 acpi_battery_units(battery)); 549 550 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 551 seq_printf(seq, "last full capacity: unknown\n"); 552 else 553 seq_printf(seq, "last full capacity: %d %sh\n", 554 battery->full_charge_capacity, 555 acpi_battery_units(battery)); 556 557 seq_printf(seq, "battery technology: %srechargeable\n", 558 (!battery->technology)?"non-":""); 559 560 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 561 seq_printf(seq, "design voltage: unknown\n"); 562 else 563 seq_printf(seq, "design voltage: %d mV\n", 564 battery->design_voltage); 565 seq_printf(seq, "design capacity warning: %d %sh\n", 566 battery->design_capacity_warning, 567 acpi_battery_units(battery)); 568 seq_printf(seq, "design capacity low: %d %sh\n", 569 battery->design_capacity_low, 570 acpi_battery_units(battery)); 571 seq_printf(seq, "capacity granularity 1: %d %sh\n", 572 battery->capacity_granularity_1, 573 acpi_battery_units(battery)); 574 seq_printf(seq, "capacity granularity 2: %d %sh\n", 575 battery->capacity_granularity_2, 576 acpi_battery_units(battery)); 577 seq_printf(seq, "model number: %s\n", battery->model_number); 578 seq_printf(seq, "serial number: %s\n", battery->serial_number); 579 seq_printf(seq, "battery type: %s\n", battery->type); 580 seq_printf(seq, "OEM info: %s\n", battery->oem_info); 581 end: 582 if (result) 583 seq_printf(seq, "ERROR: Unable to read battery info\n"); 584 return result; 585 } 586 587 static int acpi_battery_print_state(struct seq_file *seq, int result) 588 { 589 struct acpi_battery *battery = seq->private; 590 591 if (result) 592 goto end; 593 594 seq_printf(seq, "present: %s\n", 595 acpi_battery_present(battery)?"yes":"no"); 596 if (!acpi_battery_present(battery)) 597 goto end; 598 599 seq_printf(seq, "capacity state: %s\n", 600 (battery->state & 0x04)?"critical":"ok"); 601 if ((battery->state & 0x01) && (battery->state & 0x02)) 602 seq_printf(seq, 603 "charging state: charging/discharging\n"); 604 else if (battery->state & 0x01) 605 seq_printf(seq, "charging state: discharging\n"); 606 else if (battery->state & 0x02) 607 seq_printf(seq, "charging state: charging\n"); 608 else 609 seq_printf(seq, "charging state: charged\n"); 610 611 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) 612 seq_printf(seq, "present rate: unknown\n"); 613 else 614 seq_printf(seq, "present rate: %d %s\n", 615 battery->rate_now, acpi_battery_units(battery)); 616 617 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) 618 seq_printf(seq, "remaining capacity: unknown\n"); 619 else 620 seq_printf(seq, "remaining capacity: %d %sh\n", 621 battery->capacity_now, acpi_battery_units(battery)); 622 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) 623 seq_printf(seq, "present voltage: unknown\n"); 624 else 625 seq_printf(seq, "present voltage: %d mV\n", 626 battery->voltage_now); 627 end: 628 if (result) 629 seq_printf(seq, "ERROR: Unable to read battery state\n"); 630 631 return result; 632 } 633 634 static int acpi_battery_print_alarm(struct seq_file *seq, int result) 635 { 636 struct acpi_battery *battery = seq->private; 637 638 if (result) 639 goto end; 640 641 if (!acpi_battery_present(battery)) { 642 seq_printf(seq, "present: no\n"); 643 goto end; 644 } 645 seq_printf(seq, "alarm: "); 646 if (!battery->alarm) 647 seq_printf(seq, "unsupported\n"); 648 else 649 seq_printf(seq, "%u %sh\n", battery->alarm, 650 acpi_battery_units(battery)); 651 end: 652 if (result) 653 seq_printf(seq, "ERROR: Unable to read battery alarm\n"); 654 return result; 655 } 656 657 static ssize_t acpi_battery_write_alarm(struct file *file, 658 const char __user * buffer, 659 size_t count, loff_t * ppos) 660 { 661 int result = 0; 662 char alarm_string[12] = { '\0' }; 663 struct seq_file *m = file->private_data; 664 struct acpi_battery *battery = m->private; 665 666 if (!battery || (count > sizeof(alarm_string) - 1)) 667 return -EINVAL; 668 if (!acpi_battery_present(battery)) { 669 result = -ENODEV; 670 goto end; 671 } 672 if (copy_from_user(alarm_string, buffer, count)) { 673 result = -EFAULT; 674 goto end; 675 } 676 alarm_string[count] = '\0'; 677 battery->alarm = simple_strtol(alarm_string, NULL, 0); 678 result = acpi_battery_set_alarm(battery); 679 end: 680 if (!result) 681 return count; 682 return result; 683 } 684 685 typedef int(*print_func)(struct seq_file *seq, int result); 686 687 static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { 688 acpi_battery_print_info, 689 acpi_battery_print_state, 690 acpi_battery_print_alarm, 691 }; 692 693 static int acpi_battery_read(int fid, struct seq_file *seq) 694 { 695 struct acpi_battery *battery = seq->private; 696 int result = acpi_battery_update(battery); 697 return acpi_print_funcs[fid](seq, result); 698 } 699 700 #define DECLARE_FILE_FUNCTIONS(_name) \ 701 static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ 702 { \ 703 return acpi_battery_read(_name##_tag, seq); \ 704 } \ 705 static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ 706 { \ 707 return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \ 708 } 709 710 DECLARE_FILE_FUNCTIONS(info); 711 DECLARE_FILE_FUNCTIONS(state); 712 DECLARE_FILE_FUNCTIONS(alarm); 713 714 #undef DECLARE_FILE_FUNCTIONS 715 716 #define FILE_DESCRIPTION_RO(_name) \ 717 { \ 718 .name = __stringify(_name), \ 719 .mode = S_IRUGO, \ 720 .ops = { \ 721 .open = acpi_battery_##_name##_open_fs, \ 722 .read = seq_read, \ 723 .llseek = seq_lseek, \ 724 .release = single_release, \ 725 .owner = THIS_MODULE, \ 726 }, \ 727 } 728 729 #define FILE_DESCRIPTION_RW(_name) \ 730 { \ 731 .name = __stringify(_name), \ 732 .mode = S_IFREG | S_IRUGO | S_IWUSR, \ 733 .ops = { \ 734 .open = acpi_battery_##_name##_open_fs, \ 735 .read = seq_read, \ 736 .llseek = seq_lseek, \ 737 .write = acpi_battery_write_##_name, \ 738 .release = single_release, \ 739 .owner = THIS_MODULE, \ 740 }, \ 741 } 742 743 static struct battery_file { 744 struct file_operations ops; 745 mode_t mode; 746 const char *name; 747 } acpi_battery_file[] = { 748 FILE_DESCRIPTION_RO(info), 749 FILE_DESCRIPTION_RO(state), 750 FILE_DESCRIPTION_RW(alarm), 751 }; 752 753 #undef FILE_DESCRIPTION_RO 754 #undef FILE_DESCRIPTION_RW 755 756 static int acpi_battery_add_fs(struct acpi_device *device) 757 { 758 struct proc_dir_entry *entry = NULL; 759 int i; 760 761 if (!acpi_device_dir(device)) { 762 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 763 acpi_battery_dir); 764 if (!acpi_device_dir(device)) 765 return -ENODEV; 766 } 767 768 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { 769 entry = proc_create_data(acpi_battery_file[i].name, 770 acpi_battery_file[i].mode, 771 acpi_device_dir(device), 772 &acpi_battery_file[i].ops, 773 acpi_driver_data(device)); 774 if (!entry) 775 return -ENODEV; 776 } 777 return 0; 778 } 779 780 static void acpi_battery_remove_fs(struct acpi_device *device) 781 { 782 int i; 783 if (!acpi_device_dir(device)) 784 return; 785 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) 786 remove_proc_entry(acpi_battery_file[i].name, 787 acpi_device_dir(device)); 788 789 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); 790 acpi_device_dir(device) = NULL; 791 } 792 793 #endif 794 795 /* -------------------------------------------------------------------------- 796 Driver Interface 797 -------------------------------------------------------------------------- */ 798 799 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) 800 { 801 struct acpi_battery *battery = data; 802 struct acpi_device *device; 803 if (!battery) 804 return; 805 device = battery->device; 806 acpi_battery_update(battery); 807 acpi_bus_generate_proc_event(device, event, 808 acpi_battery_present(battery)); 809 acpi_bus_generate_netlink_event(device->pnp.device_class, 810 dev_name(&device->dev), event, 811 acpi_battery_present(battery)); 812 #ifdef CONFIG_ACPI_SYSFS_POWER 813 /* acpi_batter_update could remove power_supply object */ 814 if (battery->bat.dev) 815 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); 816 #endif 817 } 818 819 static int acpi_battery_add(struct acpi_device *device) 820 { 821 int result = 0; 822 acpi_status status = 0; 823 struct acpi_battery *battery = NULL; 824 if (!device) 825 return -EINVAL; 826 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); 827 if (!battery) 828 return -ENOMEM; 829 battery->device = device; 830 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 831 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 832 device->driver_data = battery; 833 mutex_init(&battery->lock); 834 acpi_battery_update(battery); 835 #ifdef CONFIG_ACPI_PROCFS_POWER 836 result = acpi_battery_add_fs(device); 837 if (result) 838 goto end; 839 #endif 840 status = acpi_install_notify_handler(device->handle, 841 ACPI_ALL_NOTIFY, 842 acpi_battery_notify, battery); 843 if (ACPI_FAILURE(status)) { 844 ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); 845 result = -ENODEV; 846 goto end; 847 } 848 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", 849 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), 850 device->status.battery_present ? "present" : "absent"); 851 end: 852 if (result) { 853 #ifdef CONFIG_ACPI_PROCFS_POWER 854 acpi_battery_remove_fs(device); 855 #endif 856 kfree(battery); 857 } 858 return result; 859 } 860 861 static int acpi_battery_remove(struct acpi_device *device, int type) 862 { 863 acpi_status status = 0; 864 struct acpi_battery *battery = NULL; 865 866 if (!device || !acpi_driver_data(device)) 867 return -EINVAL; 868 battery = acpi_driver_data(device); 869 status = acpi_remove_notify_handler(device->handle, 870 ACPI_ALL_NOTIFY, 871 acpi_battery_notify); 872 #ifdef CONFIG_ACPI_PROCFS_POWER 873 acpi_battery_remove_fs(device); 874 #endif 875 #ifdef CONFIG_ACPI_SYSFS_POWER 876 sysfs_remove_battery(battery); 877 #endif 878 mutex_destroy(&battery->lock); 879 kfree(battery); 880 return 0; 881 } 882 883 /* this is needed to learn about changes made in suspended state */ 884 static int acpi_battery_resume(struct acpi_device *device) 885 { 886 struct acpi_battery *battery; 887 if (!device) 888 return -EINVAL; 889 battery = acpi_driver_data(device); 890 battery->update_time = 0; 891 acpi_battery_update(battery); 892 return 0; 893 } 894 895 static struct acpi_driver acpi_battery_driver = { 896 .name = "battery", 897 .class = ACPI_BATTERY_CLASS, 898 .ids = battery_device_ids, 899 .ops = { 900 .add = acpi_battery_add, 901 .resume = acpi_battery_resume, 902 .remove = acpi_battery_remove, 903 }, 904 }; 905 906 static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) 907 { 908 if (acpi_disabled) 909 return; 910 #ifdef CONFIG_ACPI_PROCFS_POWER 911 acpi_battery_dir = acpi_lock_battery_dir(); 912 if (!acpi_battery_dir) 913 return; 914 #endif 915 if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { 916 #ifdef CONFIG_ACPI_PROCFS_POWER 917 acpi_unlock_battery_dir(acpi_battery_dir); 918 #endif 919 return; 920 } 921 return; 922 } 923 924 static int __init acpi_battery_init(void) 925 { 926 async_schedule(acpi_battery_init_async, NULL); 927 return 0; 928 } 929 930 static void __exit acpi_battery_exit(void) 931 { 932 acpi_bus_unregister_driver(&acpi_battery_driver); 933 #ifdef CONFIG_ACPI_PROCFS_POWER 934 acpi_unlock_battery_dir(acpi_battery_dir); 935 #endif 936 } 937 938 module_init(acpi_battery_init); 939 module_exit(acpi_battery_exit); 940