From 8c76688b5fab2b9dcf7458322013620023ab435d Mon Sep 17 00:00:00 2001 From: Mulin Chao Date: Thu, 4 Mar 2021 02:37:35 -0800 Subject: [PATCH] soc: power: npcx: solve an interrupt storm caused by host access. This CL solves an interrupt storm caused by plenty of host access messages when system is in S0. It only turns on the host access interrupt before ec enters sleep and turns it off after leaving sleep. Signed-off-by: Mulin Chao --- drivers/espi/host_subs_npcx.c | 16 ++++++++++++---- soc/arm/nuvoton_npcx/common/soc_host.h | 11 +++++++++++ soc/arm/nuvoton_npcx/npcx7/power.c | 9 +++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/espi/host_subs_npcx.c b/drivers/espi/host_subs_npcx.c index 54140c31b39..b1bea00f7b8 100644 --- a/drivers/espi/host_subs_npcx.c +++ b/drivers/espi/host_subs_npcx.c @@ -962,6 +962,16 @@ void npcx_host_init_subs_host_domain(void) LOG_DBG("Hos sub-modules configurations are done!"); } +void npcx_host_enable_access_interrupt(void) +{ + npcx_miwu_irq_enable(&host_sub_cfg.host_acc_wui); +} + +void npcx_host_disable_access_interrupt(void) +{ + npcx_miwu_irq_disable(&host_sub_cfg.host_acc_wui); +} + int npcx_host_init_subs_core_domain(const struct device *host_bus_dev, sys_slist_t *callbacks) { @@ -1057,13 +1067,11 @@ int npcx_host_init_subs_core_domain(const struct device *host_bus_dev, if (IS_ENABLED(CONFIG_PM)) { /* * Configure the host access wake-up event triggered from a host - * transaction on eSPI/LPC bus. No need for callback function. + * transaction on eSPI/LPC bus. Do not enable it here. Or plenty + * of interrupts will jam the system in S0. */ npcx_miwu_interrupt_configure(&host_sub_cfg.host_acc_wui, NPCX_MIWU_MODE_EDGE, NPCX_MIWU_TRIG_HIGH); - - /* Enable irq of interrupt-input module */ - npcx_miwu_irq_enable(&host_sub_cfg.host_acc_wui); } return 0; diff --git a/soc/arm/nuvoton_npcx/common/soc_host.h b/soc/arm/nuvoton_npcx/common/soc_host.h index 719bb46641c..b7f5e94f718 100644 --- a/soc/arm/nuvoton_npcx/common/soc_host.h +++ b/soc/arm/nuvoton_npcx/common/soc_host.h @@ -68,6 +68,17 @@ int npcx_host_periph_read_request(enum lpc_peripheral_opcode op, int npcx_host_periph_write_request(enum lpc_peripheral_opcode op, const uint32_t *data); +/** + * @brief Enable host access wake-up interrupt. Usually, it is used to wake up + * ec during system is in Modern standby power mode. + */ +void npcx_host_enable_access_interrupt(void); + +/** + * @brief Disable host access wake-up interrupt. + */ +void npcx_host_disable_access_interrupt(void); + #ifdef __cplusplus } #endif diff --git a/soc/arm/nuvoton_npcx/npcx7/power.c b/soc/arm/nuvoton_npcx/npcx7/power.c index 328b6768aeb..19637edc6fa 100644 --- a/soc/arm/nuvoton_npcx/npcx7/power.c +++ b/soc/arm/nuvoton_npcx/npcx7/power.c @@ -46,9 +46,12 @@ */ #include +#include #include #include +#include "soc_host.h" + #include LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); @@ -94,6 +97,9 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode) npcx_clock_control_turn_on_system_sleep(slp_mode == NPCX_DEEP_SLEEP, wk_mode == NPCX_INSTANT_WAKE_UP); + /* Turn on host access wake-up interrupt. */ + npcx_host_enable_access_interrupt(); + /* * Capture the reading of low-freq timer for compensation before ec * enters system sleep mode. @@ -109,6 +115,9 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode) */ npcx_clock_compensate_system_timer(); + /* Turn off host access wake-up interrupt. */ + npcx_host_disable_access_interrupt(); + /* Turn off system sleep mode. */ npcx_clock_control_turn_off_system_sleep(); }