diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2016-06-23 12:36:36 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-06-24 17:24:08 -0700 |
commit | ebcf57035b3b31c224a8c67b1e6a5bd96e50fb6f (patch) | |
tree | 365310c6c97fff7fcf7539536f538c3f537b0b02 /power | |
parent | cbb3063ae9de72e20c1e70820c1a215054065bf1 (diff) | |
download | chrome-ec-ebcf57035b3b31c224a8c67b1e6a5bd96e50fb6f.tar.gz |
power: rk3399: Control power state properly on power button / lid toggle
- Power up the AP automatically on initial EC power-on.
- In S0, wait for 8s power button hold before powering down.
- In S3 and lower, power down immediately on power press.
- In G3 / S5, power up on lid open.
BUG=chrome-os-partner:54582,chrome-os-partner:54511
BRANCH=None
TEST=Manual on gru. Verify the following:
- AP powers up when battery initially attached.
- `reboot` powers up AP after EC reset.
- `reboot ap-off` doesn't power up AP.
- `apshutdown` + `lidclose` + `lidopen` causes AP power-up.
- Holding power for 4s in S0 does not change power state.
- Holding power for 8s in S0 causes AP power down.
Change-Id: I588056549a972212c28b9aa6a83fe2e0b179baa9
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/355650
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/rk3399.c | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/power/rk3399.c b/power/rk3399.c index 0ae4786b51..554e5aee3d 100644 --- a/power/rk3399.c +++ b/power/rk3399.c @@ -40,6 +40,9 @@ /* All inputs in the right state for S0 */ #define IN_ALL_S0 (IN_PGOOD_S0 | IN_SUSPEND_DEASSERTED) +/* Long power key press to force shutdown in S0 */ +#define FORCED_SHUTDOWN_DELAY (8 * SECOND) + static int forcing_shutdown; void chipset_force_shutdown(void) @@ -75,11 +78,20 @@ enum power_state power_chipset_init(void) } wireless_set_state(WIRELESS_OFF); - } + } else if (!(system_get_reset_flags() & RESET_FLAG_AP_OFF)) + /* Auto-power on */ + chipset_exit_hard_off(); return POWER_G3; } +static void force_shutdown(void) +{ + forcing_shutdown = 1; + task_wake(TASK_ID_CHIPSET); +} +DECLARE_DEFERRED(force_shutdown); + enum power_state power_handle_state(enum power_state state) { switch (state) { @@ -209,6 +221,15 @@ enum power_state power_handle_state(enum power_state state) */ enable_sleep(SLEEP_MASK_AP_RUN); + /* + * In case the power button is held awaiting power-off timeout, + * power off immediately now that we're entering S3. + */ + if (power_button_is_pressed()) { + forcing_shutdown = 1; + hook_call_deferred(&force_shutdown_data, -1); + } + return POWER_S3; case POWER_S3S5: @@ -252,16 +273,30 @@ enum power_state power_handle_state(enum power_state state) static void power_button_changed(void) { - /* Only pay attention to power button presses, not releases */ - if (!power_button_is_pressed()) - return; + if (power_button_is_pressed()) { + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + /* Power up from off */ + chipset_exit_hard_off(); - if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) - /* Power up */ - chipset_exit_hard_off(); - else - forcing_shutdown = 1; + else if (!chipset_in_state(CHIPSET_STATE_ON)) + /* Power down immediately from S3 */ + force_shutdown(); - task_wake(TASK_ID_CHIPSET); + else + /* Delayed power down from S0 */ + hook_call_deferred(&force_shutdown_data, + FORCED_SHUTDOWN_DELAY); + } else { + /* Power button released, cancel deferred shutdown */ + hook_call_deferred(&force_shutdown_data, -1); + } } DECLARE_HOOK(HOOK_POWER_BUTTON_CHANGE, power_button_changed, HOOK_PRIO_DEFAULT); + +static void lid_changed(void) +{ + /* Power-up from off on lid open */ + if (lid_is_open() && chipset_in_state(CHIPSET_STATE_ANY_OFF)) + chipset_exit_hard_off(); +} +DECLARE_HOOK(HOOK_LID_CHANGE, lid_changed, HOOK_PRIO_DEFAULT); |