aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/acpi/battery.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c115
1 files changed, 6 insertions, 109 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 7efaeaa53b8..7711d94a040 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -34,7 +34,6 @@
34#include <linux/dmi.h> 34#include <linux/dmi.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/suspend.h> 36#include <linux/suspend.h>
37#include <asm/unaligned.h>
38 37
39#ifdef CONFIG_ACPI_PROCFS_POWER 38#ifdef CONFIG_ACPI_PROCFS_POWER
40#include <linux/proc_fs.h> 39#include <linux/proc_fs.h>
@@ -96,18 +95,6 @@ enum {
96 ACPI_BATTERY_ALARM_PRESENT, 95 ACPI_BATTERY_ALARM_PRESENT,
97 ACPI_BATTERY_XINFO_PRESENT, 96 ACPI_BATTERY_XINFO_PRESENT,
98 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, 97 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
99 /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
100 switches between mWh and mAh depending on whether the system
101 is running on battery or not. When mAh is the unit, most
102 reported values are incorrect and need to be adjusted by
103 10000/design_voltage. Verified on x201, t410, t410s, and x220.
104 Pre-2010 and 2012 models appear to always report in mWh and
105 are thus unaffected (tested with t42, t61, t500, x200, x300,
106 and x230). Also, in mid-2012 Lenovo issued a BIOS update for
107 the 2011 models that fixes the issue (tested on x220 with a
108 post-1.29 BIOS), but as of Nov. 2012, no such update is
109 available for the 2010 models. */
110 ACPI_BATTERY_QUIRK_THINKPAD_MAH,
111}; 98};
112 99
113struct acpi_battery { 100struct acpi_battery {
@@ -263,13 +250,6 @@ static int acpi_battery_get_property(struct power_supply *psy,
263 else 250 else
264 val->intval = battery->capacity_now * 1000; 251 val->intval = battery->capacity_now * 1000;
265 break; 252 break;
266 case POWER_SUPPLY_PROP_CAPACITY:
267 if (battery->capacity_now && battery->full_charge_capacity)
268 val->intval = battery->capacity_now * 100/
269 battery->full_charge_capacity;
270 else
271 val->intval = 0;
272 break;
273 case POWER_SUPPLY_PROP_MODEL_NAME: 253 case POWER_SUPPLY_PROP_MODEL_NAME:
274 val->strval = battery->model_number; 254 val->strval = battery->model_number;
275 break; 255 break;
@@ -296,7 +276,6 @@ static enum power_supply_property charge_battery_props[] = {
296 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 276 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
297 POWER_SUPPLY_PROP_CHARGE_FULL, 277 POWER_SUPPLY_PROP_CHARGE_FULL,
298 POWER_SUPPLY_PROP_CHARGE_NOW, 278 POWER_SUPPLY_PROP_CHARGE_NOW,
299 POWER_SUPPLY_PROP_CAPACITY,
300 POWER_SUPPLY_PROP_MODEL_NAME, 279 POWER_SUPPLY_PROP_MODEL_NAME,
301 POWER_SUPPLY_PROP_MANUFACTURER, 280 POWER_SUPPLY_PROP_MANUFACTURER,
302 POWER_SUPPLY_PROP_SERIAL_NUMBER, 281 POWER_SUPPLY_PROP_SERIAL_NUMBER,
@@ -313,7 +292,6 @@ static enum power_supply_property energy_battery_props[] = {
313 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 292 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
314 POWER_SUPPLY_PROP_ENERGY_FULL, 293 POWER_SUPPLY_PROP_ENERGY_FULL,
315 POWER_SUPPLY_PROP_ENERGY_NOW, 294 POWER_SUPPLY_PROP_ENERGY_NOW,
316 POWER_SUPPLY_PROP_CAPACITY,
317 POWER_SUPPLY_PROP_MODEL_NAME, 295 POWER_SUPPLY_PROP_MODEL_NAME,
318 POWER_SUPPLY_PROP_MANUFACTURER, 296 POWER_SUPPLY_PROP_MANUFACTURER,
319 POWER_SUPPLY_PROP_SERIAL_NUMBER, 297 POWER_SUPPLY_PROP_SERIAL_NUMBER,
@@ -451,21 +429,6 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
451 kfree(buffer.pointer); 429 kfree(buffer.pointer);
452 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) 430 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
453 battery->full_charge_capacity = battery->design_capacity; 431 battery->full_charge_capacity = battery->design_capacity;
454 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
455 battery->power_unit && battery->design_voltage) {
456 battery->design_capacity = battery->design_capacity *
457 10000 / battery->design_voltage;
458 battery->full_charge_capacity = battery->full_charge_capacity *
459 10000 / battery->design_voltage;
460 battery->design_capacity_warning =
461 battery->design_capacity_warning *
462 10000 / battery->design_voltage;
463 /* Curiously, design_capacity_low, unlike the rest of them,
464 is correct. */
465 /* capacity_granularity_* equal 1 on the systems tested, so
466 it's impossible to tell if they would need an adjustment
467 or not if their values were higher. */
468 }
469 return result; 432 return result;
470} 433}
471 434
@@ -514,11 +477,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
514 && battery->capacity_now >= 0 && battery->capacity_now <= 100) 477 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
515 battery->capacity_now = (battery->capacity_now * 478 battery->capacity_now = (battery->capacity_now *
516 battery->full_charge_capacity) / 100; 479 battery->full_charge_capacity) / 100;
517 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
518 battery->power_unit && battery->design_voltage) {
519 battery->capacity_now = battery->capacity_now *
520 10000 / battery->design_voltage;
521 }
522 return result; 480 return result;
523} 481}
524 482
@@ -628,24 +586,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
628 mutex_unlock(&battery->sysfs_lock); 586 mutex_unlock(&battery->sysfs_lock);
629} 587}
630 588
631static void find_battery(const struct dmi_header *dm, void *private)
632{
633 struct acpi_battery *battery = (struct acpi_battery *)private;
634 /* Note: the hardcoded offsets below have been extracted from
635 the source code of dmidecode. */
636 if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
637 const u8 *dmi_data = (const u8 *)(dm + 1);
638 int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
639 if (dm->length >= 18)
640 dmi_capacity *= dmi_data[17];
641 if (battery->design_capacity * battery->design_voltage / 1000
642 != dmi_capacity &&
643 battery->design_capacity * 10 == dmi_capacity)
644 set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
645 &battery->flags);
646 }
647}
648
649/* 589/*
650 * According to the ACPI spec, some kinds of primary batteries can 590 * According to the ACPI spec, some kinds of primary batteries can
651 * report percentage battery remaining capacity directly to OS. 591 * report percentage battery remaining capacity directly to OS.
@@ -671,32 +611,6 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
671 battery->capacity_now = (battery->capacity_now * 611 battery->capacity_now = (battery->capacity_now *
672 battery->full_charge_capacity) / 100; 612 battery->full_charge_capacity) / 100;
673 } 613 }
674
675 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
676 return ;
677
678 if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
679 const char *s;
680 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
681 if (s && !strnicmp(s, "ThinkPad", 8)) {
682 dmi_walk(find_battery, battery);
683 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
684 &battery->flags) &&
685 battery->design_voltage) {
686 battery->design_capacity =
687 battery->design_capacity *
688 10000 / battery->design_voltage;
689 battery->full_charge_capacity =
690 battery->full_charge_capacity *
691 10000 / battery->design_voltage;
692 battery->design_capacity_warning =
693 battery->design_capacity_warning *
694 10000 / battery->design_voltage;
695 battery->capacity_now = battery->capacity_now *
696 10000 / battery->design_voltage;
697 }
698 }
699 }
700} 614}
701 615
702static int acpi_battery_update(struct acpi_battery *battery) 616static int acpi_battery_update(struct acpi_battery *battery)
@@ -729,19 +643,11 @@ static int acpi_battery_update(struct acpi_battery *battery)
729 643
730static void acpi_battery_refresh(struct acpi_battery *battery) 644static void acpi_battery_refresh(struct acpi_battery *battery)
731{ 645{
732 int power_unit;
733
734 if (!battery->bat.dev) 646 if (!battery->bat.dev)
735 return; 647 return;
736 648
737 power_unit = battery->power_unit;
738
739 acpi_battery_get_info(battery); 649 acpi_battery_get_info(battery);
740 650 /* The battery may have changed its reporting units. */
741 if (power_unit == battery->power_unit)
742 return;
743
744 /* The battery has changed its reporting units. */
745 sysfs_remove_battery(battery); 651 sysfs_remove_battery(battery);
746 sysfs_add_battery(battery); 652 sysfs_add_battery(battery);
747} 653}
@@ -967,7 +873,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
967 873
968static const struct battery_file { 874static const struct battery_file {
969 struct file_operations ops; 875 struct file_operations ops;
970 umode_t mode; 876 mode_t mode;
971 const char *name; 877 const char *name;
972} acpi_battery_file[] = { 878} acpi_battery_file[] = {
973 FILE_DESCRIPTION_RO(info), 879 FILE_DESCRIPTION_RO(info),
@@ -1129,26 +1035,17 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
1129 return 0; 1035 return 0;
1130} 1036}
1131 1037
1132#ifdef CONFIG_PM_SLEEP
1133/* this is needed to learn about changes made in suspended state */ 1038/* this is needed to learn about changes made in suspended state */
1134static int acpi_battery_resume(struct device *dev) 1039static int acpi_battery_resume(struct acpi_device *device)
1135{ 1040{
1136 struct acpi_battery *battery; 1041 struct acpi_battery *battery;
1137 1042 if (!device)
1138 if (!dev)
1139 return -EINVAL;
1140
1141 battery = acpi_driver_data(to_acpi_device(dev));
1142 if (!battery)
1143 return -EINVAL; 1043 return -EINVAL;
1144 1044 battery = acpi_driver_data(device);
1145 battery->update_time = 0; 1045 battery->update_time = 0;
1146 acpi_battery_update(battery); 1046 acpi_battery_update(battery);
1147 return 0; 1047 return 0;
1148} 1048}
1149#endif
1150
1151static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
1152 1049
1153static struct acpi_driver acpi_battery_driver = { 1050static struct acpi_driver acpi_battery_driver = {
1154 .name = "battery", 1051 .name = "battery",
@@ -1157,10 +1054,10 @@ static struct acpi_driver acpi_battery_driver = {
1157 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, 1054 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1158 .ops = { 1055 .ops = {
1159 .add = acpi_battery_add, 1056 .add = acpi_battery_add,
1057 .resume = acpi_battery_resume,
1160 .remove = acpi_battery_remove, 1058 .remove = acpi_battery_remove,
1161 .notify = acpi_battery_notify, 1059 .notify = acpi_battery_notify,
1162 }, 1060 },
1163 .drv.pm = &acpi_battery_pm,
1164}; 1061};
1165 1062
1166static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) 1063static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)