summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-02-28 13:56:02 -0800
committerRandall Spangler <rspangler@chromium.org>2013-03-05 15:36:09 -0800
commitac05ba645e813d5a77af63cf031fd547ecf49ba5 (patch)
tree29dc0c1a89ab56f5e57e1e362e29fc21231436e3
parent2e59225288b604537e61489a15d8db93e42ff79c (diff)
downloadchrome-ec-ac05ba645e813d5a77af63cf031fd547ecf49ba5.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 Original-Change-Id: I87d17f70d60673f3e3f1c6eb88f3f00a8c9ed4e7 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/44314 (cherry picked from commit 6971fd7a7f8a2351f011bdd60eabda664e0c3ba2) Conflicts: common/charge_state.c Change-Id: I6e819c31c9bcbd4e7adb870390ee5a80c0894f4c Reviewed-on: https://gerrit.chromium.org/gerrit/44692 Commit-Queue: Randall Spangler <rspangler@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Tested-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--common/charge_state.c46
-rw-r--r--include/battery.h7
-rw-r--r--include/chipset.h10
3 files changed, 45 insertions, 18 deletions
diff --git a/common/charge_state.c b/common/charge_state.c
index 09337fd409..a68ddfe6e7 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -104,20 +104,17 @@ static void update_battery_info(void)
/* Prevent battery from going into deep discharge state */
static void poweroff_wait_ac(int hibernate_ec)
{
- /* Shutdown the main processor */
if (chipset_in_state(CHIPSET_STATE_ON)) {
- /* chipset_force_state(CHIPSET_STATE_SOFT_OFF);
- * TODO(rong): remove platform dependent code
+ /*
+ * Shut down the AP. The EC will hibernate after the AP shuts
+ * down.
*/
-#ifdef CONFIG_TASK_X86POWER
- x86_power_force_shutdown();
+ CPRINTF("[%T charge force shutdown due to low battery]\n");
+ chipset_force_shutdown();
host_set_single_event(EC_HOST_EVENT_BATTERY_SHUTDOWN);
-#endif /* CONFIG_TASK_X86POWER */
- }
-
- /* 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,9 +241,8 @@ static int state_common(struct power_state_context *ctx)
if ((batt->state_of_charge < BATTERY_LEVEL_SHUTDOWN &&
!(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);
+ !(curr->error & F_BATTERY_VOLTAGE)))
+ poweroff_wait_ac(1);
}
/* Check battery presence */
@@ -827,6 +823,24 @@ static int charge_init(void)
}
DECLARE_HOOK(HOOK_INIT, charge_init, HOOK_PRIO_DEFAULT);
+
+static int 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);
+ }
+
+ return EC_SUCCESS;
+}
+/*
+ * 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 */
@@ -907,6 +921,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_POWERSTATE);
+
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 */
diff --git a/include/chipset.h b/include/chipset.h
index b2f8897ea9..0705495333 100644
--- a/include/chipset.h
+++ b/include/chipset.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -41,4 +41,12 @@ void chipset_exit_hard_off(void);
/* Enable/disable CPU throttling. */
void chipset_throttle_cpu(int throttle);
+/**
+ * Immediately shut off power to main processor and chipset.
+ *
+ * This is intended for use when the system is too hot or battery power is
+ * critical.
+ */
+void chipset_force_shutdown(void);
+
#endif /* __CROS_EC_CHIPSET_H */