diff options
author | Randall Spangler <rspangler@chromium.org> | 2013-02-28 13:56:02 -0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-03-05 10:26:21 -0800 |
commit | 6971fd7a7f8a2351f011bdd60eabda664e0c3ba2 (patch) | |
tree | 2f27d93673a1846010d5be5af665c41d6041fafd /common | |
parent | 70cdf52ea1aec0681372a21bc41308a1e4ad20e4 (diff) | |
download | chrome-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
Diffstat (limited to 'common')
-rw-r--r-- | common/charge_state.c | 38 |
1 files changed, 29 insertions, 9 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, |