diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-12-19 10:38:52 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-01-06 18:48:11 -0800 |
commit | 0af6e77a3a90299418628a997c81436acbec242c (patch) | |
tree | 342623ba55704015efdd89515f893974471dcb5e | |
parent | 0c8a1b8d39734eaae692eacbe04894207bb2c6da (diff) | |
download | chrome-ec-0af6e77a3a90299418628a997c81436acbec242c.tar.gz |
charger: Change unlocked battery level ignore conditions
x86 systems will auto-power-on when power is applied to the EC. When
the battery level is critically low, power-on is prevented, except when
the system is unlocked. So, when unlocked, some systems will
auto-power-on regardless of battery level, overcurrent the charger /
battery, and then repeat forever.
Prevent this reboot loop by ignoring auto-power-up when the battery is
critically low, regardless of system unlocked status.
BUG=chrome-os-partner:48339
TEST=Verify power-up is prevented on no-battery chell w/ donette. Then,
run 'powerbtn' on EC console and verify system powers on (and
overcurrents).
BRANCH=None
Change-Id: Ia631b5a8c45b42ec805e4a0c3f827929a0efd236
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/319187
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r-- | board/samus/power_sequence.c | 2 | ||||
-rw-r--r-- | common/charge_state_v1.c | 2 | ||||
-rw-r--r-- | common/charge_state_v2.c | 18 | ||||
-rw-r--r-- | common/lightbar.c | 2 | ||||
-rw-r--r-- | common/power_button_x86.c | 24 | ||||
-rw-r--r-- | include/charge_state.h | 5 | ||||
-rw-r--r-- | include/charger.h | 2 | ||||
-rw-r--r-- | power/skylake.c | 2 |
8 files changed, 31 insertions, 26 deletions
diff --git a/board/samus/power_sequence.c b/board/samus/power_sequence.c index a3e40338f4..cac9647a44 100644 --- a/board/samus/power_sequence.c +++ b/board/samus/power_sequence.c @@ -228,7 +228,7 @@ enum power_state power_handle_state(enum power_state state) case POWER_G3S5: /* Return to G3 if battery level is too low */ if (charge_want_shutdown() || - charge_prevent_power_on()) { + charge_prevent_power_on(0)) { CPRINTS("power-up inhibited"); chipset_force_g3(); return POWER_G3; diff --git a/common/charge_state_v1.c b/common/charge_state_v1.c index 4002901f76..b38bdc3e0d 100644 --- a/common/charge_state_v1.c +++ b/common/charge_state_v1.c @@ -682,7 +682,7 @@ int charge_want_shutdown(void) charge_get_percent() < BATTERY_LEVEL_SHUTDOWN; } -int charge_prevent_power_on(void) +int charge_prevent_power_on(int power_button_pressed) { int prevent_power_on = 0; #ifdef CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index c49fc639eb..4401aa54bb 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -644,8 +644,6 @@ void charger_task(void) charger_set_input_current(curr.desired_input_current); } - curr.chg.flags |= CHG_FLAG_INITIALIZED; - /* * TODO(crosbug.com/p/27527). Sometimes the battery thinks its * temperature is 6280C, which seems a bit high. Let's ignore @@ -916,14 +914,20 @@ int charge_want_shutdown(void) (curr.batt.state_of_charge < BATTERY_LEVEL_SHUTDOWN); } -int charge_prevent_power_on(void) +int charge_prevent_power_on(int power_button_pressed) { int prevent_power_on = 0; #ifdef CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON struct batt_params params; struct batt_params *current_batt_params = &curr.batt; - int charger_is_uninitialized = - !(curr.chg.flags & CHG_FLAG_INITIALIZED); + static int automatic_power_on = 1; + + /* + * Remember that a power button was pressed, and assume subsequent + * power-ups are user-requested and non-automatic. + */ + if (power_button_pressed) + automatic_power_on = 0; /* If battery params seem uninitialized then retrieve them */ if (current_batt_params->is_present == BP_NOT_SURE) { @@ -951,9 +955,9 @@ int charge_prevent_power_on(void) /* * Factory override: Always allow power on if WP is disabled, - * except when EC is starting up, due to brown out potential. + * except when auto-power-on at EC startup. */ - prevent_power_on &= (system_is_locked() || charger_is_uninitialized); + prevent_power_on &= (system_is_locked() || automatic_power_on); #endif return prevent_power_on; diff --git a/common/lightbar.c b/common/lightbar.c index 2355067016..822cb77caf 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -268,7 +268,7 @@ static int get_battery_level(void) #ifdef HAS_TASK_CHARGER st.battery_percent = pct = charge_get_percent(); st.battery_is_charging = (PWR_STATE_DISCHARGE != charge_get_state()); - st.battery_is_power_on_prevented = charge_prevent_power_on(); + st.battery_is_power_on_prevented = charge_prevent_power_on(0); #endif /* Find the new battery level */ diff --git a/common/power_button_x86.c b/common/power_button_x86.c index 9ae2be1ff5..ce7bba990e 100644 --- a/common/power_button_x86.c +++ b/common/power_button_x86.c @@ -112,7 +112,7 @@ static const char * const state_names[] = { */ static uint64_t tnext_state; -static void set_pwrbtn_to_pch(int high) +static void set_pwrbtn_to_pch(int high, int init) { /* * If the battery is discharging and low enough we'd shut down the @@ -122,7 +122,7 @@ static void set_pwrbtn_to_pch(int high) */ #ifdef CONFIG_CHARGER if (chipset_in_state(CHIPSET_STATE_ANY_OFF) && !high && - (charge_want_shutdown() || charge_prevent_power_on())) { + (charge_want_shutdown() || charge_prevent_power_on(!init))) { CPRINTS("PB PCH pwrbtn ignored due to battery level"); high = 1; } @@ -137,7 +137,7 @@ void power_button_pch_press(void) /* Assert power button signal to PCH */ if (!power_button_is_pressed()) - set_pwrbtn_to_pch(0); + set_pwrbtn_to_pch(0, 0); } void power_button_pch_release(void) @@ -145,7 +145,7 @@ void power_button_pch_release(void) CPRINTS("PB PCH force release"); /* Deassert power button signal to PCH */ - set_pwrbtn_to_pch(1); + set_pwrbtn_to_pch(1, 0); /* * If power button is actually pressed, eat the next release so we @@ -162,7 +162,7 @@ void power_button_pch_pulse(void) CPRINTS("PB PCH pulse"); chipset_exit_hard_off(); - set_pwrbtn_to_pch(0); + set_pwrbtn_to_pch(0, 0); pwrbtn_state = PWRBTN_STATE_LID_OPEN; tnext_state = get_time().val + PWRBTN_INITIAL_US; task_wake(TASK_ID_POWERBTN); @@ -203,7 +203,7 @@ static void set_initial_pwrbtn_state(void) */ if (power_button_is_pressed()) { CPRINTS("PB init-jumped-held"); - set_pwrbtn_to_pch(0); + set_pwrbtn_to_pch(0, 0); } else { CPRINTS("PB init-jumped"); } @@ -270,12 +270,12 @@ static void state_machine(uint64_t tnow) tnext_state = tnow + PWRBTN_DELAY_T0; pwrbtn_state = PWRBTN_STATE_T0; } - set_pwrbtn_to_pch(0); + set_pwrbtn_to_pch(0, 0); break; case PWRBTN_STATE_T0: tnext_state = tnow + PWRBTN_DELAY_T1; pwrbtn_state = PWRBTN_STATE_T1; - set_pwrbtn_to_pch(1); + set_pwrbtn_to_pch(1, 0); break; case PWRBTN_STATE_T1: /* @@ -286,12 +286,12 @@ static void state_machine(uint64_t tnow) if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) CPRINTS("PB chipset already off"); else - set_pwrbtn_to_pch(0); + set_pwrbtn_to_pch(0, 0); pwrbtn_state = PWRBTN_STATE_HELD; break; case PWRBTN_STATE_RELEASED: case PWRBTN_STATE_LID_OPEN: - set_pwrbtn_to_pch(1); + set_pwrbtn_to_pch(1, 0); pwrbtn_state = PWRBTN_STATE_IDLE; break; case PWRBTN_STATE_INIT_ON: @@ -310,7 +310,7 @@ static void state_machine(uint64_t tnow) * battery is handled inside set_pwrbtn_to_pch(). */ chipset_exit_hard_off(); - set_pwrbtn_to_pch(0); + set_pwrbtn_to_pch(0, 1); tnext_state = get_time().val + PWRBTN_INITIAL_US; if (power_button_is_pressed()) { @@ -329,7 +329,7 @@ static void state_machine(uint64_t tnow) * button until it's released, so that holding down the * recovery combination doesn't cause the chipset to shut back * down. */ - set_pwrbtn_to_pch(1); + set_pwrbtn_to_pch(1, 0); if (power_button_is_pressed()) pwrbtn_state = PWRBTN_STATE_EAT_RELEASE; else diff --git a/include/charge_state.h b/include/charge_state.h index 97c6ca404e..3a86bf4baf 100644 --- a/include/charge_state.h +++ b/include/charge_state.h @@ -96,8 +96,11 @@ int charge_want_shutdown(void); /** * Return non-zero if the battery level is too low to allow power on, even if * a charger is attached. + * + * @param power_button_pressed True if the power-up attempt is caused by a + * power button press. */ -int charge_prevent_power_on(void); +int charge_prevent_power_on(int power_button_pressed); /** * Get the last polled battery/charger temperature. diff --git a/include/charger.h b/include/charger.h index 70d0ff7543..3141c89bab 100644 --- a/include/charger.h +++ b/include/charger.h @@ -49,8 +49,6 @@ void charger_get_params(struct charger_params *chg); #define CHG_FLAG_BAD_INPUT_CURRENT 0x00000004 #define CHG_FLAG_BAD_STATUS 0x00000008 #define CHG_FLAG_BAD_OPTION 0x00000010 -/* Bit to indicate that the charger data has been initialized */ -#define CHG_FLAG_INITIALIZED 0x00000020 /* All of the above CHG_FLAG_BAD_* bits */ #define CHG_FLAG_BAD_ANY 0x0000001f diff --git a/power/skylake.c b/power/skylake.c index 8c28b6d42e..c15c26d1f7 100644 --- a/power/skylake.c +++ b/power/skylake.c @@ -198,7 +198,7 @@ static enum power_state _power_handle_state(enum power_state state) * Allow up to 1s for charger to be initialized, in case * we're trying to boot the AP with no battery. */ - while (charge_prevent_power_on() && + while (charge_prevent_power_on(0) && tries++ < CHARGER_INITIALIZED_TRIES) { msleep(CHARGER_INITIALIZED_DELAY_MS); } |