diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2016-08-11 17:02:41 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2017-02-13 09:30:26 +0000 |
commit | 9c336f10a68028f7e292e73474359e6d6ea4d512 (patch) | |
tree | 47b03b6830bbe71898dfd9e9c85a5ecfd267611f | |
parent | 108c73bdb2873386e2382cdca9a9dd9dbbd43cd4 (diff) | |
download | chrome-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.c | 20 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/ec_commands.h | 14 | ||||
-rw-r--r-- | include/power.h | 8 | ||||
-rw-r--r-- | power/common.c | 22 | ||||
-rw-r--r-- | util/ectool.c | 29 |
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}, |