From 24c26b3f126b26effd2a388c889dfa52f387eea0 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Fri, 8 Mar 2019 09:33:07 -0800 Subject: chgstv2: Refactor shutdown_on_critical_battery This patch refactors shutdown_on_critical_battery. There is no change in its functionality. Signed-off-by: Daisuke Nojiri BUG=none BRANCH=nami,strago,coral TEST=Verify Vayne cuts off battery when soc <= 4% in S0 and S5. Change-Id: Ia6d3e2166d01803ae8983afd2d4e15d254845065 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1515719 Reviewed-by: Daisuke Nojiri Commit-Queue: Daisuke Nojiri Tested-by: Daisuke Nojiri --- common/charge_state_v2.c | 98 +++++++++++++++++++++++++++--------------------- test/sbs_charging_v2.c | 4 +- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index ddd8d2501e..de696a3622 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -46,7 +46,7 @@ static int is_full; /* battery not accepting current */ static int state_machine_force_idle; static int manual_mode; /* volt/curr are no longer maintained by charger */ static unsigned int user_current_limit = -1U; -test_export_static timestamp_t shutdown_warning_time; +test_export_static timestamp_t shutdown_target_time; static timestamp_t precharge_start_time; /* Is battery connected but unresponsive after precharge? */ @@ -474,69 +474,81 @@ enum critical_shutdown board_critical_shutdown_check( #endif } - /* - * If the battery is at extremely low charge (and discharging) or extremely - * high temperature, the EC will notify the AP and start a timer. If the - * critical condition is not corrected before the timeout expires, the EC - * will shut down the AP (if the AP is not already off) and then optionally - * hibernate or cut off battery. - */ -static int shutdown_on_critical_battery(void) +static int is_battery_critical(void) { - int batt_temp_c; - int battery_critical = 0; + int batt_temp_c = DECI_KELVIN_TO_CELSIUS(curr.batt.temperature); /* * TODO(crosbug.com/p/27642): The thermal loop should watch the battery * temp, so it can turn fans on. */ - batt_temp_c = DECI_KELVIN_TO_CELSIUS(curr.batt.temperature); if (battery_too_hot(batt_temp_c)) { CPRINTS("Batt temp out of range: %dC", batt_temp_c); - battery_critical = 1; + return 1; } if (battery_too_low() && !curr.batt_is_charging) { CPRINTS("Low battery: %d%%, %dmV", curr.batt.state_of_charge, curr.batt.voltage); - battery_critical = 1; + return 1; } - if (!battery_critical) { + return 0; +} + + /* + * If the battery is at extremely low charge (and discharging) or extremely + * high temperature, the EC will notify the AP and start a timer. If the + * critical condition is not corrected before the timeout expires, the EC + * will shut down the AP (if the AP is not already off) and then optionally + * hibernate or cut off battery. + */ +static int shutdown_on_critical_battery(void) +{ + if (!is_battery_critical()) { /* Reset shutdown warning time */ - shutdown_warning_time.val = 0; - return; + shutdown_target_time.val = 0; + return 0; } - if (!shutdown_warning_time.val) { - CPRINTS("charge warn shutdown due to critical battery"); - shutdown_warning_time = get_time(); + if (!shutdown_target_time.val) { + /* Start count down timer */ + CPRINTS("Start shutdown due to critical battery"); + shutdown_target_time.val = get_time().val + + CRITICAL_BATTERY_SHUTDOWN_TIMEOUT_US; +#ifdef CONFIG_HOSTCMD_EVENTS if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) host_set_single_event(EC_HOST_EVENT_BATTERY_SHUTDOWN); - } else if (get_time().val > shutdown_warning_time.val + - CRITICAL_BATTERY_SHUTDOWN_TIMEOUT_US) { - if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { - /* Timeout waiting for charger to provide more power */ - switch (board_critical_shutdown_check(&curr)) { - case CRITICAL_SHUTDOWN_HIBERNATE: - CPRINTS("Hibernate due to critical battery"); - system_hibernate(0, 0); - break; - case CRITICAL_SHUTDOWN_CUTOFF: - CPRINTS("Cutoff due to critical battery"); - board_cut_off_battery(); - break; - case CRITICAL_SHUTDOWN_IGNORE: - default: - break; - } - } else { - /* Timeout waiting for AP to shut down, so kill it */ - CPRINTS( - "charge force shutdown due to critical battery"); - chipset_force_shutdown(); +#endif + return 1; + } + + if (!timestamp_expired(shutdown_target_time, 0)) + return 1; + + /* Timer has expired */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + switch (board_critical_shutdown_check(&curr)) { + case CRITICAL_SHUTDOWN_HIBERNATE: + CPRINTS("Hibernate due to critical battery"); + system_hibernate(0, 0); + break; + case CRITICAL_SHUTDOWN_CUTOFF: + CPRINTS("Cutoff due to critical battery"); + board_cut_off_battery(); + break; + case CRITICAL_SHUTDOWN_IGNORE: + default: + break; } + } else { + /* Timeout waiting for AP to shut down, so kill it */ + CPRINTS( + "charge force shutdown due to critical battery"); + chipset_force_shutdown(); } + + return 1; } /* @@ -588,7 +600,7 @@ void charger_task(void) prev_ac = prev_charge = prev_bp = -1; state_machine_force_idle = 0; - shutdown_warning_time.val = 0UL; + shutdown_target_time.val = 0UL; battery_seems_to_be_dead = 0; battery_level_shutdown = board_set_battery_level_shutdown(); diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c index 5452c89334..05d0fb131f 100644 --- a/test/sbs_charging_v2.c +++ b/test/sbs_charging_v2.c @@ -26,14 +26,14 @@ static int is_hibernated; static int override_voltage, override_current, override_usec; /* The simulation doesn't really hibernate, so we must reset this ourselves */ -extern timestamp_t shutdown_warning_time; +extern timestamp_t shutdown_target_time; static void reset_mocks(void) { mock_chipset_state = CHIPSET_STATE_ON; is_shutdown = is_force_discharge = is_hibernated = 0; override_voltage = override_current = override_usec = 0; - shutdown_warning_time.val = 0ULL; + shutdown_target_time.val = 0ULL; } int board_cut_off_battery(void) -- cgit v1.2.1