summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ec_commands.h35
-rw-r--r--power/common.c30
2 files changed, 65 insertions, 0 deletions
diff --git a/include/ec_commands.h b/include/ec_commands.h
index ddf47d4fc7..b2eb3fe385 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2909,6 +2909,41 @@ struct ec_params_external_power_limit_v1 {
#define EC_POWER_LIMIT_NONE 0xffff
/*****************************************************************************/
+/* Hibernate/Deep Sleep Commands */
+
+/* Set the delay before going into hibernation. */
+#define EC_CMD_HIBERNATION_DELAY 0xa8
+
+struct ec_params_hibernation_delay {
+ /*
+ * Seconds to wait in G3 before hibernate. Pass in 0 to read the
+ * current settings without changing them.
+ */
+ uint32_t seconds;
+};
+
+struct ec_response_hibernation_delay {
+ /*
+ * The current time in seconds in which the system has been in the G3
+ * state. This value is reset if the EC transitions out of G3.
+ */
+ uint32_t time_g3;
+
+ /*
+ * The current time remaining in seconds until the EC should hibernate.
+ * This value is also reset if the EC transitions out of G3.
+ */
+ uint32_t time_remaining;
+
+ /*
+ * The current time in seconds that the EC should wait in G3 before
+ * hibernating.
+ */
+ uint32_t hibernate_delay;
+};
+
+
+/*****************************************************************************/
/* Smart battery pass-through */
/* Get / Set 16-bit smart battery registers */
diff --git a/power/common.c b/power/common.c
index fa0ccc2816..204ef2221e 100644
--- a/power/common.c
+++ b/power/common.c
@@ -562,6 +562,36 @@ DECLARE_CONSOLE_COMMAND(hibdelay, command_hibernation_delay,
"[sec]",
"Set the delay before going into hibernation",
NULL);
+
+static int host_command_hibernation_delay(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_hibernation_delay *p = args->params;
+ struct ec_response_hibernation_delay *r = args->response;
+
+ uint32_t time_g3 = (uint32_t)((get_time().val - last_shutdown_time)
+ / SECOND);
+
+ /* Only change the hibernation delay if seconds is non-zero. */
+ if (p->seconds)
+ hibernate_delay = p->seconds;
+
+ if (state == POWER_G3 && !extpower_is_present())
+ r->time_g3 = time_g3;
+ else
+ r->time_g3 = 0;
+
+ if ((time_g3 != 0) && (time_g3 > hibernate_delay))
+ r->time_remaining = 0;
+ else
+ r->time_remaining = hibernate_delay - time_g3;
+ r->hibernate_delay = hibernate_delay;
+
+ args->response_size = sizeof(struct ec_response_hibernation_delay);
+ return EC_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_HIBERNATION_DELAY,
+ host_command_hibernation_delay,
+ EC_VER_MASK(0));
#endif /* CONFIG_HIBERNATE */
#ifdef CONFIG_POWER_SHUTDOWN_PAUSE_IN_S5