From fcd0f0a5e485653d40d6409802d1a26c4595d605 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Fri, 5 Oct 2012 11:09:49 -0700 Subject: [PATCH] link: Hibernate EC when battery level drops below 2% We already shut down the main processor below 3%. Hibernating the EC below 2% will further cut power draw and minimize the risk of deep-discharging the battery. BUG=chrome-os-partner:14839 BRANCH=link TEST=manual 1) discharge battery below 3%; system should shut down. when powered on again it should shut back down within ~10 sec. 2) discharge battery below 2%; when system shuts down it should also hibernate. (I've also tested this with a hacked smart_battery.c which lies about the battery state of charge, since that's faster than waiting for my battery to discharge.) Change-Id: I504ba927012430db5cf10b895a36e6cd6fdf4c8b Signed-off-by: Randall Spangler Reviewed-on: https://gerrit.chromium.org/gerrit/34793 Reviewed-by: Bill Richardson --- common/charge_state.c | 16 ++++++++++++---- include/battery.h | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/common/charge_state.c b/common/charge_state.c index b0deee1f2c..3a91afd273 100644 --- a/common/charge_state.c +++ b/common/charge_state.c @@ -98,7 +98,7 @@ static void update_battery_info(void) } /* Prevent battery from going into deep discharge state */ -static void poweroff_wait_ac(void) +static void poweroff_wait_ac(int hibernate_ec) { /* Shutdown the main processor */ if (chipset_in_state(CHIPSET_STATE_ON)) { @@ -111,6 +111,12 @@ static void poweroff_wait_ac(void) 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"); + system_hibernate(0, 0); + } } /* Common handler for charging states. @@ -219,12 +225,14 @@ static int state_common(struct power_state_context *ctx) } /* Prevent deep discharging */ - if (!curr->ac) + if (!curr->ac) { 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(); + poweroff_wait_ac(batt->state_of_charge < + BATTERY_LEVEL_HIBERNATE_EC ? 1 : 0); + } /* Check battery presence */ if (curr->error & F_BATTERY_MASK) { @@ -465,7 +473,7 @@ static enum power_state state_discharge(struct power_state_context *ctx) */ if (batt->temperature > ctx->battery->temp_discharge_max || batt->temperature < ctx->battery->temp_discharge_min) - poweroff_wait_ac(); + poweroff_wait_ac(0); return PWR_STATE_UNCHANGE; } diff --git a/include/battery.h b/include/battery.h index 02001b763a..c09e4eb76b 100644 --- a/include/battery.h +++ b/include/battery.h @@ -12,7 +12,10 @@ #define BATTERY_LEVEL_WARNING 15 #define BATTERY_LEVEL_LOW 10 #define BATTERY_LEVEL_CRITICAL 5 +/* Shut down main processor when battery level reaches this level */ #define BATTERY_LEVEL_SHUTDOWN 3 +/* Hibernate EC immediately when battery level reaches this level */ +#define BATTERY_LEVEL_HIBERNATE_EC 2 /* Stop charge when state of charge reaches this percentage */ #define STOP_CHARGE_THRESHOLD 100