summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-06-23 12:36:36 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-06-24 17:24:08 -0700
commitebcf57035b3b31c224a8c67b1e6a5bd96e50fb6f (patch)
tree365310c6c97fff7fcf7539536f538c3f537b0b02
parentcbb3063ae9de72e20c1e70820c1a215054065bf1 (diff)
downloadchrome-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>
-rw-r--r--power/rk3399.c55
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);