diff options
author | Wai-Hong Tam <waihong@google.com> | 2020-07-28 21:09:24 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-08-07 19:04:24 +0000 |
commit | 530c9c71275ca9f08f1a8c470da380f3aa38bebc (patch) | |
tree | 8521d13fe16d10305a693afae2df31a54183c905 /power | |
parent | e5993c83d2a8bbf3c42c45ef97fd08eea728f49f (diff) | |
download | chrome-ec-530c9c71275ca9f08f1a8c470da380f3aa38bebc.tar.gz |
power/intel_x86: Abstract the chipset specific functions
This CL abstracts the chipset specific functions, that makes the hang
detection logic clearer. The changes are like:
* Set the sleep_notify variable through the call sleep_set_notify()
* The chipset specific timeout handle is moved to a callback function.
This callback is passed to sleep_start_suspend().
BRANCH=None
BUG=b:162083524
TEST=Build the hatch board.
Change-Id: Ib9462f1fecbd39d63607bb9f10d1994e54c9ac64
Signed-off-by: Wai-Hong Tam <waihong@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2327837
Reviewed-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/intel_x86.c | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/power/intel_x86.c b/power/intel_x86.c index 1433fc44ab..4fdfbdfb9c 100644 --- a/power/intel_x86.c +++ b/power/intel_x86.c @@ -176,6 +176,26 @@ static void lpc_s0ix_resume_restore_masks(void) backup_sci_mask = backup_smi_mask = 0; } +static void lpc_s0ix_hang_detected(void) +{ + /* + * Wake up the AP so they don't just chill in a non-suspended state and + * burn power. Overload a vaguely related event bit since event bits are + * at a premium. If the system never entered S0ix, then manually set the + * wake mask to pretend it did, so that the hang detect event wakes the + * system. + */ + if (power_get_state() == POWER_S0) { + host_event_t sleep_wake_mask; + + get_lazy_wake_mask(POWER_S0ix, &sleep_wake_mask); + lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, sleep_wake_mask); + } + + CPRINTS("Warning: Detected sleep hang! Waking host up!"); + host_set_single_event(EC_HOST_EVENT_HANG_DETECT); +} + enum sleep_notify_type { SLEEP_NOTIFY_NONE, SLEEP_NOTIFY_SUSPEND, @@ -189,13 +209,18 @@ 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_notify = SLEEP_NOTIFY_NONE; + sleep_set_notify(SLEEP_NOTIFY_NONE); } static void handle_chipset_suspend(void) @@ -220,6 +245,7 @@ DECLARE_HOOK(HOOK_CHIPSET_RESET, handle_chipset_reset, HOOK_PRIO_FIRST); 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); @@ -259,28 +285,17 @@ static void sleep_transition_timeout(void) sleep_signal_transitions |= EC_HOST_RESUME_SLEEP_TIMEOUT; hook_call_deferred(&sleep_transition_timeout_data, -1); - /* - * Wake up the AP so they don't just chill in a non-suspended state and - * burn power. Overload a vaguely related event bit since event bits are - * at a premium. If the system never entered S0ix, then manually set the - * wake mask to pretend it did, so that the hang detect event wakes the - * system. - */ - if (power_get_state() == POWER_S0) { - host_event_t sleep_wake_mask; - - get_lazy_wake_mask(POWER_S0ix, &sleep_wake_mask); - lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, sleep_wake_mask); - } - - CPRINTS("Warning: Detected sleep hang! Waking host up!"); - host_set_single_event(EC_HOST_EVENT_HANG_DETECT); + /* Call the custom callback */ + if (sleep_timeout_callback) + sleep_timeout_callback(); } -static void sleep_start_suspend(struct host_sleep_event_context *ctx) +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. */ @@ -307,6 +322,7 @@ static void sleep_reset_tracking(void) { sleep_signal_transitions = 0; sleep_signal_timeout = 0; + sleep_timeout_callback = NULL; } #else /* !CONFIG_POWER_SLEEP_FAILURE_DETECTION */ @@ -674,16 +690,16 @@ __override void power_chipset_handle_host_sleep_event( * s0ix/s3 suspend has been received and so chipset suspend * notification needs to be sent to listeners. */ - sleep_notify = SLEEP_NOTIFY_SUSPEND; + sleep_set_notify(SLEEP_NOTIFY_SUSPEND); - sleep_start_suspend(ctx); + sleep_start_suspend(ctx, lpc_s0ix_hang_detected); power_signal_enable_interrupt(sleep_sig[SYS_SLEEP_S0IX]); } else if (state == HOST_SLEEP_EVENT_S0IX_RESUME) { /* * Wake up chipset task and indicate to power state machine that * listeners need to be notified of chipset resume. */ - sleep_notify = SLEEP_NOTIFY_RESUME; + sleep_set_notify(SLEEP_NOTIFY_RESUME); task_wake(TASK_ID_CHIPSET); lpc_s0ix_resume_restore_masks(); power_signal_disable_interrupt(sleep_sig[SYS_SLEEP_S0IX]); |