summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-08-11 17:02:41 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-02-13 09:30:26 +0000
commit9c336f10a68028f7e292e73474359e6d6ea4d512 (patch)
tree47b03b6830bbe71898dfd9e9c85a5ecfd267611f
parent108c73bdb2873386e2382cdca9a9dd9dbbd43cd4 (diff)
downloadchrome-ec-9c336f10a68028f7e292e73474359e6d6ea4d512.tar.gz
mkbp_event: Allow host to report sleep state for non-wake event skipping
Allow the host to self-report its sleep state through EC_CMD_HOST_SLEEP_EVENT, which will typically be sent with SUSPEND param when the host begins its sleep process. While the host has self-reported that it is in SUSPEND, don't assert the interrupt line, except for designated wake events. BUG=chrome-os-partner:56156,chrome-os-partner:60882 BRANCH=veyron TEST=On kevin, run 'ectool hostsleepstate suspend', verify that interrupt assertion is skipped for battery host event. Run 'ectool hostsleepstate resume' and verify interrupt is again asserted by the battery host event. Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Original-Change-Id: I74288465587ccf7185cec717f7c1810602361b8c Reviewed-on: https://chromium-review.googlesource.com/368391 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> (cherry picked from commit de4d25964de310effe8ede09e5ba6fa2f40dc52b) Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> Conflicts: board/kevin/board.h include/config.h include/ec_commands.h power/common.c util/ectool.c Change-Id: Ic9e8a2677e43de8b11177f60510f7ab8da0fbaa6 Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> Reviewed-on: https://chromium-review.googlesource.com/438068 Reviewed-by: Alexandru Stan <amstan@chromium.org> Reviewed-by: Simon Glass <sjg@google.com>
-rw-r--r--common/mkbp_event.c20
-rw-r--r--include/config.h6
-rw-r--r--include/ec_commands.h14
-rw-r--r--include/power.h8
-rw-r--r--power/common.c22
-rw-r--r--util/ectool.c29
6 files changed, 97 insertions, 2 deletions
diff --git a/common/mkbp_event.c b/common/mkbp_event.c
index fc6a010ce2..7dfeddcea0 100644
--- a/common/mkbp_event.c
+++ b/common/mkbp_event.c
@@ -11,6 +11,7 @@
#include "host_command.h"
#include "link_defs.h"
#include "mkbp_event.h"
+#include "power.h"
#include "util.h"
static uint32_t events;
@@ -44,13 +45,28 @@ static void set_host_interrupt(int active)
#endif
}
+/**
+ * Check if the host is sleeping. Check our power state in addition to the
+ * self-reported sleep state of host (CONFIG_POWER_TRACK_HOST_SLEEP_STATE).
+ */
+static inline int host_is_sleeping(void)
+{
+ int is_sleeping = !chipset_in_state(CHIPSET_STATE_ON);
+
+#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
+ is_sleeping |=
+ (power_get_host_sleep_state() == HOST_SLEEP_EVENT_S3_SUSPEND);
+#endif
+ return is_sleeping;
+}
+
void mkbp_send_event(uint8_t event_type)
{
set_event(event_type);
#ifdef CONFIG_MKBP_WAKEUP_MASK
- /* checking the event if AP is not in S0 */
- if (!chipset_in_state(CHIPSET_STATE_ON)) {
+ /* Only assert interrupt for wake events if host is sleeping */
+ if (host_is_sleeping()) {
uint32_t events;
events = *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS);
/*
diff --git a/include/config.h b/include/config.h
index 4feb759441..b5c84fb732 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1038,6 +1038,12 @@
/* Use part of the EC's data EEPROM to hold persistent storage for the AP. */
#undef CONFIG_PSTORE
+/*
+ * Allow the host to self-report its sleep state, in case there is some delay
+ * between the host beginning to enter the sleep state and power signals
+ * actually reflecting the new state.
+ */
+#undef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
/*****************************************************************************/
/* Support PWM control */
#undef CONFIG_PWM
diff --git a/include/ec_commands.h b/include/ec_commands.h
index cc8234468d..5aaf05717a 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2666,6 +2666,20 @@ struct ec_params_ext_power_current_limit {
uint32_t limit; /* in mA */
} __packed;
+/* Inform the EC when entering a sleep state */
+#define EC_CMD_HOST_SLEEP_EVENT 0xa9
+
+enum host_sleep_event {
+ HOST_SLEEP_EVENT_S3_SUSPEND = 1,
+ HOST_SLEEP_EVENT_S3_RESUME = 2,
+ HOST_SLEEP_EVENT_S0IX_SUSPEND = 3,
+ HOST_SLEEP_EVENT_S0IX_RESUME = 4
+};
+
+struct ec_params_host_sleep_event {
+ uint8_t sleep_event;
+} __packed;
+
/*****************************************************************************/
/* Smart battery pass-through */
diff --git a/include/power.h b/include/power.h
index 36054e8bd1..e59fc10415 100644
--- a/include/power.h
+++ b/include/power.h
@@ -103,4 +103,12 @@ void power_signal_interrupt(enum gpio_signal signal);
#define power_signal_interrupt NULL
#endif
+#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
+/**
+ * Get sleep state of host, as reported by the host.
+ *
+ * @return Believed sleep state of host.
+ */
+enum host_sleep_event power_get_host_sleep_state(void);
+#endif
#endif /* __CROS_EC_POWER_H */
diff --git a/power/common.c b/power/common.c
index d71fadc696..c44a7deb8d 100644
--- a/power/common.c
+++ b/power/common.c
@@ -12,6 +12,7 @@
#include "extpower.h"
#include "gpio.h"
#include "hooks.h"
+#include "host_command.h"
#include "power.h"
#include "system.h"
#include "task.h"
@@ -505,3 +506,24 @@ DECLARE_CONSOLE_COMMAND(hibdelay, command_hibernation_delay,
"Set the delay before going into hibernation",
NULL);
#endif /* CONFIG_HIBERNATE */
+
+#ifdef CONFIG_POWER_TRACK_HOST_SLEEP_STATE
+/* Track last reported sleep event */
+static enum host_sleep_event host_sleep_state;
+
+static int host_command_host_sleep_event(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_host_sleep_event *p = args->params;
+
+ host_sleep_state = p->sleep_event;
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_HOST_SLEEP_EVENT,
+ host_command_host_sleep_event,
+ EC_VER_MASK(0));
+
+enum host_sleep_event power_get_host_sleep_state(void)
+{
+ return host_sleep_state;
+}
+#endif /* CONFIG_POWER_TRACK_HOST_SLEEP_STATE */
diff --git a/util/ectool.c b/util/ectool.c
index 2045df4603..9ba8de919f 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -116,6 +116,8 @@ const char help_str[] =
" Configure or start/stop the hang detect timer\n"
" hello\n"
" Checks for basic communication with EC\n"
+ " hostsleepstate\n"
+ " Report host sleep state to the EC\n"
" kbpress\n"
" Simulate key press\n"
" i2cread\n"
@@ -320,6 +322,32 @@ int cmd_hello(int argc, char *argv[])
return 0;
}
+int cmd_hostsleepstate(int argc, char *argv[])
+{
+ struct ec_params_host_sleep_event p;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s [suspend|resume|freeze|thaw]\n",
+ argv[0]);
+ return -1;
+ }
+
+ if (!strcmp(argv[1], "suspend"))
+ p.sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND;
+ else if (!strcmp(argv[1], "resume"))
+ p.sleep_event = HOST_SLEEP_EVENT_S3_RESUME;
+ else if (!strcmp(argv[1], "freeze"))
+ p.sleep_event = HOST_SLEEP_EVENT_S0IX_SUSPEND;
+ else if (!strcmp(argv[1], "thaw"))
+ p.sleep_event = HOST_SLEEP_EVENT_S0IX_RESUME;
+ else {
+ fprintf(stderr, "Unknown command: %s\n", argv[1]);
+ return -1;
+ }
+
+ return ec_command(EC_CMD_HOST_SLEEP_EVENT, 0, &p, sizeof(p), NULL, 0);
+}
+
int cmd_test(int argc, char *argv[])
{
struct ec_params_test_protocol p = {
@@ -5535,6 +5563,7 @@ const struct command commands[] = {
{"gpioset", cmd_gpio_set},
{"hangdetect", cmd_hang_detect},
{"hello", cmd_hello},
+ {"hostsleepstate", cmd_hostsleepstate},
{"kbpress", cmd_kbpress},
{"i2cread", cmd_i2c_read},
{"i2cwrite", cmd_i2c_write},