summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-02-28 13:56:02 -0800
committerChromeBot <chrome-bot@google.com>2013-03-05 10:26:21 -0800
commit6971fd7a7f8a2351f011bdd60eabda664e0c3ba2 (patch)
tree2f27d93673a1846010d5be5af665c41d6041fafd
parent70cdf52ea1aec0681372a21bc41308a1e4ad20e4 (diff)
downloadchrome-ec-6971fd7a7f8a2351f011bdd60eabda664e0c3ba2.tar.gz
After shutting down AP, hibernate EC if battery is low
This preserves more battery for the real-time clock. It also gets rid of one battery level/state, since the EC will now shut down at the same level (2%) as the AP. Having the EC hibernate at the same level as the AP shuts down also prevents the following weird scenario: - EC powers on at 2% battery. - EC won't power on the AP to do software sync because battery is low. - But the charge state machine won't actually hibernate the EC until 1%. - Between 2% and 1%, AC is inserted and system starts charging. - But EC-RO is what's doing the charging; we should go through software sync before charging. BUG=chrome-os-partner:17124 BRANCH=link TEST=manual On battery power, 1) With system on, battfake 2 -> system shuts down and EC hibernates 2) With system off, battfake 2 -> EC hibernates Change-Id: I87d17f70d60673f3e3f1c6eb88f3f00a8c9ed4e7 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/44314
-rw-r--r--common/charge_state.c38
-rw-r--r--include/battery.h7
2 files changed, 33 insertions, 12 deletions
diff --git a/common/charge_state.c b/common/charge_state.c
index e13f8969ce..7612f91036 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -109,16 +109,17 @@ static void update_battery_info(void)
*/
static void poweroff_wait_ac(int hibernate_ec)
{
- /* Shutdown the main processor */
if (chipset_in_state(CHIPSET_STATE_ON)) {
- CPRINTF("[%T force shutdown to avoid damaging battery]\n");
+ /*
+ * Shut down the AP. The EC will hibernate after the AP shuts
+ * down.
+ */
+ CPRINTF("[%T charge force shutdown due to low battery]\n");
chipset_force_shutdown();
host_set_single_event(EC_HOST_EVENT_BATTERY_SHUTDOWN);
- }
-
- /* If battery level is critical, hibernate the EC too */
- if (hibernate_ec) {
- CPRINTF("[%T force EC hibernate to avoid damaging battery]\n");
+ } else if (hibernate_ec) {
+ /* If battery level is critical, hibernate the EC */
+ CPRINTF("[%T charge force EC hibernate due to low battery]\n");
system_hibernate(0, 0);
}
}
@@ -244,8 +245,7 @@ static int state_common(struct power_state_context *ctx)
!(curr->error & F_BATTERY_STATE_OF_CHARGE)) ||
(batt->voltage <= ctx->battery->voltage_min &&
!(curr->error & F_BATTERY_VOLTAGE)))
- poweroff_wait_ac(batt->state_of_charge <
- BATTERY_LEVEL_HIBERNATE_EC ? 1 : 0);
+ poweroff_wait_ac(1);
}
/* Check battery presence */
@@ -837,6 +837,22 @@ static void charge_init(void)
}
DECLARE_HOOK(HOOK_INIT, charge_init, HOOK_PRIO_DEFAULT);
+
+static void charge_shutdown(void)
+{
+ /* Hibernate immediately if battery level is too low */
+ if (charge_want_shutdown()) {
+ CPRINTF("[%T charge force EC hibernate after"
+ " shutdown due to low battery]\n");
+ system_hibernate(0, 0);
+ }
+}
+/*
+ * Run the charge shutdown hook last, since when it hibernates no subsequent
+ * hooks would be run.
+ */
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, charge_shutdown, HOOK_PRIO_LAST);
+
/*****************************************************************************/
/* Host commands */
@@ -916,6 +932,10 @@ static int command_battfake(int argc, char **argv)
else
ccprintf("Reporting fake battery level %d%%\n",
fake_state_of_charge);
+
+ /* Wake charger task immediately to see new level */
+ task_wake(TASK_ID_CHARGER);
+
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(battfake, command_battfake,
diff --git a/include/battery.h b/include/battery.h
index da4071e158..50b4e53f7c 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -23,10 +23,11 @@
* level.
*/
#define BATTERY_LEVEL_CRITICAL 5
-/* Shut down main processor when discharging and battery level < this level */
+/*
+ * Shut down main processor and/or hibernate EC when discharging and battery
+ * level < this level.
+ */
#define BATTERY_LEVEL_SHUTDOWN 3
-/* Hibernate EC immediately when discharging and battery level < this level */
-#define BATTERY_LEVEL_HIBERNATE_EC 2
#endif /* __CROS_EC_BATTERY_H */