1 /* 2 * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $) 3 * 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or (at 12 * your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 22 * 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 */ 25 26 #include <linux/kernel.h> 27 #include <linux/module.h> 28 #include <linux/init.h> 29 #include <linux/types.h> 30 #include <linux/proc_fs.h> 31 #include <linux/seq_file.h> 32 #include <asm/uaccess.h> 33 34 #include <acpi/acpi_bus.h> 35 #include <acpi/acpi_drivers.h> 36 37 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF 38 39 #define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" 40 #define ACPI_BATTERY_FORMAT_BST "NNNN" 41 42 #define ACPI_BATTERY_COMPONENT 0x00040000 43 #define ACPI_BATTERY_CLASS "battery" 44 #define ACPI_BATTERY_HID "PNP0C0A" 45 #define ACPI_BATTERY_DRIVER_NAME "ACPI Battery Driver" 46 #define ACPI_BATTERY_DEVICE_NAME "Battery" 47 #define ACPI_BATTERY_FILE_INFO "info" 48 #define ACPI_BATTERY_FILE_STATUS "state" 49 #define ACPI_BATTERY_FILE_ALARM "alarm" 50 #define ACPI_BATTERY_NOTIFY_STATUS 0x80 51 #define ACPI_BATTERY_NOTIFY_INFO 0x81 52 #define ACPI_BATTERY_UNITS_WATTS "mW" 53 #define ACPI_BATTERY_UNITS_AMPS "mA" 54 55 #define _COMPONENT ACPI_BATTERY_COMPONENT 56 ACPI_MODULE_NAME("acpi_battery") 57 58 MODULE_AUTHOR("Paul Diefenbaugh"); 59 MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME); 60 MODULE_LICENSE("GPL"); 61 62 extern struct proc_dir_entry *acpi_lock_battery_dir(void); 63 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 64 65 static int acpi_battery_add(struct acpi_device *device); 66 static int acpi_battery_remove(struct acpi_device *device, int type); 67 68 static struct acpi_driver acpi_battery_driver = { 69 .name = ACPI_BATTERY_DRIVER_NAME, 70 .class = ACPI_BATTERY_CLASS, 71 .ids = ACPI_BATTERY_HID, 72 .ops = { 73 .add = acpi_battery_add, 74 .remove = acpi_battery_remove, 75 }, 76 }; 77 78 struct acpi_battery_status { 79 acpi_integer state; 80 acpi_integer present_rate; 81 acpi_integer remaining_capacity; 82 acpi_integer present_voltage; 83 }; 84 85 struct acpi_battery_info { 86 acpi_integer power_unit; 87 acpi_integer design_capacity; 88 acpi_integer last_full_capacity; 89 acpi_integer battery_technology; 90 acpi_integer design_voltage; 91 acpi_integer design_capacity_warning; 92 acpi_integer design_capacity_low; 93 acpi_integer battery_capacity_granularity_1; 94 acpi_integer battery_capacity_granularity_2; 95 acpi_string model_number; 96 acpi_string serial_number; 97 acpi_string battery_type; 98 acpi_string oem_info; 99 }; 100 101 struct acpi_battery_flags { 102 u8 present:1; /* Bay occupied? */ 103 u8 power_unit:1; /* 0=watts, 1=apms */ 104 u8 alarm:1; /* _BTP present? */ 105 u8 reserved:5; 106 }; 107 108 struct acpi_battery_trips { 109 unsigned long warning; 110 unsigned long low; 111 }; 112 113 struct acpi_battery { 114 struct acpi_device * device; 115 struct acpi_battery_flags flags; 116 struct acpi_battery_trips trips; 117 unsigned long alarm; 118 struct acpi_battery_info *info; 119 }; 120 121 /* -------------------------------------------------------------------------- 122 Battery Management 123 -------------------------------------------------------------------------- */ 124 125 static int 126 acpi_battery_get_info(struct acpi_battery *battery, 127 struct acpi_battery_info **bif) 128 { 129 int result = 0; 130 acpi_status status = 0; 131 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 132 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), 133 ACPI_BATTERY_FORMAT_BIF 134 }; 135 struct acpi_buffer data = { 0, NULL }; 136 union acpi_object *package = NULL; 137 138 139 if (!battery || !bif) 140 return -EINVAL; 141 142 /* Evalute _BIF */ 143 144 status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); 145 if (ACPI_FAILURE(status)) { 146 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 147 return -ENODEV; 148 } 149 150 package = (union acpi_object *)buffer.pointer; 151 152 /* Extract Package Data */ 153 154 status = acpi_extract_package(package, &format, &data); 155 if (status != AE_BUFFER_OVERFLOW) { 156 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); 157 result = -ENODEV; 158 goto end; 159 } 160 161 data.pointer = kmalloc(data.length, GFP_KERNEL); 162 if (!data.pointer) { 163 result = -ENOMEM; 164 goto end; 165 } 166 memset(data.pointer, 0, data.length); 167 168 status = acpi_extract_package(package, &format, &data); 169 if (ACPI_FAILURE(status)) { 170 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); 171 kfree(data.pointer); 172 result = -ENODEV; 173 goto end; 174 } 175 176 end: 177 kfree(buffer.pointer); 178 179 if (!result) 180 (*bif) = (struct acpi_battery_info *)data.pointer; 181 182 return result; 183 } 184 185 static int 186 acpi_battery_get_status(struct acpi_battery *battery, 187 struct acpi_battery_status **bst) 188 { 189 int result = 0; 190 acpi_status status = 0; 191 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 192 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), 193 ACPI_BATTERY_FORMAT_BST 194 }; 195 struct acpi_buffer data = { 0, NULL }; 196 union acpi_object *package = NULL; 197 198 199 if (!battery || !bst) 200 return -EINVAL; 201 202 /* Evalute _BST */ 203 204 status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); 205 if (ACPI_FAILURE(status)) { 206 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 207 return -ENODEV; 208 } 209 210 package = (union acpi_object *)buffer.pointer; 211 212 /* Extract Package Data */ 213 214 status = acpi_extract_package(package, &format, &data); 215 if (status != AE_BUFFER_OVERFLOW) { 216 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); 217 result = -ENODEV; 218 goto end; 219 } 220 221 data.pointer = kmalloc(data.length, GFP_KERNEL); 222 if (!data.pointer) { 223 result = -ENOMEM; 224 goto end; 225 } 226 memset(data.pointer, 0, data.length); 227 228 status = acpi_extract_package(package, &format, &data); 229 if (ACPI_FAILURE(status)) { 230 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); 231 kfree(data.pointer); 232 result = -ENODEV; 233 goto end; 234 } 235 236 end: 237 kfree(buffer.pointer); 238 239 if (!result) 240 (*bst) = (struct acpi_battery_status *)data.pointer; 241 242 return result; 243 } 244 245 static int 246 acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) 247 { 248 acpi_status status = 0; 249 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 250 struct acpi_object_list arg_list = { 1, &arg0 }; 251 252 253 if (!battery) 254 return -EINVAL; 255 256 if (!battery->flags.alarm) 257 return -ENODEV; 258 259 arg0.integer.value = alarm; 260 261 status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); 262 if (ACPI_FAILURE(status)) 263 return -ENODEV; 264 265 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm)); 266 267 battery->alarm = alarm; 268 269 return 0; 270 } 271 272 static int acpi_battery_check(struct acpi_battery *battery) 273 { 274 int result = 0; 275 acpi_status status = AE_OK; 276 acpi_handle handle = NULL; 277 struct acpi_device *device = NULL; 278 struct acpi_battery_info *bif = NULL; 279 280 281 if (!battery) 282 return -EINVAL; 283 284 device = battery->device; 285 286 result = acpi_bus_get_status(device); 287 if (result) 288 return result; 289 290 /* Insertion? */ 291 292 if (!battery->flags.present && device->status.battery_present) { 293 294 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); 295 296 /* Evalute _BIF to get certain static information */ 297 298 result = acpi_battery_get_info(battery, &bif); 299 if (result) 300 return result; 301 302 battery->flags.power_unit = bif->power_unit; 303 battery->trips.warning = bif->design_capacity_warning; 304 battery->trips.low = bif->design_capacity_low; 305 kfree(bif); 306 307 /* See if alarms are supported, and if so, set default */ 308 309 status = acpi_get_handle(battery->device->handle, "_BTP", &handle); 310 if (ACPI_SUCCESS(status)) { 311 battery->flags.alarm = 1; 312 acpi_battery_set_alarm(battery, battery->trips.warning); 313 } 314 } 315 316 /* Removal? */ 317 318 else if (battery->flags.present && !device->status.battery_present) { 319 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n")); 320 } 321 322 battery->flags.present = device->status.battery_present; 323 324 return result; 325 } 326 327 /* -------------------------------------------------------------------------- 328 FS Interface (/proc) 329 -------------------------------------------------------------------------- */ 330 331 static struct proc_dir_entry *acpi_battery_dir; 332 static int acpi_battery_read_info(struct seq_file *seq, void *offset) 333 { 334 int result = 0; 335 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 336 struct acpi_battery_info *bif = NULL; 337 char *units = "?"; 338 339 340 if (!battery) 341 goto end; 342 343 if (battery->flags.present) 344 seq_printf(seq, "present: yes\n"); 345 else { 346 seq_printf(seq, "present: no\n"); 347 goto end; 348 } 349 350 /* Battery Info (_BIF) */ 351 352 result = acpi_battery_get_info(battery, &bif); 353 if (result || !bif) { 354 seq_printf(seq, "ERROR: Unable to read battery information\n"); 355 goto end; 356 } 357 358 units = 359 bif-> 360 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 361 362 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 363 seq_printf(seq, "design capacity: unknown\n"); 364 else 365 seq_printf(seq, "design capacity: %d %sh\n", 366 (u32) bif->design_capacity, units); 367 368 if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 369 seq_printf(seq, "last full capacity: unknown\n"); 370 else 371 seq_printf(seq, "last full capacity: %d %sh\n", 372 (u32) bif->last_full_capacity, units); 373 374 switch ((u32) bif->battery_technology) { 375 case 0: 376 seq_printf(seq, "battery technology: non-rechargeable\n"); 377 break; 378 case 1: 379 seq_printf(seq, "battery technology: rechargeable\n"); 380 break; 381 default: 382 seq_printf(seq, "battery technology: unknown\n"); 383 break; 384 } 385 386 if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 387 seq_printf(seq, "design voltage: unknown\n"); 388 else 389 seq_printf(seq, "design voltage: %d mV\n", 390 (u32) bif->design_voltage); 391 392 seq_printf(seq, "design capacity warning: %d %sh\n", 393 (u32) bif->design_capacity_warning, units); 394 seq_printf(seq, "design capacity low: %d %sh\n", 395 (u32) bif->design_capacity_low, units); 396 seq_printf(seq, "capacity granularity 1: %d %sh\n", 397 (u32) bif->battery_capacity_granularity_1, units); 398 seq_printf(seq, "capacity granularity 2: %d %sh\n", 399 (u32) bif->battery_capacity_granularity_2, units); 400 seq_printf(seq, "model number: %s\n", bif->model_number); 401 seq_printf(seq, "serial number: %s\n", bif->serial_number); 402 seq_printf(seq, "battery type: %s\n", bif->battery_type); 403 seq_printf(seq, "OEM info: %s\n", bif->oem_info); 404 405 end: 406 kfree(bif); 407 408 return 0; 409 } 410 411 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) 412 { 413 return single_open(file, acpi_battery_read_info, PDE(inode)->data); 414 } 415 416 static int acpi_battery_read_state(struct seq_file *seq, void *offset) 417 { 418 int result = 0; 419 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 420 struct acpi_battery_status *bst = NULL; 421 char *units = "?"; 422 423 424 if (!battery) 425 goto end; 426 427 if (battery->flags.present) 428 seq_printf(seq, "present: yes\n"); 429 else { 430 seq_printf(seq, "present: no\n"); 431 goto end; 432 } 433 434 /* Battery Units */ 435 436 units = 437 battery->flags. 438 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 439 440 /* Battery Status (_BST) */ 441 442 result = acpi_battery_get_status(battery, &bst); 443 if (result || !bst) { 444 seq_printf(seq, "ERROR: Unable to read battery status\n"); 445 goto end; 446 } 447 448 if (!(bst->state & 0x04)) 449 seq_printf(seq, "capacity state: ok\n"); 450 else 451 seq_printf(seq, "capacity state: critical\n"); 452 453 if ((bst->state & 0x01) && (bst->state & 0x02)) { 454 seq_printf(seq, 455 "charging state: charging/discharging\n"); 456 } else if (bst->state & 0x01) 457 seq_printf(seq, "charging state: discharging\n"); 458 else if (bst->state & 0x02) 459 seq_printf(seq, "charging state: charging\n"); 460 else { 461 seq_printf(seq, "charging state: charged\n"); 462 } 463 464 if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) 465 seq_printf(seq, "present rate: unknown\n"); 466 else 467 seq_printf(seq, "present rate: %d %s\n", 468 (u32) bst->present_rate, units); 469 470 if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 471 seq_printf(seq, "remaining capacity: unknown\n"); 472 else 473 seq_printf(seq, "remaining capacity: %d %sh\n", 474 (u32) bst->remaining_capacity, units); 475 476 if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 477 seq_printf(seq, "present voltage: unknown\n"); 478 else 479 seq_printf(seq, "present voltage: %d mV\n", 480 (u32) bst->present_voltage); 481 482 end: 483 kfree(bst); 484 485 return 0; 486 } 487 488 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) 489 { 490 return single_open(file, acpi_battery_read_state, PDE(inode)->data); 491 } 492 493 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 494 { 495 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 496 char *units = "?"; 497 498 499 if (!battery) 500 goto end; 501 502 if (!battery->flags.present) { 503 seq_printf(seq, "present: no\n"); 504 goto end; 505 } 506 507 /* Battery Units */ 508 509 units = 510 battery->flags. 511 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 512 513 /* Battery Alarm */ 514 515 seq_printf(seq, "alarm: "); 516 if (!battery->alarm) 517 seq_printf(seq, "unsupported\n"); 518 else 519 seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units); 520 521 end: 522 return 0; 523 } 524 525 static ssize_t 526 acpi_battery_write_alarm(struct file *file, 527 const char __user * buffer, 528 size_t count, loff_t * ppos) 529 { 530 int result = 0; 531 char alarm_string[12] = { '\0' }; 532 struct seq_file *m = (struct seq_file *)file->private_data; 533 struct acpi_battery *battery = (struct acpi_battery *)m->private; 534 535 536 if (!battery || (count > sizeof(alarm_string) - 1)) 537 return -EINVAL; 538 539 if (!battery->flags.present) 540 return -ENODEV; 541 542 if (copy_from_user(alarm_string, buffer, count)) 543 return -EFAULT; 544 545 alarm_string[count] = '\0'; 546 547 result = acpi_battery_set_alarm(battery, 548 simple_strtoul(alarm_string, NULL, 0)); 549 if (result) 550 return result; 551 552 return count; 553 } 554 555 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) 556 { 557 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); 558 } 559 560 static const struct file_operations acpi_battery_info_ops = { 561 .open = acpi_battery_info_open_fs, 562 .read = seq_read, 563 .llseek = seq_lseek, 564 .release = single_release, 565 .owner = THIS_MODULE, 566 }; 567 568 static const struct file_operations acpi_battery_state_ops = { 569 .open = acpi_battery_state_open_fs, 570 .read = seq_read, 571 .llseek = seq_lseek, 572 .release = single_release, 573 .owner = THIS_MODULE, 574 }; 575 576 static const struct file_operations acpi_battery_alarm_ops = { 577 .open = acpi_battery_alarm_open_fs, 578 .read = seq_read, 579 .write = acpi_battery_write_alarm, 580 .llseek = seq_lseek, 581 .release = single_release, 582 .owner = THIS_MODULE, 583 }; 584 585 static int acpi_battery_add_fs(struct acpi_device *device) 586 { 587 struct proc_dir_entry *entry = NULL; 588 589 590 if (!acpi_device_dir(device)) { 591 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 592 acpi_battery_dir); 593 if (!acpi_device_dir(device)) 594 return -ENODEV; 595 acpi_device_dir(device)->owner = THIS_MODULE; 596 } 597 598 /* 'info' [R] */ 599 entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, 600 S_IRUGO, acpi_device_dir(device)); 601 if (!entry) 602 return -ENODEV; 603 else { 604 entry->proc_fops = &acpi_battery_info_ops; 605 entry->data = acpi_driver_data(device); 606 entry->owner = THIS_MODULE; 607 } 608 609 /* 'status' [R] */ 610 entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS, 611 S_IRUGO, acpi_device_dir(device)); 612 if (!entry) 613 return -ENODEV; 614 else { 615 entry->proc_fops = &acpi_battery_state_ops; 616 entry->data = acpi_driver_data(device); 617 entry->owner = THIS_MODULE; 618 } 619 620 /* 'alarm' [R/W] */ 621 entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM, 622 S_IFREG | S_IRUGO | S_IWUSR, 623 acpi_device_dir(device)); 624 if (!entry) 625 return -ENODEV; 626 else { 627 entry->proc_fops = &acpi_battery_alarm_ops; 628 entry->data = acpi_driver_data(device); 629 entry->owner = THIS_MODULE; 630 } 631 632 return 0; 633 } 634 635 static int acpi_battery_remove_fs(struct acpi_device *device) 636 { 637 638 if (acpi_device_dir(device)) { 639 remove_proc_entry(ACPI_BATTERY_FILE_ALARM, 640 acpi_device_dir(device)); 641 remove_proc_entry(ACPI_BATTERY_FILE_STATUS, 642 acpi_device_dir(device)); 643 remove_proc_entry(ACPI_BATTERY_FILE_INFO, 644 acpi_device_dir(device)); 645 646 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); 647 acpi_device_dir(device) = NULL; 648 } 649 650 return 0; 651 } 652 653 /* -------------------------------------------------------------------------- 654 Driver Interface 655 -------------------------------------------------------------------------- */ 656 657 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) 658 { 659 struct acpi_battery *battery = (struct acpi_battery *)data; 660 struct acpi_device *device = NULL; 661 662 663 if (!battery) 664 return; 665 666 device = battery->device; 667 668 switch (event) { 669 case ACPI_BATTERY_NOTIFY_STATUS: 670 case ACPI_BATTERY_NOTIFY_INFO: 671 case ACPI_NOTIFY_BUS_CHECK: 672 case ACPI_NOTIFY_DEVICE_CHECK: 673 acpi_battery_check(battery); 674 acpi_bus_generate_event(device, event, battery->flags.present); 675 break; 676 default: 677 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 678 "Unsupported event [0x%x]\n", event)); 679 break; 680 } 681 682 return; 683 } 684 685 static int acpi_battery_add(struct acpi_device *device) 686 { 687 int result = 0; 688 acpi_status status = 0; 689 struct acpi_battery *battery = NULL; 690 691 692 if (!device) 693 return -EINVAL; 694 695 battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL); 696 if (!battery) 697 return -ENOMEM; 698 memset(battery, 0, sizeof(struct acpi_battery)); 699 700 battery->device = device; 701 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 702 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 703 acpi_driver_data(device) = battery; 704 705 result = acpi_battery_check(battery); 706 if (result) 707 goto end; 708 709 result = acpi_battery_add_fs(device); 710 if (result) 711 goto end; 712 713 status = acpi_install_notify_handler(device->handle, 714 ACPI_ALL_NOTIFY, 715 acpi_battery_notify, battery); 716 if (ACPI_FAILURE(status)) { 717 result = -ENODEV; 718 goto end; 719 } 720 721 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", 722 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), 723 device->status.battery_present ? "present" : "absent"); 724 725 end: 726 if (result) { 727 acpi_battery_remove_fs(device); 728 kfree(battery); 729 } 730 731 return result; 732 } 733 734 static int acpi_battery_remove(struct acpi_device *device, int type) 735 { 736 acpi_status status = 0; 737 struct acpi_battery *battery = NULL; 738 739 740 if (!device || !acpi_driver_data(device)) 741 return -EINVAL; 742 743 battery = (struct acpi_battery *)acpi_driver_data(device); 744 745 status = acpi_remove_notify_handler(device->handle, 746 ACPI_ALL_NOTIFY, 747 acpi_battery_notify); 748 749 acpi_battery_remove_fs(device); 750 751 kfree(battery); 752 753 return 0; 754 } 755 756 static int __init acpi_battery_init(void) 757 { 758 int result; 759 760 if (acpi_disabled) 761 return -ENODEV; 762 763 acpi_battery_dir = acpi_lock_battery_dir(); 764 if (!acpi_battery_dir) 765 return -ENODEV; 766 767 result = acpi_bus_register_driver(&acpi_battery_driver); 768 if (result < 0) { 769 acpi_unlock_battery_dir(acpi_battery_dir); 770 return -ENODEV; 771 } 772 773 return 0; 774 } 775 776 static void __exit acpi_battery_exit(void) 777 { 778 779 acpi_bus_unregister_driver(&acpi_battery_driver); 780 781 acpi_unlock_battery_dir(acpi_battery_dir); 782 783 return; 784 } 785 786 module_init(acpi_battery_init); 787 module_exit(acpi_battery_exit); 788