diff options
author | Ravi Chandra Sadineni <ravisadineni@chromium.org> | 2019-07-24 17:19:22 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-09-19 05:36:41 +0000 |
commit | a9ea6907339ff2a99970f8de4d1655bc17107435 (patch) | |
tree | fc51156a7f45fdcc48a4c2ccd2f8bf29fb9c312c | |
parent | 40c69e55dc29c70ed2e36959833b83f01a67483b (diff) | |
download | chrome-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.c | 38 | ||||
-rw-r--r-- | power/intel_x86.c | 3 |
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) { |