diff options
author | Randall Spangler <rspangler@chromium.org> | 2013-02-28 13:56:02 -0800 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2013-03-05 15:36:09 -0800 |
commit | ac05ba645e813d5a77af63cf031fd547ecf49ba5 (patch) | |
tree | 29dc0c1a89ab56f5e57e1e362e29fc21231436e3 | |
parent | 2e59225288b604537e61489a15d8db93e42ff79c (diff) | |
download | chrome-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.c | 46 | ||||
-rw-r--r-- | include/battery.h | 7 | ||||
-rw-r--r-- | include/chipset.h | 10 |
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 */ |