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