summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2020-07-28 21:09:24 -0700
committerCommit Bot <commit-bot@chromium.org>2020-08-07 19:04:24 +0000
commit530c9c71275ca9f08f1a8c470da380f3aa38bebc (patch)
tree8521d13fe16d10305a693afae2df31a54183c905 /power
parente5993c83d2a8bbf3c42c45ef97fd08eea728f49f (diff)
downloadchrome-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.c58
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]);