From 2fbeb3eec6ebbb4eecc1cf92982998b811c758e6 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 1 Sep 2022 17:55:15 +0800 Subject: Battery: align OS low battery shutdown behavior Deprecate BATTERY_LEVEL_CRITICAL in battery logic and use CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE instead to align OS low battery shutdown behavior, and centralize the low battery threshold decision. LOW_COVERAGE_REASON=CONFIG_OCPC is per-board definition. BRANCH=none BUG=b:244253629 TEST=Verify dedede shutdown from resume on low battery. Signed-off-by: Ivan Chen Change-Id: Ibab3f87f213cc23c54fb5d7dc95aa6366c98e94e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3868875 Reviewed-by: Daisuke Nojiri Commit-Queue: Shou-Chieh Hsu --- common/battery_v1.c | 3 +-- common/battery_v2.c | 3 +-- common/charge_state_v2.c | 33 +++++++++++++++++++++++++-------- include/charge_state.h | 22 ++++++++++++++++++++++ test/sbs_charging_v2.c | 6 ++++-- 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/common/battery_v1.c b/common/battery_v1.c index e7507cf75d..2c81d6b446 100644 --- a/common/battery_v1.c +++ b/common/battery_v1.c @@ -155,8 +155,7 @@ void update_dynamic_battery_info(void) } if (curr->batt.is_present == BP_YES && - !(curr->batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && - curr->batt.state_of_charge <= BATTERY_LEVEL_CRITICAL) + battery_is_below_threshold(BATT_THRESHOLD_TYPE_SHUTDOWN, false)) tmp |= EC_BATT_FLAG_LEVEL_CRITICAL; tmp |= curr->batt_is_charging ? EC_BATT_FLAG_CHARGING : diff --git a/common/battery_v2.c b/common/battery_v2.c index 2bd274b465..57ae07196b 100644 --- a/common/battery_v2.c +++ b/common/battery_v2.c @@ -360,8 +360,7 @@ void update_dynamic_battery_info(void) } if (curr->batt.is_present == BP_YES && - !(curr->batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && - curr->batt.state_of_charge <= BATTERY_LEVEL_CRITICAL) + battery_is_below_threshold(BATT_THRESHOLD_TYPE_SHUTDOWN, false)) tmp |= EC_BATT_FLAG_LEVEL_CRITICAL; tmp |= curr->batt_is_charging ? EC_BATT_FLAG_CHARGING : diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index 9b567ba2ff..728606ef8a 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -1266,6 +1266,29 @@ static int shutdown_on_critical_battery(void) return 1; } +int battery_is_below_threshold(enum batt_threshold_type type, bool transitioned) +{ + int threshold; + + /* We can't tell what the current charge is. Assume it's okay. */ + if (curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) + return 0; + + switch (type) { + case BATT_THRESHOLD_TYPE_LOW: + threshold = BATTERY_LEVEL_LOW; + break; + case BATT_THRESHOLD_TYPE_SHUTDOWN: + threshold = CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE; + break; + default: + return 0; + } + + return curr.batt.state_of_charge <= threshold && + (!transitioned || prev_charge > threshold); +} + /* * Send host events as the battery charge drops below certain thresholds. * We handle forced shutdown and other actions elsewhere; this is just for the @@ -1274,17 +1297,11 @@ static int shutdown_on_critical_battery(void) */ static void notify_host_of_low_battery_charge(void) { - /* We can't tell what the current charge is. Assume it's okay. */ - if (curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) - return; - #ifdef CONFIG_HOSTCMD_EVENTS - if (curr.batt.state_of_charge <= BATTERY_LEVEL_LOW && - prev_charge > BATTERY_LEVEL_LOW) + if (battery_is_below_threshold(BATT_THRESHOLD_TYPE_LOW, true)) host_set_single_event(EC_HOST_EVENT_BATTERY_LOW); - if (curr.batt.state_of_charge <= BATTERY_LEVEL_CRITICAL && - prev_charge > BATTERY_LEVEL_CRITICAL) + if (battery_is_below_threshold(BATT_THRESHOLD_TYPE_SHUTDOWN, true)) host_set_single_event(EC_HOST_EVENT_BATTERY_CRITICAL); #endif } diff --git a/include/charge_state.h b/include/charge_state.h index c2d2bce948..221947b9d1 100644 --- a/include/charge_state.h +++ b/include/charge_state.h @@ -7,6 +7,7 @@ #include "common.h" #include "timer.h" +#include "stdbool.h" /* Stuff that's common to all charger implementations can go here. */ @@ -135,6 +136,27 @@ static inline int charge_want_shutdown(void) } #endif +/** + * Return true if battery level is below threshold, false otherwise, + * or if SoC can't be determined. + * + * @param transitioned True to check if SoC is previously above threshold + */ +enum batt_threshold_type { + BATT_THRESHOLD_TYPE_LOW = 0, + BATT_THRESHOLD_TYPE_SHUTDOWN +}; +#if defined(CONFIG_CHARGER) && defined(CONFIG_BATTERY) +int battery_is_below_threshold(enum batt_threshold_type type, + bool transitioned); +#else +static inline int battery_is_below_threshold(enum batt_threshold_type type, + bool transitioned) +{ + return 0; +} +#endif + /** * Return non-zero if the battery level is too low to allow power on, even if * a charger is attached. diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c index 1144a93368..b30f377c67 100644 --- a/test/sbs_charging_v2.c +++ b/test/sbs_charging_v2.c @@ -725,7 +725,8 @@ static int test_low_battery_hostevents(void) TEST_ASSERT(!is_shutdown); /* (Shout) a little bit louder now */ - sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_CRITICAL + 1); + sb_write(SB_RELATIVE_STATE_OF_CHARGE, + CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE + 1); state = wait_charging_state(); TEST_ASSERT(state == PWR_STATE_DISCHARGE); TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW)); @@ -734,7 +735,8 @@ static int test_low_battery_hostevents(void) TEST_ASSERT(!is_shutdown); /* (Shout) a little bit louder now */ - sb_write(SB_RELATIVE_STATE_OF_CHARGE, BATTERY_LEVEL_CRITICAL - 1); + sb_write(SB_RELATIVE_STATE_OF_CHARGE, + CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE - 1); state = wait_charging_state(); TEST_ASSERT(state == PWR_STATE_DISCHARGE); TEST_ASSERT(ev_is_set(EC_HOST_EVENT_BATTERY_LOW)); -- cgit v1.2.1