aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2014-05-04 02:07:06 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-16 10:34:17 -0400
commit9e50bc14a7f58b5d8a55973b2d69355852ae2dae (patch)
tree446e2a10b2c6a1420914f69cd44ec8de2a55fd9f /drivers/acpi/battery.c
parent054c1c45395175ad057487d456668b83d51856ec (diff)
ACPI / battery: Accelerate battery resume callback
Most time of battery resume callback is spent on executing AML code _BTP, _BIF and _BIF to get battery info, status and set alarm. These AML methods may access EC operation regions several times and consumes time. These operations are not necessary during devices resume and can run during POST_SUSPEND/HIBERNATION event when all processes are thawed. This also can avoid removing and adding battery sysfs nodes every system resume even if the battery unit is not actually changed. The original code updates sysfs nodes without check and this seems not reasonable. Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 6e7b2a12860d..3b4921e4dc4e 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -696,7 +696,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
696 } 696 }
697} 697}
698 698
699static int acpi_battery_update(struct acpi_battery *battery) 699static int acpi_battery_update(struct acpi_battery *battery, bool resume)
700{ 700{
701 int result, old_present = acpi_battery_present(battery); 701 int result, old_present = acpi_battery_present(battery);
702 result = acpi_battery_get_status(battery); 702 result = acpi_battery_get_status(battery);
@@ -707,6 +707,10 @@ static int acpi_battery_update(struct acpi_battery *battery)
707 battery->update_time = 0; 707 battery->update_time = 0;
708 return 0; 708 return 0;
709 } 709 }
710
711 if (resume)
712 return 0;
713
710 if (!battery->update_time || 714 if (!battery->update_time ||
711 old_present != acpi_battery_present(battery)) { 715 old_present != acpi_battery_present(battery)) {
712 result = acpi_battery_get_info(battery); 716 result = acpi_battery_get_info(battery);
@@ -915,7 +919,7 @@ static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
915static int acpi_battery_read(int fid, struct seq_file *seq) 919static int acpi_battery_read(int fid, struct seq_file *seq)
916{ 920{
917 struct acpi_battery *battery = seq->private; 921 struct acpi_battery *battery = seq->private;
918 int result = acpi_battery_update(battery); 922 int result = acpi_battery_update(battery, false);
919 return acpi_print_funcs[fid](seq, result); 923 return acpi_print_funcs[fid](seq, result);
920} 924}
921 925
@@ -1030,7 +1034,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
1030 old = battery->bat.dev; 1034 old = battery->bat.dev;
1031 if (event == ACPI_BATTERY_NOTIFY_INFO) 1035 if (event == ACPI_BATTERY_NOTIFY_INFO)
1032 acpi_battery_refresh(battery); 1036 acpi_battery_refresh(battery);
1033 acpi_battery_update(battery); 1037 acpi_battery_update(battery, false);
1034 acpi_bus_generate_netlink_event(device->pnp.device_class, 1038 acpi_bus_generate_netlink_event(device->pnp.device_class,
1035 dev_name(&device->dev), event, 1039 dev_name(&device->dev), event,
1036 acpi_battery_present(battery)); 1040 acpi_battery_present(battery));
@@ -1045,13 +1049,27 @@ static int battery_notify(struct notifier_block *nb,
1045{ 1049{
1046 struct acpi_battery *battery = container_of(nb, struct acpi_battery, 1050 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
1047 pm_nb); 1051 pm_nb);
1052 int result;
1053
1048 switch (mode) { 1054 switch (mode) {
1049 case PM_POST_HIBERNATION: 1055 case PM_POST_HIBERNATION:
1050 case PM_POST_SUSPEND: 1056 case PM_POST_SUSPEND:
1051 if (battery->bat.dev) { 1057 if (!acpi_battery_present(battery))
1052 sysfs_remove_battery(battery); 1058 return 0;
1053 sysfs_add_battery(battery); 1059
1054 } 1060 if (!battery->bat.dev) {
1061 result = acpi_battery_get_info(battery);
1062 if (result)
1063 return result;
1064
1065 result = sysfs_add_battery(battery);
1066 if (result)
1067 return result;
1068 } else
1069 acpi_battery_refresh(battery);
1070
1071 acpi_battery_init_alarm(battery);
1072 acpi_battery_get_state(battery);
1055 break; 1073 break;
1056 } 1074 }
1057 1075
@@ -1087,7 +1105,7 @@ static int acpi_battery_add(struct acpi_device *device)
1087 mutex_init(&battery->sysfs_lock); 1105 mutex_init(&battery->sysfs_lock);
1088 if (acpi_has_method(battery->device->handle, "_BIX")) 1106 if (acpi_has_method(battery->device->handle, "_BIX"))
1089 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); 1107 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
1090 result = acpi_battery_update(battery); 1108 result = acpi_battery_update(battery, false);
1091 if (result) 1109 if (result)
1092 goto fail; 1110 goto fail;
1093#ifdef CONFIG_ACPI_PROCFS_POWER 1111#ifdef CONFIG_ACPI_PROCFS_POWER
@@ -1149,7 +1167,7 @@ static int acpi_battery_resume(struct device *dev)
1149 return -EINVAL; 1167 return -EINVAL;
1150 1168
1151 battery->update_time = 0; 1169 battery->update_time = 0;
1152 acpi_battery_update(battery); 1170 acpi_battery_update(battery, true);
1153 return 0; 1171 return 0;
1154} 1172}
1155#else 1173#else