diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/acpi/battery.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r-- | drivers/acpi/battery.c | 115 |
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 | ||
113 | struct acpi_battery { | 100 | struct 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 | ||
631 | static 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 | ||
702 | static int acpi_battery_update(struct acpi_battery *battery) | 616 | static int acpi_battery_update(struct acpi_battery *battery) |
@@ -729,19 +643,11 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
729 | 643 | ||
730 | static void acpi_battery_refresh(struct acpi_battery *battery) | 644 | static 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 | ||
968 | static const struct battery_file { | 874 | static 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 */ |
1134 | static int acpi_battery_resume(struct device *dev) | 1039 | static 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 | |||
1151 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); | ||
1152 | 1049 | ||
1153 | static struct acpi_driver acpi_battery_driver = { | 1050 | static 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 | ||
1166 | static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) | 1063 | static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) |