summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRavi Chandra Sadineni <ravisadineni@chromium.org>2019-07-24 17:19:22 -0700
committerCommit Bot <commit-bot@chromium.org>2019-09-19 05:36:41 +0000
commita9ea6907339ff2a99970f8de4d1655bc17107435 (patch)
treefc51156a7f45fdcc48a4c2ccd2f8bf29fb9c312c
parent40c69e55dc29c70ed2e36959833b83f01a67483b (diff)
downloadchrome-ec-a9ea6907339ff2a99970f8de4d1655bc17107435.tar.gz
EC: Do not drop SCI events responsible for wake.
EC currently clears all events(main copy of hostevents) on every resume. This seems to be added to clear events that are only part of wake mask and not part of SCI mask as they can stick and cause premature wake on next suspend. This patch stops clearing events that are part of SCI mask from the main copy as ACPI subsystem will query and clear them on resume anyway. This helps kernel to identify the reason for wake if it caused by events that are part of SCI mask. Previously coreboot used to depend on main copy to log wake reason. i.e on every resume coreboot used to query and log and clear the wake reason by reading all events from the main copy. Since this also comes in way of kernel in identifying the wake reason, this change also sets up events_copy_b for coreboot by clearing it on every suspend entery. More details can be found at http://go/hostevent-refactor. BUG=b:141248527 BRANCH=None TEST=Tested suspend/resume with wakeup count on hatch and grunt. Change-Id: I0fac250d4dac49af960b29e8b0e28841af2ef509 Signed-off-by: Ravi Chandra Sadineni <ravisadineni@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1717498 Reviewed-by: Furquan Shaikh <furquan@chromium.org> (cherry picked from commit 74f268374972bdc8bd6c2a5c412d31edafa812b1) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1809817
-rw-r--r--common/host_event_commands.c38
-rw-r--r--power/intel_x86.c3
2 files changed, 34 insertions, 7 deletions
diff --git a/common/host_event_commands.c b/common/host_event_commands.c
index 2762a8bd56..08158a3e7b 100644
--- a/common/host_event_commands.c
+++ b/common/host_event_commands.c
@@ -209,6 +209,22 @@ void lpc_s3_resume_clear_masks(void)
lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, 0);
}
+/*
+ * Clear events that are not part of SCI/SMI mask so as to prevent
+ * premature wakes on next suspend. This is needed because A.P only queries
+ * SCI events after resume. We do not clear SCI/SMI events as they help
+ * kernel identify the wake reason on resume.
+ * For events that are not set in SCI mask but are part of WAKE(S0ix/S3)
+ * masks, kernel drivers should have other ways (physical/virtual interrupt)
+ * pin to identify when they trigger wakes.
+ */
+void clear_non_sci_events(void)
+{
+ host_clear_events(~lpc_get_host_event_mask(LPC_HOST_EVENT_SCI) &
+ ~lpc_get_host_event_mask(LPC_HOST_EVENT_SMI));
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, clear_non_sci_events, HOOK_PRIO_DEFAULT);
+
#endif
/*
@@ -217,10 +233,14 @@ void lpc_s3_resume_clear_masks(void)
* The primary copy is mirrored in mapped memory and used to trigger interrupts
* on the host via ACPI/SCI/SMI/GPIO.
*
- * The secondary (B) copy is used to track events at a non-interrupt level (for
- * example, so a user-level process can find out what events have happened
- * since the last call, even though a kernel-level process is consuming events
- * from the first copy).
+ * The secondary (B) copy is used by entities other than ACPI to query the state
+ * of host events on EC. Currently events_copy_b is used for
+ * 1. Logging recovery mode switch in coreboot.
+ * 2. Used by depthcharge on devices with no 8042 and no MKBP interrupt.
+ * 3. Logging wake reason in coreboot.
+ * Current query of a event from copy_b is immediately followed by clear of the
+ * same event. Further uses of copy_b should make sure this semantics is
+ * followed and none of the above mentioned use cases are broken.
*
* Setting an event sets both copies. Copies are cleared separately.
*/
@@ -418,6 +438,16 @@ test_mockable void host_throttle_cpu(int throttle)
host_set_single_event(EC_HOST_EVENT_THROTTLE_STOP);
}
+/*
+ * Events copy b is used by coreboot for logging the wake reason. For this to
+ * work, events_copy_b needs to be cleared on every suspend.
+ */
+void clear_events_copy_b(void)
+{
+ events_copy_b = 0;
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, clear_events_copy_b, HOOK_PRIO_DEFAULT);
+
/*****************************************************************************/
/* Console commands */
static int command_host_event(int argc, char **argv)
diff --git a/power/intel_x86.c b/power/intel_x86.c
index 1cc8beadf5..2243c045ca 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -550,9 +550,6 @@ void power_chipset_handle_host_sleep_event(enum host_sleep_event state)
*/
s0ix_notify = S0IX_NOTIFY_RESUME;
task_wake(TASK_ID_CHIPSET);
- /* clear host events */
- while (lpc_get_next_host_event() != 0)
- ;
lpc_s0ix_resume_restore_masks();
power_signal_disable_interrupt(sleep_sig[SYS_SLEEP_S0IX]);
} else if (state == HOST_SLEEP_EVENT_DEFAULT_RESET) {