aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2014-05-28 03:23:38 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-30 07:45:25 -0400
commite0d1f09e311fafa33b4bfd942c852671ce25ae58 (patch)
tree8616a1b7cdff33967a4a55e90b83ecce764f9735
parent9113e260767b1cb44f8da0e5922e1a9a5417c4b8 (diff)
ACPI / battery: wakeup the system only when necessary
ACPI Battery device receives notifications from firmware frequently, and most of these notifications are some general events, like battery remaining capacity change, etc, which should not wake the system up if the system is in suspend/hibernate state. This causes a problem that the system wakes up from suspend to freeze shortly, because there is an ACPI battery notification every 10 seconds. Fix the problem in this patch by registering ACPI battery device' own wakeup source, and waking up the system only when the battery remaining capacity is critical low, or lower than the alarm capacity set via _BTP. Link: https://bugzilla.kernel.org/show_bug.cgi?id=76221 Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/battery.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 11285e7df278..e48fc98e71c4 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -622,7 +622,8 @@ static int sysfs_add_battery(struct acpi_battery *battery)
622 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; 622 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
623 battery->bat.get_property = acpi_battery_get_property; 623 battery->bat.get_property = acpi_battery_get_property;
624 624
625 result = power_supply_register(&battery->device->dev, &battery->bat); 625 result = power_supply_register_no_ws(&battery->device->dev, &battery->bat);
626
626 if (result) 627 if (result)
627 return result; 628 return result;
628 return device_create_file(battery->bat.dev, &alarm_attr); 629 return device_create_file(battery->bat.dev, &alarm_attr);
@@ -741,7 +742,19 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume)
741 return result; 742 return result;
742 } 743 }
743 result = acpi_battery_get_state(battery); 744 result = acpi_battery_get_state(battery);
745 if (result)
746 return result;
744 acpi_battery_quirks(battery); 747 acpi_battery_quirks(battery);
748
749 /*
750 * Wakeup the system if battery is critical low
751 * or lower than the alarm level
752 */
753 if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
754 (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
755 (battery->capacity_now <= battery->alarm)))
756 pm_wakeup_event(&battery->device->dev, 0);
757
745 return result; 758 return result;
746} 759}
747 760
@@ -1142,6 +1155,8 @@ static int acpi_battery_add(struct acpi_device *device)
1142 battery->pm_nb.notifier_call = battery_notify; 1155 battery->pm_nb.notifier_call = battery_notify;
1143 register_pm_notifier(&battery->pm_nb); 1156 register_pm_notifier(&battery->pm_nb);
1144 1157
1158 device_init_wakeup(&device->dev, 1);
1159
1145 return result; 1160 return result;
1146 1161
1147fail: 1162fail:
@@ -1158,6 +1173,7 @@ static int acpi_battery_remove(struct acpi_device *device)
1158 1173
1159 if (!device || !acpi_driver_data(device)) 1174 if (!device || !acpi_driver_data(device))
1160 return -EINVAL; 1175 return -EINVAL;
1176 device_init_wakeup(&device->dev, 0);
1161 battery = acpi_driver_data(device); 1177 battery = acpi_driver_data(device);
1162 unregister_pm_notifier(&battery->pm_nb); 1178 unregister_pm_notifier(&battery->pm_nb);
1163#ifdef CONFIG_ACPI_PROCFS_POWER 1179#ifdef CONFIG_ACPI_PROCFS_POWER