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_DEVICE_NAME "Battery" 45 #define ACPI_BATTERY_NOTIFY_STATUS 0x80 46 #define ACPI_BATTERY_NOTIFY_INFO 0x81 47 #define ACPI_BATTERY_UNITS_WATTS "mW" 48 #define ACPI_BATTERY_UNITS_AMPS "mA" 49 50 #define _COMPONENT ACPI_BATTERY_COMPONENT 51 52 #define ACPI_BATTERY_UPDATE_TIME 0 53 54 #define ACPI_BATTERY_NONE_UPDATE 0 55 #define ACPI_BATTERY_EASY_UPDATE 1 56 #define ACPI_BATTERY_INIT_UPDATE 2 57 58 ACPI_MODULE_NAME("battery"); 59 60 MODULE_AUTHOR("Paul Diefenbaugh"); 61 MODULE_DESCRIPTION("ACPI Battery Driver"); 62 MODULE_LICENSE("GPL"); 63 64 static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME; 65 66 /* 0 - every time, > 0 - by update_time */ 67 module_param(update_time, uint, 0644); 68 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 static int acpi_battery_add(struct acpi_device *device); 73 static int acpi_battery_remove(struct acpi_device *device, int type); 74 static int acpi_battery_resume(struct acpi_device *device); 75 76 static const struct acpi_device_id battery_device_ids[] = { 77 {"PNP0C0A", 0}, 78 {"", 0}, 79 }; 80 MODULE_DEVICE_TABLE(acpi, battery_device_ids); 81 82 static struct acpi_driver acpi_battery_driver = { 83 .name = "battery", 84 .class = ACPI_BATTERY_CLASS, 85 .ids = battery_device_ids, 86 .ops = { 87 .add = acpi_battery_add, 88 .resume = acpi_battery_resume, 89 .remove = acpi_battery_remove, 90 }, 91 }; 92 93 struct acpi_battery_state { 94 acpi_integer state; 95 acpi_integer present_rate; 96 acpi_integer remaining_capacity; 97 acpi_integer present_voltage; 98 }; 99 100 struct acpi_battery_info { 101 acpi_integer power_unit; 102 acpi_integer design_capacity; 103 acpi_integer last_full_capacity; 104 acpi_integer battery_technology; 105 acpi_integer design_voltage; 106 acpi_integer design_capacity_warning; 107 acpi_integer design_capacity_low; 108 acpi_integer battery_capacity_granularity_1; 109 acpi_integer battery_capacity_granularity_2; 110 acpi_string model_number; 111 acpi_string serial_number; 112 acpi_string battery_type; 113 acpi_string oem_info; 114 }; 115 116 enum acpi_battery_files{ 117 ACPI_BATTERY_INFO = 0, 118 ACPI_BATTERY_STATE, 119 ACPI_BATTERY_ALARM, 120 ACPI_BATTERY_NUMFILES, 121 }; 122 123 struct acpi_battery_flags { 124 u8 battery_present_prev; 125 u8 alarm_present; 126 u8 init_update; 127 u8 update[ACPI_BATTERY_NUMFILES]; 128 u8 power_unit; 129 }; 130 131 struct acpi_battery { 132 struct mutex mutex; 133 struct acpi_device *device; 134 struct acpi_battery_flags flags; 135 struct acpi_buffer bif_data; 136 struct acpi_buffer bst_data; 137 unsigned long alarm; 138 unsigned long update_time[ACPI_BATTERY_NUMFILES]; 139 }; 140 141 inline int acpi_battery_present(struct acpi_battery *battery) 142 { 143 return battery->device->status.battery_present; 144 } 145 inline char *acpi_battery_power_units(struct acpi_battery *battery) 146 { 147 if (battery->flags.power_unit) 148 return ACPI_BATTERY_UNITS_AMPS; 149 else 150 return ACPI_BATTERY_UNITS_WATTS; 151 } 152 153 inline acpi_handle acpi_battery_handle(struct acpi_battery *battery) 154 { 155 return battery->device->handle; 156 } 157 158 /* -------------------------------------------------------------------------- 159 Battery Management 160 -------------------------------------------------------------------------- */ 161 162 static void acpi_battery_check_result(struct acpi_battery *battery, int result) 163 { 164 if (!battery) 165 return; 166 167 if (result) { 168 battery->flags.init_update = 1; 169 } 170 } 171 172 static int acpi_battery_extract_package(struct acpi_battery *battery, 173 union acpi_object *package, 174 struct acpi_buffer *format, 175 struct acpi_buffer *data, 176 char *package_name) 177 { 178 acpi_status status = AE_OK; 179 struct acpi_buffer data_null = { 0, NULL }; 180 181 status = acpi_extract_package(package, format, &data_null); 182 if (status != AE_BUFFER_OVERFLOW) { 183 ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", 184 package_name)); 185 return -ENODEV; 186 } 187 188 if (data_null.length != data->length) { 189 kfree(data->pointer); 190 data->pointer = kzalloc(data_null.length, GFP_KERNEL); 191 if (!data->pointer) { 192 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); 193 return -ENOMEM; 194 } 195 data->length = data_null.length; 196 } 197 198 status = acpi_extract_package(package, format, data); 199 if (ACPI_FAILURE(status)) { 200 ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", 201 package_name)); 202 return -ENODEV; 203 } 204 205 return 0; 206 } 207 208 static int acpi_battery_get_status(struct acpi_battery *battery) 209 { 210 int result = 0; 211 212 result = acpi_bus_get_status(battery->device); 213 if (result) { 214 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); 215 return -ENODEV; 216 } 217 return result; 218 } 219 220 static int acpi_battery_get_info(struct acpi_battery *battery) 221 { 222 int result = 0; 223 acpi_status status = 0; 224 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 225 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), 226 ACPI_BATTERY_FORMAT_BIF 227 }; 228 union acpi_object *package = NULL; 229 struct acpi_buffer *data = NULL; 230 struct acpi_battery_info *bif = NULL; 231 232 battery->update_time[ACPI_BATTERY_INFO] = get_seconds(); 233 234 if (!acpi_battery_present(battery)) 235 return 0; 236 237 /* Evaluate _BIF */ 238 239 status = 240 acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, 241 &buffer); 242 if (ACPI_FAILURE(status)) { 243 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 244 return -ENODEV; 245 } 246 247 package = buffer.pointer; 248 249 data = &battery->bif_data; 250 251 /* Extract Package Data */ 252 253 result = 254 acpi_battery_extract_package(battery, package, &format, data, 255 "_BIF"); 256 if (result) 257 goto end; 258 259 end: 260 261 kfree(buffer.pointer); 262 263 if (!result) { 264 bif = data->pointer; 265 battery->flags.power_unit = bif->power_unit; 266 } 267 268 return result; 269 } 270 271 static int acpi_battery_get_state(struct acpi_battery *battery) 272 { 273 int result = 0; 274 acpi_status status = 0; 275 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 276 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), 277 ACPI_BATTERY_FORMAT_BST 278 }; 279 union acpi_object *package = NULL; 280 struct acpi_buffer *data = NULL; 281 282 battery->update_time[ACPI_BATTERY_STATE] = get_seconds(); 283 284 if (!acpi_battery_present(battery)) 285 return 0; 286 287 /* Evaluate _BST */ 288 289 status = 290 acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, 291 &buffer); 292 if (ACPI_FAILURE(status)) { 293 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 294 return -ENODEV; 295 } 296 297 package = buffer.pointer; 298 299 data = &battery->bst_data; 300 301 /* Extract Package Data */ 302 303 result = 304 acpi_battery_extract_package(battery, package, &format, data, 305 "_BST"); 306 if (result) 307 goto end; 308 309 end: 310 kfree(buffer.pointer); 311 312 return result; 313 } 314 315 static int acpi_battery_get_alarm(struct acpi_battery *battery) 316 { 317 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); 318 319 return 0; 320 } 321 322 static int acpi_battery_set_alarm(struct acpi_battery *battery, 323 unsigned long alarm) 324 { 325 acpi_status status = 0; 326 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 327 struct acpi_object_list arg_list = { 1, &arg0 }; 328 329 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); 330 331 if (!acpi_battery_present(battery)) 332 return -ENODEV; 333 334 if (!battery->flags.alarm_present) 335 return -ENODEV; 336 337 arg0.integer.value = alarm; 338 339 status = 340 acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", 341 &arg_list, NULL); 342 if (ACPI_FAILURE(status)) 343 return -ENODEV; 344 345 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm)); 346 347 battery->alarm = alarm; 348 349 return 0; 350 } 351 352 static int acpi_battery_init_alarm(struct acpi_battery *battery) 353 { 354 int result = 0; 355 acpi_status status = AE_OK; 356 acpi_handle handle = NULL; 357 struct acpi_battery_info *bif = battery->bif_data.pointer; 358 unsigned long alarm = battery->alarm; 359 360 /* See if alarms are supported, and if so, set default */ 361 362 status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); 363 if (ACPI_SUCCESS(status)) { 364 battery->flags.alarm_present = 1; 365 if (!alarm && bif) { 366 alarm = bif->design_capacity_warning; 367 } 368 result = acpi_battery_set_alarm(battery, alarm); 369 if (result) 370 goto end; 371 } else { 372 battery->flags.alarm_present = 0; 373 } 374 375 end: 376 377 return result; 378 } 379 380 static int acpi_battery_init_update(struct acpi_battery *battery) 381 { 382 int result = 0; 383 384 result = acpi_battery_get_status(battery); 385 if (result) 386 return result; 387 388 battery->flags.battery_present_prev = acpi_battery_present(battery); 389 390 if (acpi_battery_present(battery)) { 391 result = acpi_battery_get_info(battery); 392 if (result) 393 return result; 394 result = acpi_battery_get_state(battery); 395 if (result) 396 return result; 397 398 acpi_battery_init_alarm(battery); 399 } 400 401 return result; 402 } 403 404 static int acpi_battery_update(struct acpi_battery *battery, 405 int update, int *update_result_ptr) 406 { 407 int result = 0; 408 int update_result = ACPI_BATTERY_NONE_UPDATE; 409 410 if (!acpi_battery_present(battery)) { 411 update = 1; 412 } 413 414 if (battery->flags.init_update) { 415 result = acpi_battery_init_update(battery); 416 if (result) 417 goto end; 418 update_result = ACPI_BATTERY_INIT_UPDATE; 419 } else if (update) { 420 result = acpi_battery_get_status(battery); 421 if (result) 422 goto end; 423 if ((!battery->flags.battery_present_prev & acpi_battery_present(battery)) 424 || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) { 425 result = acpi_battery_init_update(battery); 426 if (result) 427 goto end; 428 update_result = ACPI_BATTERY_INIT_UPDATE; 429 } else { 430 update_result = ACPI_BATTERY_EASY_UPDATE; 431 } 432 } 433 434 end: 435 436 battery->flags.init_update = (result != 0); 437 438 *update_result_ptr = update_result; 439 440 return result; 441 } 442 443 static void acpi_battery_notify_update(struct acpi_battery *battery) 444 { 445 acpi_battery_get_status(battery); 446 447 if (battery->flags.init_update) { 448 return; 449 } 450 451 if ((!battery->flags.battery_present_prev & 452 acpi_battery_present(battery)) || 453 (battery->flags.battery_present_prev & 454 !acpi_battery_present(battery))) { 455 battery->flags.init_update = 1; 456 } else { 457 battery->flags.update[ACPI_BATTERY_INFO] = 1; 458 battery->flags.update[ACPI_BATTERY_STATE] = 1; 459 battery->flags.update[ACPI_BATTERY_ALARM] = 1; 460 } 461 } 462 463 /* -------------------------------------------------------------------------- 464 FS Interface (/proc) 465 -------------------------------------------------------------------------- */ 466 467 static struct proc_dir_entry *acpi_battery_dir; 468 469 static int acpi_battery_print_info(struct seq_file *seq, int result) 470 { 471 struct acpi_battery *battery = seq->private; 472 struct acpi_battery_info *bif = NULL; 473 char *units = "?"; 474 475 if (result) 476 goto end; 477 478 if (acpi_battery_present(battery)) 479 seq_printf(seq, "present: yes\n"); 480 else { 481 seq_printf(seq, "present: no\n"); 482 goto end; 483 } 484 485 bif = battery->bif_data.pointer; 486 if (!bif) { 487 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL")); 488 result = -ENODEV; 489 goto end; 490 } 491 492 /* Battery Units */ 493 494 units = acpi_battery_power_units(battery); 495 496 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 497 seq_printf(seq, "design capacity: unknown\n"); 498 else 499 seq_printf(seq, "design capacity: %d %sh\n", 500 (u32) bif->design_capacity, units); 501 502 if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 503 seq_printf(seq, "last full capacity: unknown\n"); 504 else 505 seq_printf(seq, "last full capacity: %d %sh\n", 506 (u32) bif->last_full_capacity, units); 507 508 switch ((u32) bif->battery_technology) { 509 case 0: 510 seq_printf(seq, "battery technology: non-rechargeable\n"); 511 break; 512 case 1: 513 seq_printf(seq, "battery technology: rechargeable\n"); 514 break; 515 default: 516 seq_printf(seq, "battery technology: unknown\n"); 517 break; 518 } 519 520 if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 521 seq_printf(seq, "design voltage: unknown\n"); 522 else 523 seq_printf(seq, "design voltage: %d mV\n", 524 (u32) bif->design_voltage); 525 seq_printf(seq, "design capacity warning: %d %sh\n", 526 (u32) bif->design_capacity_warning, units); 527 seq_printf(seq, "design capacity low: %d %sh\n", 528 (u32) bif->design_capacity_low, units); 529 seq_printf(seq, "capacity granularity 1: %d %sh\n", 530 (u32) bif->battery_capacity_granularity_1, units); 531 seq_printf(seq, "capacity granularity 2: %d %sh\n", 532 (u32) bif->battery_capacity_granularity_2, units); 533 seq_printf(seq, "model number: %s\n", bif->model_number); 534 seq_printf(seq, "serial number: %s\n", bif->serial_number); 535 seq_printf(seq, "battery type: %s\n", bif->battery_type); 536 seq_printf(seq, "OEM info: %s\n", bif->oem_info); 537 538 end: 539 540 if (result) 541 seq_printf(seq, "ERROR: Unable to read battery info\n"); 542 543 return result; 544 } 545 546 static int acpi_battery_print_state(struct seq_file *seq, int result) 547 { 548 struct acpi_battery *battery = seq->private; 549 struct acpi_battery_state *bst = NULL; 550 char *units = "?"; 551 552 if (result) 553 goto end; 554 555 if (acpi_battery_present(battery)) 556 seq_printf(seq, "present: yes\n"); 557 else { 558 seq_printf(seq, "present: no\n"); 559 goto end; 560 } 561 562 bst = battery->bst_data.pointer; 563 if (!bst) { 564 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL")); 565 result = -ENODEV; 566 goto end; 567 } 568 569 /* Battery Units */ 570 571 units = acpi_battery_power_units(battery); 572 573 if (!(bst->state & 0x04)) 574 seq_printf(seq, "capacity state: ok\n"); 575 else 576 seq_printf(seq, "capacity state: critical\n"); 577 578 if ((bst->state & 0x01) && (bst->state & 0x02)) { 579 seq_printf(seq, 580 "charging state: charging/discharging\n"); 581 } else if (bst->state & 0x01) 582 seq_printf(seq, "charging state: discharging\n"); 583 else if (bst->state & 0x02) 584 seq_printf(seq, "charging state: charging\n"); 585 else { 586 seq_printf(seq, "charging state: charged\n"); 587 } 588 589 if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) 590 seq_printf(seq, "present rate: unknown\n"); 591 else 592 seq_printf(seq, "present rate: %d %s\n", 593 (u32) bst->present_rate, units); 594 595 if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 596 seq_printf(seq, "remaining capacity: unknown\n"); 597 else 598 seq_printf(seq, "remaining capacity: %d %sh\n", 599 (u32) bst->remaining_capacity, units); 600 601 if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) 602 seq_printf(seq, "present voltage: unknown\n"); 603 else 604 seq_printf(seq, "present voltage: %d mV\n", 605 (u32) bst->present_voltage); 606 607 end: 608 609 if (result) { 610 seq_printf(seq, "ERROR: Unable to read battery state\n"); 611 } 612 613 return result; 614 } 615 616 static int acpi_battery_print_alarm(struct seq_file *seq, int result) 617 { 618 struct acpi_battery *battery = seq->private; 619 char *units = "?"; 620 621 if (result) 622 goto end; 623 624 if (!acpi_battery_present(battery)) { 625 seq_printf(seq, "present: no\n"); 626 goto end; 627 } 628 629 /* Battery Units */ 630 631 units = acpi_battery_power_units(battery); 632 633 seq_printf(seq, "alarm: "); 634 if (!battery->alarm) 635 seq_printf(seq, "unsupported\n"); 636 else 637 seq_printf(seq, "%lu %sh\n", battery->alarm, units); 638 639 end: 640 641 if (result) 642 seq_printf(seq, "ERROR: Unable to read battery alarm\n"); 643 644 return result; 645 } 646 647 static ssize_t 648 acpi_battery_write_alarm(struct file *file, 649 const char __user * buffer, 650 size_t count, loff_t * ppos) 651 { 652 int result = 0; 653 char alarm_string[12] = { '\0' }; 654 struct seq_file *m = file->private_data; 655 struct acpi_battery *battery = m->private; 656 int update_result = ACPI_BATTERY_NONE_UPDATE; 657 658 if (!battery || (count > sizeof(alarm_string) - 1)) 659 return -EINVAL; 660 661 mutex_lock(&battery->mutex); 662 663 result = acpi_battery_update(battery, 1, &update_result); 664 if (result) { 665 result = -ENODEV; 666 goto end; 667 } 668 669 if (!acpi_battery_present(battery)) { 670 result = -ENODEV; 671 goto end; 672 } 673 674 if (copy_from_user(alarm_string, buffer, count)) { 675 result = -EFAULT; 676 goto end; 677 } 678 679 alarm_string[count] = '\0'; 680 681 result = acpi_battery_set_alarm(battery, 682 simple_strtoul(alarm_string, NULL, 0)); 683 if (result) 684 goto end; 685 686 end: 687 688 acpi_battery_check_result(battery, result); 689 690 if (!result) 691 result = count; 692 693 mutex_unlock(&battery->mutex); 694 695 return result; 696 } 697 698 typedef int(*print_func)(struct seq_file *seq, int result); 699 typedef int(*get_func)(struct acpi_battery *battery); 700 701 static struct acpi_read_mux { 702 print_func print; 703 get_func get; 704 } acpi_read_funcs[ACPI_BATTERY_NUMFILES] = { 705 {.get = acpi_battery_get_info, .print = acpi_battery_print_info}, 706 {.get = acpi_battery_get_state, .print = acpi_battery_print_state}, 707 {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm}, 708 }; 709 710 static int acpi_battery_read(int fid, struct seq_file *seq) 711 { 712 struct acpi_battery *battery = seq->private; 713 int result = 0; 714 int update_result = ACPI_BATTERY_NONE_UPDATE; 715 int update = 0; 716 717 mutex_lock(&battery->mutex); 718 719 update = (get_seconds() - battery->update_time[fid] >= update_time); 720 update = (update | battery->flags.update[fid]); 721 722 result = acpi_battery_update(battery, update, &update_result); 723 if (result) 724 goto end; 725 726 if (update_result == ACPI_BATTERY_EASY_UPDATE) { 727 result = acpi_read_funcs[fid].get(battery); 728 if (result) 729 goto end; 730 } 731 732 end: 733 result = acpi_read_funcs[fid].print(seq, result); 734 acpi_battery_check_result(battery, result); 735 battery->flags.update[fid] = result; 736 mutex_unlock(&battery->mutex); 737 return result; 738 } 739 740 static int acpi_battery_read_info(struct seq_file *seq, void *offset) 741 { 742 return acpi_battery_read(ACPI_BATTERY_INFO, seq); 743 } 744 745 static int acpi_battery_read_state(struct seq_file *seq, void *offset) 746 { 747 return acpi_battery_read(ACPI_BATTERY_STATE, seq); 748 } 749 750 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 751 { 752 return acpi_battery_read(ACPI_BATTERY_ALARM, seq); 753 } 754 755 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) 756 { 757 return single_open(file, acpi_battery_read_info, PDE(inode)->data); 758 } 759 760 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) 761 { 762 return single_open(file, acpi_battery_read_state, PDE(inode)->data); 763 } 764 765 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) 766 { 767 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); 768 } 769 770 static struct battery_file { 771 struct file_operations ops; 772 mode_t mode; 773 char *name; 774 } acpi_battery_file[] = { 775 { 776 .name = "info", 777 .mode = S_IRUGO, 778 .ops = { 779 .open = acpi_battery_info_open_fs, 780 .read = seq_read, 781 .llseek = seq_lseek, 782 .release = single_release, 783 .owner = THIS_MODULE, 784 }, 785 }, 786 { 787 .name = "state", 788 .mode = S_IRUGO, 789 .ops = { 790 .open = acpi_battery_state_open_fs, 791 .read = seq_read, 792 .llseek = seq_lseek, 793 .release = single_release, 794 .owner = THIS_MODULE, 795 }, 796 }, 797 { 798 .name = "alarm", 799 .mode = S_IFREG | S_IRUGO | S_IWUSR, 800 .ops = { 801 .open = acpi_battery_alarm_open_fs, 802 .read = seq_read, 803 .write = acpi_battery_write_alarm, 804 .llseek = seq_lseek, 805 .release = single_release, 806 .owner = THIS_MODULE, 807 }, 808 }, 809 }; 810 811 static int acpi_battery_add_fs(struct acpi_device *device) 812 { 813 struct proc_dir_entry *entry = NULL; 814 int i; 815 816 if (!acpi_device_dir(device)) { 817 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 818 acpi_battery_dir); 819 if (!acpi_device_dir(device)) 820 return -ENODEV; 821 acpi_device_dir(device)->owner = THIS_MODULE; 822 } 823 824 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { 825 entry = create_proc_entry(acpi_battery_file[i].name, 826 acpi_battery_file[i].mode, acpi_device_dir(device)); 827 if (!entry) 828 return -ENODEV; 829 else { 830 entry->proc_fops = &acpi_battery_file[i].ops; 831 entry->data = acpi_driver_data(device); 832 entry->owner = THIS_MODULE; 833 } 834 } 835 836 return 0; 837 } 838 839 static int acpi_battery_remove_fs(struct acpi_device *device) 840 { 841 int i; 842 if (acpi_device_dir(device)) { 843 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { 844 remove_proc_entry(acpi_battery_file[i].name, 845 acpi_device_dir(device)); 846 } 847 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); 848 acpi_device_dir(device) = NULL; 849 } 850 851 return 0; 852 } 853 854 /* -------------------------------------------------------------------------- 855 Driver Interface 856 -------------------------------------------------------------------------- */ 857 858 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) 859 { 860 struct acpi_battery *battery = data; 861 struct acpi_device *device = NULL; 862 863 if (!battery) 864 return; 865 866 device = battery->device; 867 868 switch (event) { 869 case ACPI_BATTERY_NOTIFY_STATUS: 870 case ACPI_BATTERY_NOTIFY_INFO: 871 case ACPI_NOTIFY_BUS_CHECK: 872 case ACPI_NOTIFY_DEVICE_CHECK: 873 device = battery->device; 874 acpi_battery_notify_update(battery); 875 acpi_bus_generate_event(device, event, 876 acpi_battery_present(battery)); 877 break; 878 default: 879 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 880 "Unsupported event [0x%x]\n", event)); 881 break; 882 } 883 884 return; 885 } 886 887 static int acpi_battery_add(struct acpi_device *device) 888 { 889 int result = 0; 890 acpi_status status = 0; 891 struct acpi_battery *battery = NULL; 892 893 if (!device) 894 return -EINVAL; 895 896 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); 897 if (!battery) 898 return -ENOMEM; 899 900 mutex_init(&battery->mutex); 901 902 mutex_lock(&battery->mutex); 903 904 battery->device = device; 905 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 906 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 907 acpi_driver_data(device) = battery; 908 909 result = acpi_battery_get_status(battery); 910 if (result) 911 goto end; 912 913 battery->flags.init_update = 1; 914 915 result = acpi_battery_add_fs(device); 916 if (result) 917 goto end; 918 919 status = acpi_install_notify_handler(device->handle, 920 ACPI_ALL_NOTIFY, 921 acpi_battery_notify, battery); 922 if (ACPI_FAILURE(status)) { 923 ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); 924 result = -ENODEV; 925 goto end; 926 } 927 928 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", 929 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), 930 device->status.battery_present ? "present" : "absent"); 931 932 end: 933 934 if (result) { 935 acpi_battery_remove_fs(device); 936 kfree(battery); 937 } 938 939 mutex_unlock(&battery->mutex); 940 941 return result; 942 } 943 944 static int acpi_battery_remove(struct acpi_device *device, int type) 945 { 946 acpi_status status = 0; 947 struct acpi_battery *battery = NULL; 948 949 if (!device || !acpi_driver_data(device)) 950 return -EINVAL; 951 952 battery = acpi_driver_data(device); 953 954 mutex_lock(&battery->mutex); 955 956 status = acpi_remove_notify_handler(device->handle, 957 ACPI_ALL_NOTIFY, 958 acpi_battery_notify); 959 960 acpi_battery_remove_fs(device); 961 962 kfree(battery->bif_data.pointer); 963 964 kfree(battery->bst_data.pointer); 965 966 mutex_unlock(&battery->mutex); 967 968 mutex_destroy(&battery->mutex); 969 970 kfree(battery); 971 972 return 0; 973 } 974 975 /* this is needed to learn about changes made in suspended state */ 976 static int acpi_battery_resume(struct acpi_device *device) 977 { 978 struct acpi_battery *battery; 979 980 if (!device) 981 return -EINVAL; 982 983 battery = device->driver_data; 984 985 battery->flags.init_update = 1; 986 987 return 0; 988 } 989 990 static int __init acpi_battery_init(void) 991 { 992 int result; 993 994 if (acpi_disabled) 995 return -ENODEV; 996 997 acpi_battery_dir = acpi_lock_battery_dir(); 998 if (!acpi_battery_dir) 999 return -ENODEV; 1000 1001 result = acpi_bus_register_driver(&acpi_battery_driver); 1002 if (result < 0) { 1003 acpi_unlock_battery_dir(acpi_battery_dir); 1004 return -ENODEV; 1005 } 1006 1007 return 0; 1008 } 1009 1010 static void __exit acpi_battery_exit(void) 1011 { 1012 acpi_bus_unregister_driver(&acpi_battery_driver); 1013 1014 acpi_unlock_battery_dir(acpi_battery_dir); 1015 1016 return; 1017 } 1018 1019 module_init(acpi_battery_init); 1020 module_exit(acpi_battery_exit); 1021