summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-09-24 13:10:33 -0700
committerGerrit <chrome-bot@google.com>2012-09-25 10:56:43 -0700
commitc51a8982ff742fa710887608b038e4e4dd9621e9 (patch)
tree66295bc60e8e6e2e243174992fdc83aacad01b73
parent9332d769e9e68be06fc85a9b0170ed3a2d549ee9 (diff)
downloadchrome-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.c34
-rw-r--r--include/charge_state.h1
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)