summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@google.com>2018-10-04 15:44:28 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-08 22:23:21 -0700
commitb48320f49d231279c96d4e4017b4faa35c633d11 (patch)
treec652656bb73d524650e5ce554c0993ebf504c9fe
parent028505284c631073ba3e4dd12c9291febbb90871 (diff)
downloadchrome-ec-b48320f49d231279c96d4e4017b4faa35c633d11.tar.gz
intel_x86: Clear SCI/SMI masks only after host enters S0ix
CL:1099968 cleared SCI/SMI masks on receiving host command indicating entry into S0ix. On the other hand, wake mask is programmed only after host actually enters S0ix based on the EC power state machine. However, if the host actually takes a long time to suspend, then it leaves a wide window open where none of the masks are programmed and hence user events like lidopen could get dropped. This change updates the behavior to ensure that SCI/SMI masks get cleared only after power state machine actually enters S0ix based on the SLP_S0 signal. This action is not done as part of a suspend hook because other hooks can result into host events getting set that can trigger SCI/SMI thus leading to the original problem of EC not going into low power idle. Hence, SCI/SMI masks are cleared before any suspend hook is run. BUG=b:116540387 BRANCH=nocturne TEST=None Change-Id: I463c12febc49eefe852bd6e2c2535e96ad94ada0 Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://chromium-review.googlesource.com/1258564 Commit-Ready: Furquan Shaikh <furquan@chromium.org> Tested-by: Caveh Jalali <caveh@google.com> Tested-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Caveh Jalali <caveh@google.com>
-rw-r--r--power/intel_x86.c85
1 files changed, 43 insertions, 42 deletions
diff --git a/power/intel_x86.c b/power/intel_x86.c
index 75e06fde3b..1cf49a6137 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -140,6 +140,44 @@ static enum power_state power_wait_s5_rtc_reset(void)
#endif
#ifdef CONFIG_POWER_S0IX
+/*
+ * Backup copies of SCI and SMI mask to preserve across S0ix suspend/resume
+ * cycle. If the host uses S0ix, BIOS is not involved during suspend and resume
+ * operations and hence SCI/SMI masks are programmed only once during boot-up.
+ *
+ * These backup variables are set whenever host expresses its interest to
+ * enter S0ix and then lpc_host_event_mask for SCI and SMI are cleared. When
+ * host resumes from S0ix, masks from backup variables are copied over to
+ * lpc_host_event_mask for SCI and SMI.
+ */
+static host_event_t backup_sci_mask;
+static host_event_t backup_smi_mask;
+
+/*
+ * Clear host event masks for SMI and SCI when host is entering S0ix. This is
+ * done to prevent any SCI/SMI interrupts when the host is in suspend. Since
+ * BIOS is not involved in the suspend path, EC needs to take care of clearing
+ * these masks.
+ */
+static void lpc_s0ix_suspend_clear_masks(void)
+{
+ backup_sci_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
+ backup_smi_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI);
+
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, 0);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, 0);
+}
+
+/*
+ * Restore host event masks for SMI and SCI when host exits S0ix. This is done
+ * because BIOS is not involved in the resume path and so EC needs to restore
+ * the masks from backup variables.
+ */
+static void lpc_s0ix_resume_restore_masks(void)
+{
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, backup_sci_mask);
+ lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, backup_smi_mask);
+}
enum s0ix_notify_type {
S0IX_NOTIFY_NONE,
@@ -154,6 +192,11 @@ static void s0ix_transition(int check_state, int hook_id)
{
if (s0ix_notify != check_state)
return;
+
+ /* Clear masks before any hooks are run for suspend. */
+ if (s0ix_notify == S0IX_NOTIFY_SUSPEND)
+ lpc_s0ix_suspend_clear_masks();
+
hook_notify(hook_id);
s0ix_notify = S0IX_NOTIFY_NONE;
}
@@ -493,47 +536,6 @@ power_board_handle_host_sleep_event(enum host_sleep_event state)
/* Default weak implementation -- no action required. */
}
-#ifdef CONFIG_POWER_S0IX
-/*
- * Backup copies of SCI and SMI mask to preserve across S0ix suspend/resume
- * cycle. If the host uses S0ix, BIOS is not involved during suspend and resume
- * operations and hence SCI/SMI masks are programmed only once during boot-up.
- *
- * These backup variables are set whenever host expresses its interest to
- * enter S0ix and then lpc_host_event_mask for SCI and SMI are cleared. When
- * host resumes from S0ix, masks from backup variables are copied over to
- * lpc_host_event_mask for SCI and SMI.
- */
-static host_event_t backup_sci_mask;
-static host_event_t backup_smi_mask;
-
-/*
- * Clear host event masks for SMI and SCI when host is entering S0ix. This is
- * done to prevent any SCI/SMI interrupts when the host is in suspend. Since
- * BIOS is not involved in the suspend path, EC needs to take care of clearing
- * these masks.
- */
-static void lpc_s0ix_suspend_clear_masks(void)
-{
- backup_sci_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
- backup_smi_mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI);
-
- lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, 0);
- lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, 0);
-}
-
-/*
- * Restore host event masks for SMI and SCI when host exits S0ix. This is done
- * because BIOS is not involved in the resume path and so EC needs to restore
- * the masks from backup variables.
- */
-static void lpc_s0ix_resume_restore_masks(void)
-{
- lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, backup_sci_mask);
- lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, backup_smi_mask);
-}
-#endif
-
void power_chipset_handle_host_sleep_event(enum host_sleep_event state)
{
power_board_handle_host_sleep_event(state);
@@ -546,7 +548,6 @@ void power_chipset_handle_host_sleep_event(enum host_sleep_event state)
* notification needs to be sent to listeners.
*/
s0ix_notify = S0IX_NOTIFY_SUSPEND;
- lpc_s0ix_suspend_clear_masks();
power_signal_enable_interrupt(sleep_sig[SYS_SLEEP_S0IX]);
} else if (state == HOST_SLEEP_EVENT_S0IX_RESUME) {
/*