From 1de5ac02ec5558f118e64a354967a83d6994d9c4 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Wed, 3 Jun 2015 13:34:30 -0700 Subject: skylake: Use a simulated power button press to force-shutdown the AP Holding the power button is currently the best known way to bring the AP back to a state where it is shutdown and not powered. BUG=chrome-os-partner:40826, chrome-os-partner:40677 TEST=Run `apshutdown` on glados, verify that power state machine transitions to G3 after several seconds. Run `powerbtn`, verify that state machine transitions back to S0. BRANCH=None Change-Id: Ia799c5f199127f31bd24907b93946c6289d381f8 Signed-off-by: Shawn Nematbakhsh Reviewed-on: https://chromium-review.googlesource.com/275060 Reviewed-by: Aaron Durbin --- common/power_button_x86.c | 9 +++++++++ include/power_button.h | 5 +++++ power/skylake.c | 15 +++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/common/power_button_x86.c b/common/power_button_x86.c index f695b0ffdb..9ae2be1ff5 100644 --- a/common/power_button_x86.c +++ b/common/power_button_x86.c @@ -131,6 +131,15 @@ static void set_pwrbtn_to_pch(int high) gpio_set_level(GPIO_PCH_PWRBTN_L, high); } +void power_button_pch_press(void) +{ + CPRINTS("PB PCH force press"); + + /* Assert power button signal to PCH */ + if (!power_button_is_pressed()) + set_pwrbtn_to_pch(0); +} + void power_button_pch_release(void) { CPRINTS("PB PCH force release"); diff --git a/include/power_button.h b/include/power_button.h index a7ec4612ad..d996cbbdbb 100644 --- a/include/power_button.h +++ b/include/power_button.h @@ -39,6 +39,11 @@ int power_button_signal_asserted(void); */ void power_button_interrupt(enum gpio_signal signal); +/** + * For x86 systems, force-assert the power button signal to the PCH. + */ +void power_button_pch_press(void); + /** * For x86 systems, force-deassert the power button signal to the PCH. */ diff --git a/power/skylake.c b/power/skylake.c index d8c97fc3b6..2e5634ef6e 100644 --- a/power/skylake.c +++ b/power/skylake.c @@ -11,6 +11,7 @@ #include "hooks.h" #include "host_command.h" #include "power.h" +#include "power_button.h" #include "system.h" #include "util.h" #include "wireless.h" @@ -38,15 +39,21 @@ #define IN_ALL_S0 (IN_PGOOD_ALL_CORE | IN_ALL_PM_SLP_DEASSERTED) static int throttle_cpu; /* Throttle CPU? */ +static int forcing_shutdown; /* Forced shutdown in progress? */ void chipset_force_shutdown(void) { CPRINTS("%s()", __func__); /* - * Force off. This condition will reset once the state machine - * transitions to G3. + * Force off. Sending a reset command to the PMIC will power off + * the EC, so simulate a long power button press instead. This + * condition will reset once the state machine transitions to G3. + * Consider reducing the latency here by changing the power off + * hold time on the PMIC. */ + forcing_shutdown = 1; + power_button_pch_press(); } void chipset_force_g3(void) @@ -113,6 +120,10 @@ enum power_state power_handle_state(enum power_state state) switch (state) { case POWER_G3: + if (forcing_shutdown) { + power_button_pch_release(); + forcing_shutdown = 0; + } break; case POWER_S5: -- cgit v1.2.1