diff options
author | Wai-Hong Tam <waihong@google.com> | 2020-07-23 15:04:17 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-08-07 19:04:25 +0000 |
commit | 099a6bc377ac53fe389d35d3a6296a81229df3d8 (patch) | |
tree | cf75f35aa70de271600b900b5d2532cd9d487265 /power | |
parent | 530c9c71275ca9f08f1a8c470da380f3aa38bebc (diff) | |
download | chrome-ec-099a6bc377ac53fe389d35d3a6296a81229df3d8.tar.gz |
power: Move the sleep failure detection to a common library
Move the sleep failure detection logic from intel_x86 power sequence to
a common library, i.e. host_sleep.
This CL simply moves the code, without any logic change.
BRANCH=None
BUG=b:162083524
TEST=Build the hatch board.
Change-Id: Ia3f70804ded8d80c4a079a36fbf1819c05a2090b
Signed-off-by: Wai-Hong Tam <waihong@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2321874
Reviewed-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/host_sleep.c | 143 | ||||
-rw-r--r-- | power/intel_x86.c | 122 |
2 files changed, 143 insertions, 122 deletions
diff --git a/power/host_sleep.c b/power/host_sleep.c index 673d421ca7..54a308d6c3 100644 --- a/power/host_sleep.c +++ b/power/host_sleep.c @@ -4,8 +4,14 @@ */ #include "ec_commands.h" +#include "hooks.h" #include "host_command.h" #include "power.h" +#include "util.h" + +/* Console output macros */ +#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args) /* Track last reported sleep event */ static enum host_sleep_event host_sleep_state; @@ -77,3 +83,140 @@ void power_set_host_sleep_state(enum host_sleep_event state) host_sleep_state = state; } +#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION +/* Flag to notify listeners about suspend/resume events. */ +enum sleep_notify_type sleep_notify = SLEEP_NOTIFY_NONE; + +/* + * Note: the following sleep_ functions do not get called in the S3 path on + * Intel devices. On Intel devices, they are called in the S0ix path. + */ +void sleep_set_notify(enum sleep_notify_type notify) +{ + sleep_notify = notify; +} + +void sleep_notify_transition(int check_state, int hook_id) +{ + if (sleep_notify != check_state) + return; + + hook_notify(hook_id); + sleep_set_notify(SLEEP_NOTIFY_NONE); +} + +static uint16_t sleep_signal_timeout; +static uint32_t sleep_signal_transitions; +static void (*sleep_timeout_callback)(void); + +static void sleep_transition_timeout(void); +DECLARE_DEFERRED(sleep_transition_timeout); + +static void sleep_increment_transition(void) +{ + if ((sleep_signal_transitions & EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK) < + EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK) + sleep_signal_transitions += 1; +} + +void sleep_suspend_transition(void) +{ + sleep_increment_transition(); + hook_call_deferred(&sleep_transition_timeout_data, -1); +} + +void sleep_resume_transition(void) +{ + sleep_increment_transition(); + + /* + * Start the timer again to ensure the AP doesn't get itself stuck in + * a state where it's no longer in a sleep state (S0ix/S3), but from + * the Linux perspective is still suspended. Perhaps a bug in the SoC- + * internal periodic housekeeping code might result in a situation + * like this. + */ + if (sleep_signal_timeout) + hook_call_deferred(&sleep_transition_timeout_data, + (uint32_t)sleep_signal_timeout * 1000); +} + +static void sleep_transition_timeout(void) +{ + /* Mark the timeout. */ + sleep_signal_transitions |= EC_HOST_RESUME_SLEEP_TIMEOUT; + hook_call_deferred(&sleep_transition_timeout_data, -1); + + /* Call the custom callback */ + if (sleep_timeout_callback) + sleep_timeout_callback(); +} + +void sleep_start_suspend(struct host_sleep_event_context *ctx, + void (*callback)(void)) +{ + uint16_t timeout = ctx->sleep_timeout_ms; + + sleep_timeout_callback = callback; + sleep_signal_transitions = 0; + + /* Use zero internally to indicate no timeout. */ + if (timeout == EC_HOST_SLEEP_TIMEOUT_DEFAULT) { + timeout = CONFIG_SLEEP_TIMEOUT_MS; + + } else if (timeout == EC_HOST_SLEEP_TIMEOUT_INFINITE) { + sleep_signal_timeout = 0; + return; + } + + sleep_signal_timeout = timeout; + hook_call_deferred(&sleep_transition_timeout_data, + (uint32_t)timeout * 1000); +} + +void sleep_complete_resume(struct host_sleep_event_context *ctx) +{ + hook_call_deferred(&sleep_transition_timeout_data, -1); + ctx->sleep_transitions = sleep_signal_transitions; +} + +void sleep_reset_tracking(void) +{ + sleep_signal_transitions = 0; + sleep_signal_timeout = 0; + sleep_timeout_callback = NULL; +} + +#else /* !CONFIG_POWER_SLEEP_FAILURE_DETECTION */ + +/* No action */ +void sleep_set_notify(enum sleep_notify_type notify) +{ +} + +void sleep_notify_transition(int check_state, int hook_id) +{ +} + +void sleep_suspend_transition(void) +{ +} + +void sleep_resume_transition(void) +{ +} + +void sleep_start_suspend(struct host_sleep_event_context *ctx, + void (*callback)(void)) +{ +} + +void sleep_complete_resume(struct host_sleep_event_context *ctx) +{ +} + +void sleep_reset_tracking(void) +{ +} + +#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ diff --git a/power/intel_x86.c b/power/intel_x86.c index 4fdfbdfb9c..1fdf1b96ea 100644 --- a/power/intel_x86.c +++ b/power/intel_x86.c @@ -196,38 +196,10 @@ static void lpc_s0ix_hang_detected(void) host_set_single_event(EC_HOST_EVENT_HANG_DETECT); } -enum sleep_notify_type { - SLEEP_NOTIFY_NONE, - SLEEP_NOTIFY_SUSPEND, - SLEEP_NOTIFY_RESUME, -}; - -/* Flag to notify listeners about suspend/resume events. */ -enum sleep_notify_type sleep_notify = SLEEP_NOTIFY_NONE; - -/* - * Note: the following sleep_ functions do not get called in the S3 path on - * Intel devices. On Intel devices, they are called in the S0ix path. - */ -static void sleep_set_notify(enum sleep_notify_type notify) -{ - sleep_notify = notify; -} - -static void sleep_notify_transition(int check_state, int hook_id) -{ - if (sleep_notify != check_state) - return; - - hook_notify(hook_id); - sleep_set_notify(SLEEP_NOTIFY_NONE); -} - static void handle_chipset_suspend(void) { /* Clear masks before any hooks are run for suspend. */ lpc_s0ix_suspend_clear_masks(); - } DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, handle_chipset_suspend, HOOK_PRIO_FIRST); @@ -241,100 +213,6 @@ static void handle_chipset_reset(void) } DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST); -#ifdef CONFIG_POWER_SLEEP_FAILURE_DETECTION - -static uint16_t sleep_signal_timeout; -static uint32_t sleep_signal_transitions; -static void (*sleep_timeout_callback)(void); - -static void sleep_transition_timeout(void); -DECLARE_DEFERRED(sleep_transition_timeout); - -static void sleep_increment_transition(void) -{ - if ((sleep_signal_transitions & EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK) < - EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK) - sleep_signal_transitions += 1; -} - -static void sleep_suspend_transition(void) -{ - sleep_increment_transition(); - hook_call_deferred(&sleep_transition_timeout_data, -1); -} - -static void sleep_resume_transition(void) -{ - sleep_increment_transition(); - - /* - * Start the timer again to ensure the AP doesn't get itself stuck in - * a state where it's no longer in a sleep state (S0ix/S3), but from - * the Linux perspective is still suspended. Perhaps a bug in the SoC- - * internal periodic housekeeping code might result in a situation - * like this. - */ - if (sleep_signal_timeout) - hook_call_deferred(&sleep_transition_timeout_data, - (uint32_t)sleep_signal_timeout * 1000); -} - -static void sleep_transition_timeout(void) -{ - /* Mark the timeout. */ - sleep_signal_transitions |= EC_HOST_RESUME_SLEEP_TIMEOUT; - hook_call_deferred(&sleep_transition_timeout_data, -1); - - /* Call the custom callback */ - if (sleep_timeout_callback) - sleep_timeout_callback(); -} - -static void sleep_start_suspend(struct host_sleep_event_context *ctx, - void (*callback)(void)) -{ - uint16_t timeout = ctx->sleep_timeout_ms; - - sleep_timeout_callback = callback; - sleep_signal_transitions = 0; - - /* Use zero internally to indicate no timeout. */ - if (timeout == EC_HOST_SLEEP_TIMEOUT_DEFAULT) { - timeout = CONFIG_SLEEP_TIMEOUT_MS; - - } else if (timeout == EC_HOST_SLEEP_TIMEOUT_INFINITE) { - sleep_signal_timeout = 0; - return; - } - - sleep_signal_timeout = timeout; - hook_call_deferred(&sleep_transition_timeout_data, - (uint32_t)timeout * 1000); -} - -static void sleep_complete_resume(struct host_sleep_event_context *ctx) -{ - hook_call_deferred(&sleep_transition_timeout_data, -1); - ctx->sleep_transitions = sleep_signal_transitions; -} - -static void sleep_reset_tracking(void) -{ - sleep_signal_transitions = 0; - sleep_signal_timeout = 0; - sleep_timeout_callback = NULL; -} - -#else /* !CONFIG_POWER_SLEEP_FAILURE_DETECTION */ - -#define sleep_suspend_transition() -#define sleep_resume_transition() -#define sleep_start_suspend(_ctx) -#define sleep_complete_resume(_ctx) -#define sleep_reset_tracking() - -#endif /* CONFIG_POWER_SLEEP_FAILURE_DETECTION */ - void power_reset_host_sleep_state(void) { power_set_host_sleep_state(HOST_SLEEP_EVENT_DEFAULT_RESET); |