aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c86
1 files changed, 54 insertions, 32 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 2c661353e8f2..7711d94a0409 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -55,6 +55,9 @@
55#define ACPI_BATTERY_NOTIFY_INFO 0x81 55#define ACPI_BATTERY_NOTIFY_INFO 0x81
56#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 56#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
57 57
58/* Battery power unit: 0 means mW, 1 means mA */
59#define ACPI_BATTERY_POWER_UNIT_MA 1
60
58#define _COMPONENT ACPI_BATTERY_COMPONENT 61#define _COMPONENT ACPI_BATTERY_COMPONENT
59 62
60ACPI_MODULE_NAME("battery"); 63ACPI_MODULE_NAME("battery");
@@ -91,16 +94,12 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids);
91enum { 94enum {
92 ACPI_BATTERY_ALARM_PRESENT, 95 ACPI_BATTERY_ALARM_PRESENT,
93 ACPI_BATTERY_XINFO_PRESENT, 96 ACPI_BATTERY_XINFO_PRESENT,
94 /* For buggy DSDTs that report negative 16-bit values for either
95 * charging or discharging current and/or report 0 as 65536
96 * due to bad math.
97 */
98 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
99 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, 97 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
100}; 98};
101 99
102struct acpi_battery { 100struct acpi_battery {
103 struct mutex lock; 101 struct mutex lock;
102 struct mutex sysfs_lock;
104 struct power_supply bat; 103 struct power_supply bat;
105 struct acpi_device *device; 104 struct acpi_device *device;
106 struct notifier_block pm_nb; 105 struct notifier_block pm_nb;
@@ -301,7 +300,8 @@ static enum power_supply_property energy_battery_props[] = {
301#ifdef CONFIG_ACPI_PROCFS_POWER 300#ifdef CONFIG_ACPI_PROCFS_POWER
302inline char *acpi_battery_units(struct acpi_battery *battery) 301inline char *acpi_battery_units(struct acpi_battery *battery)
303{ 302{
304 return (battery->power_unit)?"mA":"mW"; 303 return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
304 "mA" : "mW";
305} 305}
306#endif 306#endif
307 307
@@ -461,9 +461,17 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
461 battery->update_time = jiffies; 461 battery->update_time = jiffies;
462 kfree(buffer.pointer); 462 kfree(buffer.pointer);
463 463
464 if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) && 464 /* For buggy DSDTs that report negative 16-bit values for either
465 battery->rate_now != -1) 465 * charging or discharging current and/or report 0 as 65536
466 * due to bad math.
467 */
468 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
469 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
470 (s16)(battery->rate_now) < 0) {
466 battery->rate_now = abs((s16)battery->rate_now); 471 battery->rate_now = abs((s16)battery->rate_now);
472 printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate"
473 " invalid.\n");
474 }
467 475
468 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) 476 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
469 && battery->capacity_now >= 0 && battery->capacity_now <= 100) 477 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
@@ -544,7 +552,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
544{ 552{
545 int result; 553 int result;
546 554
547 if (battery->power_unit) { 555 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
548 battery->bat.properties = charge_battery_props; 556 battery->bat.properties = charge_battery_props;
549 battery->bat.num_properties = 557 battery->bat.num_properties =
550 ARRAY_SIZE(charge_battery_props); 558 ARRAY_SIZE(charge_battery_props);
@@ -566,18 +574,16 @@ static int sysfs_add_battery(struct acpi_battery *battery)
566 574
567static void sysfs_remove_battery(struct acpi_battery *battery) 575static void sysfs_remove_battery(struct acpi_battery *battery)
568{ 576{
569 if (!battery->bat.dev) 577 mutex_lock(&battery->sysfs_lock);
578 if (!battery->bat.dev) {
579 mutex_unlock(&battery->sysfs_lock);
570 return; 580 return;
581 }
582
571 device_remove_file(battery->bat.dev, &alarm_attr); 583 device_remove_file(battery->bat.dev, &alarm_attr);
572 power_supply_unregister(&battery->bat); 584 power_supply_unregister(&battery->bat);
573 battery->bat.dev = NULL; 585 battery->bat.dev = NULL;
574} 586 mutex_unlock(&battery->sysfs_lock);
575
576static void acpi_battery_quirks(struct acpi_battery *battery)
577{
578 if (dmi_name_in_vendors("Acer") && battery->power_unit) {
579 set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags);
580 }
581} 587}
582 588
583/* 589/*
@@ -592,7 +598,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
592 * 598 *
593 * Handle this correctly so that they won't break userspace. 599 * Handle this correctly so that they won't break userspace.
594 */ 600 */
595static void acpi_battery_quirks2(struct acpi_battery *battery) 601static void acpi_battery_quirks(struct acpi_battery *battery)
596{ 602{
597 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) 603 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
598 return ; 604 return ;
@@ -623,13 +629,15 @@ static int acpi_battery_update(struct acpi_battery *battery)
623 result = acpi_battery_get_info(battery); 629 result = acpi_battery_get_info(battery);
624 if (result) 630 if (result)
625 return result; 631 return result;
626 acpi_battery_quirks(battery);
627 acpi_battery_init_alarm(battery); 632 acpi_battery_init_alarm(battery);
628 } 633 }
629 if (!battery->bat.dev) 634 if (!battery->bat.dev) {
630 sysfs_add_battery(battery); 635 result = sysfs_add_battery(battery);
636 if (result)
637 return result;
638 }
631 result = acpi_battery_get_state(battery); 639 result = acpi_battery_get_state(battery);
632 acpi_battery_quirks2(battery); 640 acpi_battery_quirks(battery);
633 return result; 641 return result;
634} 642}
635 643
@@ -863,7 +871,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
863 }, \ 871 }, \
864 } 872 }
865 873
866static struct battery_file { 874static const struct battery_file {
867 struct file_operations ops; 875 struct file_operations ops;
868 mode_t mode; 876 mode_t mode;
869 const char *name; 877 const char *name;
@@ -948,9 +956,12 @@ static int battery_notify(struct notifier_block *nb,
948 struct acpi_battery *battery = container_of(nb, struct acpi_battery, 956 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
949 pm_nb); 957 pm_nb);
950 switch (mode) { 958 switch (mode) {
959 case PM_POST_HIBERNATION:
951 case PM_POST_SUSPEND: 960 case PM_POST_SUSPEND:
952 sysfs_remove_battery(battery); 961 if (battery->bat.dev) {
953 sysfs_add_battery(battery); 962 sysfs_remove_battery(battery);
963 sysfs_add_battery(battery);
964 }
954 break; 965 break;
955 } 966 }
956 967
@@ -972,28 +983,38 @@ static int acpi_battery_add(struct acpi_device *device)
972 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 983 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
973 device->driver_data = battery; 984 device->driver_data = battery;
974 mutex_init(&battery->lock); 985 mutex_init(&battery->lock);
986 mutex_init(&battery->sysfs_lock);
975 if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, 987 if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
976 "_BIX", &handle))) 988 "_BIX", &handle)))
977 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); 989 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
978 acpi_battery_update(battery); 990 result = acpi_battery_update(battery);
991 if (result)
992 goto fail;
979#ifdef CONFIG_ACPI_PROCFS_POWER 993#ifdef CONFIG_ACPI_PROCFS_POWER
980 result = acpi_battery_add_fs(device); 994 result = acpi_battery_add_fs(device);
981#endif 995#endif
982 if (!result) { 996 if (result) {
983 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
984 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
985 device->status.battery_present ? "present" : "absent");
986 } else {
987#ifdef CONFIG_ACPI_PROCFS_POWER 997#ifdef CONFIG_ACPI_PROCFS_POWER
988 acpi_battery_remove_fs(device); 998 acpi_battery_remove_fs(device);
989#endif 999#endif
990 kfree(battery); 1000 goto fail;
991 } 1001 }
992 1002
1003 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
1004 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1005 device->status.battery_present ? "present" : "absent");
1006
993 battery->pm_nb.notifier_call = battery_notify; 1007 battery->pm_nb.notifier_call = battery_notify;
994 register_pm_notifier(&battery->pm_nb); 1008 register_pm_notifier(&battery->pm_nb);
995 1009
996 return result; 1010 return result;
1011
1012fail:
1013 sysfs_remove_battery(battery);
1014 mutex_destroy(&battery->lock);
1015 mutex_destroy(&battery->sysfs_lock);
1016 kfree(battery);
1017 return result;
997} 1018}
998 1019
999static int acpi_battery_remove(struct acpi_device *device, int type) 1020static int acpi_battery_remove(struct acpi_device *device, int type)
@@ -1009,6 +1030,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
1009#endif 1030#endif
1010 sysfs_remove_battery(battery); 1031 sysfs_remove_battery(battery);
1011 mutex_destroy(&battery->lock); 1032 mutex_destroy(&battery->lock);
1033 mutex_destroy(&battery->sysfs_lock);
1012 kfree(battery); 1034 kfree(battery);
1013 return 0; 1035 return 0;
1014} 1036}