diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-09-24 13:10:33 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-09-25 10:56:43 -0700 |
commit | c51a8982ff742fa710887608b038e4e4dd9621e9 (patch) | |
tree | 66295bc60e8e6e2e243174992fdc83aacad01b73 | |
parent | 9332d769e9e68be06fc85a9b0170ed3a2d549ee9 (diff) | |
download | chrome-ec-c51a8982ff742fa710887608b038e4e4dd9621e9.tar.gz |
link: If discharging and system is off, only poll battery once a minute
This reduces power consumption in S3/S5 because the EC doesn't need to
poll the battery every 500ms.
BUG=chrome-os-partner:9676
BRANCH=link
TEST=manual
As much as can be tested with the current debug information:
- Boot system with AC adapter in. Charge state machine should go to
charging state.
- Remove AC adapter. Charge state -> discharging.
- Shut system down.
- Plug AC adapter in. Charge state -> init -> charging over the course of
a few seconds (NOT a minute).
- Remove AC adapter. Charge state -> discharging.
Really good testing requires a source-level change. Hack in a line of
debug output above task_wait_event(sleep_next) in
charge_state_machine_task() which prints how long the charge state
machine is sleeping. It should sleep for ~250ms when charging, ~500ms
when discharging and the system is on, or ~60000ms when discharging
and the system is off. (I did this when writing this change, but
removed it because it clutters up the debug console output.)
Change-Id: I7d3e291fbc40bfcc67d1fb4982d91f0e6bf2e785
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/33921
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Rong Chang <rongchang@chromium.org>
-rw-r--r-- | common/charge_state.c | 34 | ||||
-rw-r--r-- | include/charge_state.h | 1 |
2 files changed, 32 insertions, 3 deletions
diff --git a/common/charge_state.c b/common/charge_state.c index 468eb92adb..e97f03290b 100644 --- a/common/charge_state.c +++ b/common/charge_state.c @@ -13,12 +13,14 @@ #include "common.h" #include "console.h" #include "gpio.h" +#include "hooks.h" #include "host_command.h" #include "power_button.h" #include "power_led.h" #include "printf.h" #include "smart_battery.h" #include "system.h" +#include "task.h" #include "timer.h" #include "util.h" #include "x86_power.h" @@ -699,15 +701,41 @@ void charge_state_machine_task(void) diff_usec = (int)(ts.val - ctx->curr.ts.val); sleep_next = sleep_usec - diff_usec; - if (sleep_next < MIN_SLEEP_USEC) + if (ctx->curr.state == PWR_STATE_DISCHARGE && + chipset_in_state(CHIPSET_STATE_ANY_OFF | + CHIPSET_STATE_SUSPEND)) { + /* + * Discharging and system is off or suspended, so no + * need to poll frequently. charge_hook() will wake us + * up if anything important changes. + */ + sleep_next = POLL_PERIOD_VERY_LONG - diff_usec; + } else if (sleep_next < MIN_SLEEP_USEC) { sleep_next = MIN_SLEEP_USEC; - if (sleep_next > MAX_SLEEP_USEC) + } else if (sleep_next > MAX_SLEEP_USEC) { sleep_next = MAX_SLEEP_USEC; + } - usleep(sleep_next); + task_wait_event(sleep_next); } } +/** + * Charge notification hook. + * + * This is triggered when the AC state changes or the system boots, so that + * we can update our charging state. + */ +static int charge_hook(void) +{ + /* Wake up the task now */ + task_wake(TASK_ID_POWERSTATE); + return EC_SUCCESS; +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, charge_hook, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_AC_CHANGE, charge_hook, HOOK_PRIO_DEFAULT); + + static int charge_command_force_idle(struct host_cmd_handler_args *args) { const struct ec_params_force_idle *p = args->params; diff --git a/include/charge_state.h b/include/charge_state.h index d5c80ff0e0..4810a01c50 100644 --- a/include/charge_state.h +++ b/include/charge_state.h @@ -19,6 +19,7 @@ #define CHARGER_UPDATE_PERIOD (SECOND * 10) /* Power state task polling period in usec */ +#define POLL_PERIOD_VERY_LONG MINUTE #define POLL_PERIOD_LONG (MSEC * 500) #define POLL_PERIOD_CHARGE (MSEC * 250) #define POLL_PERIOD_SHORT (MSEC * 100) |