driver: uart: npcx: Fix CR_SIN interrupt storm

NPCX WIMU CR_SIN is used to wake up soc from NPCX sleep power state.
The wake-up IRQ enabled when UART init. It causes the wake-up IRQ to
generate many extra interrupt events, which causes the system too busy
to handle other events. This PR moves the UART wake-up IRQ enabling
from UART init to npcx_power_enter_system_sleep() to avoid the
interrupt storm.

Signed-off-by: Wealian Liao <WHLIAO@nuvoton.com>
This commit is contained in:
Wealian Liao 2021-06-21 10:05:31 +08:00 committed by Anas Nashif
commit b4faf7fe63
3 changed files with 42 additions and 3 deletions

View file

@ -14,6 +14,7 @@
#include <pm/device.h>
#include <soc.h>
#include "soc_miwu.h"
#include "soc_power.h"
#include <logging/log.h>
LOG_MODULE_REGISTER(uart_npcx, LOG_LEVEL_ERR);
@ -320,6 +321,12 @@ static __unused void uart_npcx_rx_wk_isr(const struct device *dev,
if (IS_ENABLED(CONFIG_UART_CONSOLE_INPUT_EXPIRED)) {
npcx_power_console_is_in_use_refresh();
}
/*
* Disable MIWU CR_SIN interrupt to avoid the other redundant interrupts
* after ec wakes up.
*/
npcx_uart_disable_access_interrupt();
}
/* UART driver registration */
@ -415,9 +422,6 @@ static int uart_npcx_init(const struct device *dev)
*/
npcx_miwu_interrupt_configure(&config->uart_rx_wui,
NPCX_MIWU_MODE_EDGE, NPCX_MIWU_TRIG_LOW);
/* Enable irq of interrupt-input module */
npcx_miwu_irq_enable(&config->uart_rx_wui);
}
/* Configure pin-mux for uart device */
@ -544,3 +548,22 @@ static int uart_npcx_pm_control(const struct device *dev, uint32_t ctrl_command,
NPCX_UART_IRQ_CONFIG_FUNC(inst)
DT_INST_FOREACH_STATUS_OKAY(NPCX_UART_INIT)
#ifdef CONFIG_PM_DEVICE
#define ENABLE_MIWU_CRIN_IRQ(inst) \
npcx_miwu_irq_get_and_clear_pending(&uart_npcx_cfg_##inst.uart_rx_wui);\
npcx_miwu_irq_enable(&uart_npcx_cfg_##inst.uart_rx_wui);
#define DISABLE_MIWU_CRIN_IRQ(inst) \
npcx_miwu_irq_disable(&uart_npcx_cfg_##inst.uart_rx_wui);
void npcx_uart_enable_access_interrupt(void)
{
DT_INST_FOREACH_STATUS_OKAY(ENABLE_MIWU_CRIN_IRQ)
}
void npcx_uart_disable_access_interrupt(void)
{
DT_INST_FOREACH_STATUS_OKAY(DISABLE_MIWU_CRIN_IRQ)
}
#endif /* CONFIG_PM_DEVICE */

View file

@ -52,6 +52,7 @@
#include <soc.h>
#include "soc_host.h"
#include "soc_power.h"
#include <logging/log.h>
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
@ -129,6 +130,11 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode)
npcx_host_enable_access_interrupt();
}
/* Turn on UART RX wake-up interrupt. */
if (IS_ENABLED(CONFIG_UART_NPCX)) {
npcx_uart_enable_access_interrupt();
}
/*
* Capture the reading of low-freq timer for compensation before ec
* enters system sleep mode.

View file

@ -36,6 +36,16 @@ void npcx_power_console_is_in_use_refresh(void);
*/
void npcx_power_set_console_in_use_timeout(int64_t timeout);
/**
* @brief Disable UART RX wake-up interrupt.
*/
void npcx_uart_disable_access_interrupt(void);
/**
* @brief Enable UART RX wake-up interrupt.
*/
void npcx_uart_enable_access_interrupt(void);
#ifdef __cplusplus
}
#endif