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.c95
1 files changed, 64 insertions, 31 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index dc58402b0a1..95649d37307 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))
@@ -186,6 +181,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
186 enum power_supply_property psp, 181 enum power_supply_property psp,
187 union power_supply_propval *val) 182 union power_supply_propval *val)
188{ 183{
184 int ret = 0;
189 struct acpi_battery *battery = to_acpi_battery(psy); 185 struct acpi_battery *battery = to_acpi_battery(psy);
190 186
191 if (acpi_battery_present(battery)) { 187 if (acpi_battery_present(battery)) {
@@ -214,26 +210,44 @@ static int acpi_battery_get_property(struct power_supply *psy,
214 val->intval = battery->cycle_count; 210 val->intval = battery->cycle_count;
215 break; 211 break;
216 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 212 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
217 val->intval = battery->design_voltage * 1000; 213 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
214 ret = -ENODEV;
215 else
216 val->intval = battery->design_voltage * 1000;
218 break; 217 break;
219 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 218 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
220 val->intval = battery->voltage_now * 1000; 219 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
220 ret = -ENODEV;
221 else
222 val->intval = battery->voltage_now * 1000;
221 break; 223 break;
222 case POWER_SUPPLY_PROP_CURRENT_NOW: 224 case POWER_SUPPLY_PROP_CURRENT_NOW:
223 case POWER_SUPPLY_PROP_POWER_NOW: 225 case POWER_SUPPLY_PROP_POWER_NOW:
224 val->intval = battery->rate_now * 1000; 226 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
227 ret = -ENODEV;
228 else
229 val->intval = battery->rate_now * 1000;
225 break; 230 break;
226 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 231 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
227 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 232 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
228 val->intval = battery->design_capacity * 1000; 233 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
234 ret = -ENODEV;
235 else
236 val->intval = battery->design_capacity * 1000;
229 break; 237 break;
230 case POWER_SUPPLY_PROP_CHARGE_FULL: 238 case POWER_SUPPLY_PROP_CHARGE_FULL:
231 case POWER_SUPPLY_PROP_ENERGY_FULL: 239 case POWER_SUPPLY_PROP_ENERGY_FULL:
232 val->intval = battery->full_charge_capacity * 1000; 240 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
241 ret = -ENODEV;
242 else
243 val->intval = battery->full_charge_capacity * 1000;
233 break; 244 break;
234 case POWER_SUPPLY_PROP_CHARGE_NOW: 245 case POWER_SUPPLY_PROP_CHARGE_NOW:
235 case POWER_SUPPLY_PROP_ENERGY_NOW: 246 case POWER_SUPPLY_PROP_ENERGY_NOW:
236 val->intval = battery->capacity_now * 1000; 247 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
248 ret = -ENODEV;
249 else
250 val->intval = battery->capacity_now * 1000;
237 break; 251 break;
238 case POWER_SUPPLY_PROP_MODEL_NAME: 252 case POWER_SUPPLY_PROP_MODEL_NAME:
239 val->strval = battery->model_number; 253 val->strval = battery->model_number;
@@ -245,9 +259,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
245 val->strval = battery->serial_number; 259 val->strval = battery->serial_number;
246 break; 260 break;
247 default: 261 default:
248 return -EINVAL; 262 ret = -EINVAL;
249 } 263 }
250 return 0; 264 return ret;
251} 265}
252 266
253static enum power_supply_property charge_battery_props[] = { 267static enum power_supply_property charge_battery_props[] = {
@@ -273,7 +287,6 @@ static enum power_supply_property energy_battery_props[] = {
273 POWER_SUPPLY_PROP_CYCLE_COUNT, 287 POWER_SUPPLY_PROP_CYCLE_COUNT,
274 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 288 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
275 POWER_SUPPLY_PROP_VOLTAGE_NOW, 289 POWER_SUPPLY_PROP_VOLTAGE_NOW,
276 POWER_SUPPLY_PROP_CURRENT_NOW,
277 POWER_SUPPLY_PROP_POWER_NOW, 290 POWER_SUPPLY_PROP_POWER_NOW,
278 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 291 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
279 POWER_SUPPLY_PROP_ENERGY_FULL, 292 POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -282,7 +295,6 @@ static enum power_supply_property energy_battery_props[] = {
282 POWER_SUPPLY_PROP_MANUFACTURER, 295 POWER_SUPPLY_PROP_MANUFACTURER,
283 POWER_SUPPLY_PROP_SERIAL_NUMBER, 296 POWER_SUPPLY_PROP_SERIAL_NUMBER,
284}; 297};
285#endif
286 298
287#ifdef CONFIG_ACPI_PROCFS_POWER 299#ifdef CONFIG_ACPI_PROCFS_POWER
288inline char *acpi_battery_units(struct acpi_battery *battery) 300inline char *acpi_battery_units(struct acpi_battery *battery)
@@ -413,6 +425,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
413 result = extract_package(battery, buffer.pointer, 425 result = extract_package(battery, buffer.pointer,
414 info_offsets, ARRAY_SIZE(info_offsets)); 426 info_offsets, ARRAY_SIZE(info_offsets));
415 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;
416 return result; 430 return result;
417} 431}
418 432
@@ -449,6 +463,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
449 battery->rate_now != -1) 463 battery->rate_now != -1)
450 battery->rate_now = abs((s16)battery->rate_now); 464 battery->rate_now = abs((s16)battery->rate_now);
451 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;
452 return result; 470 return result;
453} 471}
454 472
@@ -493,7 +511,6 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
493 return acpi_battery_set_alarm(battery); 511 return acpi_battery_set_alarm(battery);
494} 512}
495 513
496#ifdef CONFIG_ACPI_SYSFS_POWER
497static ssize_t acpi_battery_alarm_show(struct device *dev, 514static ssize_t acpi_battery_alarm_show(struct device *dev,
498 struct device_attribute *attr, 515 struct device_attribute *attr,
499 char *buf) 516 char *buf)
@@ -553,7 +570,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
553 power_supply_unregister(&battery->bat); 570 power_supply_unregister(&battery->bat);
554 battery->bat.dev = NULL; 571 battery->bat.dev = NULL;
555} 572}
556#endif
557 573
558static void acpi_battery_quirks(struct acpi_battery *battery) 574static void acpi_battery_quirks(struct acpi_battery *battery)
559{ 575{
@@ -562,6 +578,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
562 } 578 }
563} 579}
564 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
565static int acpi_battery_update(struct acpi_battery *battery) 608static int acpi_battery_update(struct acpi_battery *battery)
566{ 609{
567 int result, old_present = acpi_battery_present(battery); 610 int result, old_present = acpi_battery_present(battery);
@@ -569,9 +612,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
569 if (result) 612 if (result)
570 return result; 613 return result;
571 if (!acpi_battery_present(battery)) { 614 if (!acpi_battery_present(battery)) {
572#ifdef CONFIG_ACPI_SYSFS_POWER
573 sysfs_remove_battery(battery); 615 sysfs_remove_battery(battery);
574#endif
575 battery->update_time = 0; 616 battery->update_time = 0;
576 return 0; 617 return 0;
577 } 618 }
@@ -583,11 +624,11 @@ static int acpi_battery_update(struct acpi_battery *battery)
583 acpi_battery_quirks(battery); 624 acpi_battery_quirks(battery);
584 acpi_battery_init_alarm(battery); 625 acpi_battery_init_alarm(battery);
585 } 626 }
586#ifdef CONFIG_ACPI_SYSFS_POWER
587 if (!battery->bat.dev) 627 if (!battery->bat.dev)
588 sysfs_add_battery(battery); 628 sysfs_add_battery(battery);
589#endif 629 result = acpi_battery_get_state(battery);
590 return acpi_battery_get_state(battery); 630 acpi_battery_quirks2(battery);
631 return result;
591} 632}
592 633
593/* -------------------------------------------------------------------------- 634/* --------------------------------------------------------------------------
@@ -868,26 +909,20 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
868static void acpi_battery_notify(struct acpi_device *device, u32 event) 909static void acpi_battery_notify(struct acpi_device *device, u32 event)
869{ 910{
870 struct acpi_battery *battery = acpi_driver_data(device); 911 struct acpi_battery *battery = acpi_driver_data(device);
871#ifdef CONFIG_ACPI_SYSFS_POWER
872 struct device *old; 912 struct device *old;
873#endif
874 913
875 if (!battery) 914 if (!battery)
876 return; 915 return;
877#ifdef CONFIG_ACPI_SYSFS_POWER
878 old = battery->bat.dev; 916 old = battery->bat.dev;
879#endif
880 acpi_battery_update(battery); 917 acpi_battery_update(battery);
881 acpi_bus_generate_proc_event(device, event, 918 acpi_bus_generate_proc_event(device, event,
882 acpi_battery_present(battery)); 919 acpi_battery_present(battery));
883 acpi_bus_generate_netlink_event(device->pnp.device_class, 920 acpi_bus_generate_netlink_event(device->pnp.device_class,
884 dev_name(&device->dev), event, 921 dev_name(&device->dev), event,
885 acpi_battery_present(battery)); 922 acpi_battery_present(battery));
886#ifdef CONFIG_ACPI_SYSFS_POWER
887 /* acpi_battery_update could remove power_supply object */ 923 /* acpi_battery_update could remove power_supply object */
888 if (old && battery->bat.dev) 924 if (old && battery->bat.dev)
889 power_supply_changed(&battery->bat); 925 power_supply_changed(&battery->bat);
890#endif
891} 926}
892 927
893static int acpi_battery_add(struct acpi_device *device) 928static int acpi_battery_add(struct acpi_device *device)
@@ -935,9 +970,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
935#ifdef CONFIG_ACPI_PROCFS_POWER 970#ifdef CONFIG_ACPI_PROCFS_POWER
936 acpi_battery_remove_fs(device); 971 acpi_battery_remove_fs(device);
937#endif 972#endif
938#ifdef CONFIG_ACPI_SYSFS_POWER
939 sysfs_remove_battery(battery); 973 sysfs_remove_battery(battery);
940#endif
941 mutex_destroy(&battery->lock); 974 mutex_destroy(&battery->lock);
942 kfree(battery); 975 kfree(battery);
943 return 0; 976 return 0;