diff options
author | Jenny TC <jenny.tc@intel.com> | 2017-05-24 18:12:32 +0530 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-07-24 03:03:47 -0700 |
commit | 43081fded2ee9976dc16b1f5bd72bcade33c33d7 (patch) | |
tree | 9363e4d56e73d0745596cba97582c6797cf8985f /power/intel_x86.c | |
parent | d7f7f6931766472fab94726e82dc9b172f9c10a5 (diff) | |
download | chrome-ec-43081fded2ee9976dc16b1f5bd72bcade33c33d7.tar.gz |
S0ix: use both SLP_S0 interrupt and host command for s0ix
EC currently uses a host command from kernel to enter s0ix.
This patch waits for the SLP_S0 interrupt to come after receiving
the host command before entering S0ix.
On the exit path, the SLP_S0 interrupt directly triggers the
exit rather than waiting for the host command.
BRANCH=none
BUG=b:37443151
TEST=check in EC logs for SLP_S0 entry and powerindebug output,
check suspend_stress_test on reef and soraka works fine,
make -j8 buildall runs fine
Change-Id: Ie5507b7a1e723532f07bc0671c2abd364f6224a2
Signed-off-by: Subramony Sesha <subramony.sesha@intel.com>
Signed-off-by: Archana Patni <archana.patni@intel.com>
Signed-off-by: Jenny TC <jenny.tc@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/513705
Commit-Ready: Jenny Tc <jenny.tc@intel.com>
Tested-by: Jenny Tc <jenny.tc@intel.com>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Diffstat (limited to 'power/intel_x86.c')
-rw-r--r-- | power/intel_x86.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/power/intel_x86.c b/power/intel_x86.c index 954ec5d29a..f73e00d700 100644 --- a/power/intel_x86.c +++ b/power/intel_x86.c @@ -37,20 +37,24 @@ enum sys_sleep_state { SYS_SLEEP_S3, - SYS_SLEEP_S4 + SYS_SLEEP_S4, +#ifdef CONFIG_POWER_S0IX + SYS_SLEEP_S0IX, +#endif }; +static const int sleep_sig[] = { #ifdef CONFIG_ESPI_VW_SIGNALS -static const enum espi_vw_signal espi_vm_sig[] = { [SYS_SLEEP_S3] = VW_SLP_S3_L, [SYS_SLEEP_S4] = VW_SLP_S4_L, -}; #else -static const enum gpio_signal gpio_sig[] = { [SYS_SLEEP_S3] = GPIO_PCH_SLP_S3_L, [SYS_SLEEP_S4] = GPIO_PCH_SLP_S4_L, -}; #endif +#ifdef CONFIG_POWER_S0IX + [SYS_SLEEP_S0IX] = GPIO_PCH_SLP_S0_L, +#endif +}; static int power_s5_up; /* Chipset is sequencing up or down */ @@ -58,10 +62,11 @@ static int power_s5_up; /* Chipset is sequencing up or down */ static inline int chipset_get_sleep_signal(enum sys_sleep_state state) { #ifdef CONFIG_ESPI_VW_SIGNALS - return espi_vw_get_wire(espi_vm_sig[state]); -#else - return gpio_get_level(gpio_sig[state]); + if (sleep_sig[state] > VW_SIGNAL_BASE) + return espi_vw_get_wire(sleep_sig[state]); + else #endif + return gpio_get_level(sleep_sig[state]); } #ifdef CONFIG_BOARD_HAS_RTC_RESET @@ -220,8 +225,16 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) /* Power down to next state */ return POWER_S0S3; #ifdef CONFIG_POWER_S0IX - } else if (power_get_host_sleep_state() == - HOST_SLEEP_EVENT_S0IX_SUSPEND) { + /* + * SLP_S0 may assert in system idle scenario without a kernel + * freeze call. This may cause interrupt storm since there is + * no freeze/unfreeze of threads/process in the idle scenario. + * Ignore the SLP_S0 assertions in idle scenario by checking + * the host sleep state. + */ + } else if (power_get_host_sleep_state() + == HOST_SLEEP_EVENT_S0IX_SUSPEND && + chipset_get_sleep_signal(SYS_SLEEP_S0IX) == 0) { return POWER_S0S0ix; #endif } @@ -230,8 +243,8 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state) #ifdef CONFIG_POWER_S0IX case POWER_S0ix: - if ((power_get_host_sleep_state() == - HOST_SLEEP_EVENT_S0IX_RESUME) && + /* System in S0 only if SLP_S0 and SLP_S3 are de-asserted */ + if ((chipset_get_sleep_signal(SYS_SLEEP_S0IX) == 1) && (chipset_get_sleep_signal(SYS_SLEEP_S3) == 1)) { return POWER_S0ixS0; } else if (!power_has_signals(IN_PGOOD_ALL_CORE)) { |