diff options
-rw-r--r-- | common/system.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/common/system.c b/common/system.c index ca3ec6f06d..4e0ab91c2f 100644 --- a/common/system.c +++ b/common/system.c @@ -6,6 +6,7 @@ /* System module for Chrome EC : common functions */ #include "battery.h" #include "charge_manager.h" +#include "chipset.h" #include "clock.h" #include "common.h" #include "console.h" @@ -100,6 +101,11 @@ static int disable_jump; /* Disable ALL jumps if system is locked */ static int force_locked; /* Force system locked even if WP isn't enabled */ static enum ec_reboot_cmd reboot_at_shutdown; +#ifdef CONFIG_HIBERNATE +static uint32_t hibernate_seconds; +static uint32_t hibernate_microseconds; +#endif + /* On-going actions preventing going into deep-sleep mode */ uint32_t sleep_mask; @@ -921,7 +927,7 @@ static int handle_pending_reboot(enum ec_reboot_cmd cmd) /* Intentional fall-through */ case EC_REBOOT_HIBERNATE: CPRINTS("system hibernating"); - system_hibernate(0, 0); + system_hibernate(hibernate_seconds, hibernate_microseconds); /* That shouldn't return... */ return EC_ERROR_UNKNOWN; #endif @@ -1011,7 +1017,20 @@ static int command_hibernate(int argc, char **argv) else ccprintf("Hibernating until wake pin asserted.\n"); - system_hibernate(seconds, microseconds); + /* + * If chipset is already off, then call system_hibernate directly. Else, + * let chipset_task bring down the power rails and transition to proper + * state before system_hibernate is called. + */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + system_hibernate(seconds, microseconds); + else { + reboot_at_shutdown = EC_REBOOT_HIBERNATE; + hibernate_seconds = seconds; + hibernate_microseconds = microseconds; + + chipset_force_shutdown(CHIPSET_SHUTDOWN_CONSOLE_CMD); + } return EC_SUCCESS; } |