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.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index ac74a7ddaaa4..95649d373071 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -42,10 +42,7 @@
42 42
43#include <acpi/acpi_bus.h> 43#include <acpi/acpi_bus.h>
44#include <acpi/acpi_drivers.h> 44#include <acpi/acpi_drivers.h>
45
46#ifdef CONFIG_ACPI_SYSFS_POWER
47#include <linux/power_supply.h> 45#include <linux/power_supply.h>
48#endif
49 46
50#define PREFIX "ACPI: " 47#define PREFIX "ACPI: "
51 48
@@ -98,13 +95,12 @@ enum {
98 * due to bad math. 95 * due to bad math.
99 */ 96 */
100 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, 97 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
98 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
101}; 99};
102 100
103struct acpi_battery { 101struct acpi_battery {
104 struct mutex lock; 102 struct mutex lock;
105#ifdef CONFIG_ACPI_SYSFS_POWER
106 struct power_supply bat; 103 struct power_supply bat;
107#endif
108 struct acpi_device *device; 104 struct acpi_device *device;
109 unsigned long update_time; 105 unsigned long update_time;
110 int rate_now; 106 int rate_now;
@@ -141,7 +137,6 @@ inline int acpi_battery_present(struct acpi_battery *battery)
141 return battery->device->status.battery_present; 137 return battery->device->status.battery_present;
142} 138}
143 139
144#ifdef CONFIG_ACPI_SYSFS_POWER
145static int acpi_battery_technology(struct acpi_battery *battery) 140static int acpi_battery_technology(struct acpi_battery *battery)
146{ 141{
147 if (!strcasecmp("NiCd", battery->type)) 142 if (!strcasecmp("NiCd", battery->type))
@@ -300,7 +295,6 @@ static enum power_supply_property energy_battery_props[] = {
300 POWER_SUPPLY_PROP_MANUFACTURER, 295 POWER_SUPPLY_PROP_MANUFACTURER,
301 POWER_SUPPLY_PROP_SERIAL_NUMBER, 296 POWER_SUPPLY_PROP_SERIAL_NUMBER,
302}; 297};
303#endif
304 298
305#ifdef CONFIG_ACPI_PROCFS_POWER 299#ifdef CONFIG_ACPI_PROCFS_POWER
306inline char *acpi_battery_units(struct acpi_battery *battery) 300inline char *acpi_battery_units(struct acpi_battery *battery)
@@ -431,6 +425,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
431 result = extract_package(battery, buffer.pointer, 425 result = extract_package(battery, buffer.pointer,
432 info_offsets, ARRAY_SIZE(info_offsets)); 426 info_offsets, ARRAY_SIZE(info_offsets));
433 kfree(buffer.pointer); 427 kfree(buffer.pointer);
428 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
429 battery->full_charge_capacity = battery->design_capacity;
434 return result; 430 return result;
435} 431}
436 432
@@ -467,6 +463,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
467 battery->rate_now != -1) 463 battery->rate_now != -1)
468 battery->rate_now = abs((s16)battery->rate_now); 464 battery->rate_now = abs((s16)battery->rate_now);
469 465
466 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
467 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
468 battery->capacity_now = (battery->capacity_now *
469 battery->full_charge_capacity) / 100;
470 return result; 470 return result;
471} 471}
472 472
@@ -511,7 +511,6 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
511 return acpi_battery_set_alarm(battery); 511 return acpi_battery_set_alarm(battery);
512} 512}
513 513
514#ifdef CONFIG_ACPI_SYSFS_POWER
515static ssize_t acpi_battery_alarm_show(struct device *dev, 514static ssize_t acpi_battery_alarm_show(struct device *dev,
516 struct device_attribute *attr, 515 struct device_attribute *attr,
517 char *buf) 516 char *buf)
@@ -571,7 +570,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
571 power_supply_unregister(&battery->bat); 570 power_supply_unregister(&battery->bat);
572 battery->bat.dev = NULL; 571 battery->bat.dev = NULL;
573} 572}
574#endif
575 573
576static void acpi_battery_quirks(struct acpi_battery *battery) 574static void acpi_battery_quirks(struct acpi_battery *battery)
577{ 575{
@@ -580,6 +578,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
580 } 578 }
581} 579}
582 580
581/*
582 * According to the ACPI spec, some kinds of primary batteries can
583 * report percentage battery remaining capacity directly to OS.
584 * In this case, it reports the Last Full Charged Capacity == 100
585 * and BatteryPresentRate == 0xFFFFFFFF.
586 *
587 * Now we found some battery reports percentage remaining capacity
588 * even if it's rechargeable.
589 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
590 *
591 * Handle this correctly so that they won't break userspace.
592 */
593static void acpi_battery_quirks2(struct acpi_battery *battery)
594{
595 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
596 return ;
597
598 if (battery->full_charge_capacity == 100 &&
599 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
600 battery->capacity_now >=0 && battery->capacity_now <= 100) {
601 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
602 battery->full_charge_capacity = battery->design_capacity;
603 battery->capacity_now = (battery->capacity_now *
604 battery->full_charge_capacity) / 100;
605 }
606}
607
583static int acpi_battery_update(struct acpi_battery *battery) 608static int acpi_battery_update(struct acpi_battery *battery)
584{ 609{
585 int result, old_present = acpi_battery_present(battery); 610 int result, old_present = acpi_battery_present(battery);
@@ -587,9 +612,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
587 if (result) 612 if (result)
588 return result; 613 return result;
589 if (!acpi_battery_present(battery)) { 614 if (!acpi_battery_present(battery)) {
590#ifdef CONFIG_ACPI_SYSFS_POWER
591 sysfs_remove_battery(battery); 615 sysfs_remove_battery(battery);
592#endif
593 battery->update_time = 0; 616 battery->update_time = 0;
594 return 0; 617 return 0;
595 } 618 }
@@ -601,11 +624,11 @@ static int acpi_battery_update(struct acpi_battery *battery)
601 acpi_battery_quirks(battery); 624 acpi_battery_quirks(battery);
602 acpi_battery_init_alarm(battery); 625 acpi_battery_init_alarm(battery);
603 } 626 }
604#ifdef CONFIG_ACPI_SYSFS_POWER
605 if (!battery->bat.dev) 627 if (!battery->bat.dev)
606 sysfs_add_battery(battery); 628 sysfs_add_battery(battery);
607#endif 629 result = acpi_battery_get_state(battery);
608 return acpi_battery_get_state(battery); 630 acpi_battery_quirks2(battery);
631 return result;
609} 632}
610 633
611/* -------------------------------------------------------------------------- 634/* --------------------------------------------------------------------------
@@ -886,26 +909,20 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
886static void acpi_battery_notify(struct acpi_device *device, u32 event) 909static void acpi_battery_notify(struct acpi_device *device, u32 event)
887{ 910{
888 struct acpi_battery *battery = acpi_driver_data(device); 911 struct acpi_battery *battery = acpi_driver_data(device);
889#ifdef CONFIG_ACPI_SYSFS_POWER
890 struct device *old; 912 struct device *old;
891#endif
892 913
893 if (!battery) 914 if (!battery)
894 return; 915 return;
895#ifdef CONFIG_ACPI_SYSFS_POWER
896 old = battery->bat.dev; 916 old = battery->bat.dev;
897#endif
898 acpi_battery_update(battery); 917 acpi_battery_update(battery);
899 acpi_bus_generate_proc_event(device, event, 918 acpi_bus_generate_proc_event(device, event,
900 acpi_battery_present(battery)); 919 acpi_battery_present(battery));
901 acpi_bus_generate_netlink_event(device->pnp.device_class, 920 acpi_bus_generate_netlink_event(device->pnp.device_class,
902 dev_name(&device->dev), event, 921 dev_name(&device->dev), event,
903 acpi_battery_present(battery)); 922 acpi_battery_present(battery));
904#ifdef CONFIG_ACPI_SYSFS_POWER
905 /* acpi_battery_update could remove power_supply object */ 923 /* acpi_battery_update could remove power_supply object */
906 if (old && battery->bat.dev) 924 if (old && battery->bat.dev)
907 power_supply_changed(&battery->bat); 925 power_supply_changed(&battery->bat);
908#endif
909} 926}
910 927
911static int acpi_battery_add(struct acpi_device *device) 928static int acpi_battery_add(struct acpi_device *device)
@@ -953,9 +970,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
953#ifdef CONFIG_ACPI_PROCFS_POWER 970#ifdef CONFIG_ACPI_PROCFS_POWER
954 acpi_battery_remove_fs(device); 971 acpi_battery_remove_fs(device);
955#endif 972#endif
956#ifdef CONFIG_ACPI_SYSFS_POWER
957 sysfs_remove_battery(battery); 973 sysfs_remove_battery(battery);
958#endif
959 mutex_destroy(&battery->lock); 974 mutex_destroy(&battery->lock);
960 kfree(battery); 975 kfree(battery);
961 return 0; 976 return 0;