From 93cfa8be90891a8f264fdd559c1a38278a200554 Mon Sep 17 00:00:00 2001 From: Edward Hill Date: Fri, 4 Jan 2019 16:32:35 -0700 Subject: power_button_x86: Ensure INIT_ON presses button for 200 ms PWRBTN_STATE_INIT_ON should assert GPIO_PCH_PWRBTN_L for PWRBTN_INITIAL_US (200 milliseconds). It was sometimes releasing it too soon, so then the AP would fail to go to S0. In the failing case: 1) PWRBTN_STATE_INIT_ON calls set_pwrbtn_to_pch(). 2) The user has just released the physical button. 3) I2C activity (for battery_get_disconnect_state() from charge_prevent_power_on() in set_pwrbtn_to_pch()) allows power_button_change_deferred() to run to process the release. 4) set_pwrbtn_to_pch() finishes, setting GPIO_PCH_PWRBTN_L to 0. 5) PWRBTN_STATE_INIT_ON checks power_button_is_pressed(), which returns 0, because power_button_change_deferred() ran at 3. 6) PWRBTN_STATE_INIT_ON sets pwrbtn_state to PWRBTN_STATE_RELEASED instead of PWRBTN_STATE_BOOT_KB_RESET. 7) powerbtn_x86_changed() runs (via HOOK_POWER_BUTTON_CHANGE from 3), sets pwrbtn_state to PWRBTN_STATE_RELEASED (again) and also tnext_state to now. 8) state_machine() runs, PWRBTN_STATE_RELEASED sets GPIO_PCH_PWRBTN_L to 1. This is too soon. Change to always set the next state to PWRBTN_STATE_BOOT_KB_RESET after asserting GPIO_PCH_PWRBTN_L to fix this. This ensures powerbtn_x86_changed() will ignore all physical button changes during the initial 200 ms pulse. BUG=b:121066727 BRANCH=grunt TEST=Press Power+F3 many times. AP always boots. Change-Id: I29828f25793bb35fd75efea28de2af9fc2e85ce5 Signed-off-by: Edward Hill Reviewed-on: https://chromium-review.googlesource.com/1395759 Reviewed-by: Jett Rink --- common/power_button_x86.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/common/power_button_x86.c b/common/power_button_x86.c index 04d43f9b9b..357355bfa4 100644 --- a/common/power_button_x86.c +++ b/common/power_button_x86.c @@ -366,16 +366,7 @@ static void state_machine(uint64_t tnow) set_pwrbtn_to_pch(0, 1); tnext_state = get_time().val + PWRBTN_INITIAL_US; - - if (power_button_is_pressed()) { - if (system_get_reset_flags() & RESET_FLAG_RESET_PIN) - pwrbtn_state = PWRBTN_STATE_BOOT_KB_RESET; - else - pwrbtn_state = PWRBTN_STATE_WAS_OFF; - } else { - pwrbtn_state = PWRBTN_STATE_RELEASED; - } - + pwrbtn_state = PWRBTN_STATE_BOOT_KB_RESET; break; case PWRBTN_STATE_BOOT_KB_RESET: -- cgit v1.2.1