driver: itim: npcx: use timeout mechanism instead of unbounded loop.

Use timeout mechanism instead of unbounded loop during enabling ITIM32
module which source clock is LFCLK (32KHz).

Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
Mulin Chao 2021-02-18 00:08:49 -08:00 committed by Anas Nashif
commit db87ee2039

View file

@ -48,10 +48,13 @@ LOG_MODULE_REGISTER(itim, LOG_LEVEL_ERR);
#define EVT_CYCLES_PER_SEC LFCLK /* 32768 Hz */
#define SYS_CYCLES_PER_TICK (sys_clock_hw_cycles_per_sec() \
/ CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define SYS_CYCLES_PER_USEC (sys_clock_hw_cycles_per_sec() / 1000000)
#define EVT_CYCLES_FROM_TICKS(ticks) \
ceiling_fraction(ticks * EVT_CYCLES_PER_SEC, \
CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define NPCX_ITIM_CLK_SEL_DELAY 92 /* Delay for clock selection (Unit:us) */
/* Timeout for enabling ITIM module: 100us (Unit:cycles) */
#define NPCX_ITIM_EN_TIMEOUT_CYCLES (100 * SYS_CYCLES_PER_USEC)
/* Instance of system and event timers */
static struct itim64_reg *const sys_tmr = (struct itim64_reg *)
@ -79,7 +82,7 @@ static inline uint64_t npcx_itim_get_sys_cyc64(void)
/* Read 64-bit counter value from two 32-bit registers */
do {
cnt64h_check = sys_tmr->ITCNT64H;
cnt64l = sys_tmr->ITCNT64L;
cnt64l = sys_tmr->ITCNT64L;
cnt64h = sys_tmr->ITCNT64H;
} while (cnt64h != cnt64h_check);
@ -95,8 +98,10 @@ static inline uint64_t npcx_itim_get_sys_cyc64(void)
}
}
static inline void npcx_itim_evt_enable(void)
static inline int npcx_itim_evt_enable(void)
{
uint64_t cyc_start;
/* Enable event timer and wait for it to take effect */
evt_tmr->ITCTS32 |= BIT(NPCX_ITCTSXX_ITEN);
@ -104,9 +109,16 @@ static inline void npcx_itim_evt_enable(void)
* Usually, it need one clock (30.5 us) to take effect since
* asynchronization between core and itim32's source clock (LFCLK).
*/
cyc_start = npcx_itim_get_sys_cyc64();
while (!IS_BIT_SET(evt_tmr->ITCTS32, NPCX_ITCTSXX_ITEN)) {
continue;
if (npcx_itim_get_sys_cyc64() - cyc_start >
NPCX_ITIM_EN_TIMEOUT_CYCLES) {
LOG_ERR("Timeout: enabling EVT timer!");
return -ETIMEDOUT;
}
}
return 0;
}
static inline void npcx_itim_evt_disable(void)
@ -116,7 +128,7 @@ static inline void npcx_itim_evt_disable(void)
}
/* ITIM local functions */
static void npcx_itim_start_evt_tmr_by_tick(int32_t ticks)
static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks)
{
/*
* Get desired cycles of event timer from the requested ticks which
@ -143,7 +155,7 @@ static void npcx_itim_start_evt_tmr_by_tick(int32_t ticks)
evt_tmr->ITCNT32 = MAX(cyc_evt_timeout - 1, 1);
/* Enable event timer and start ticking */
npcx_itim_evt_enable();
return npcx_itim_evt_enable();
}
@ -309,7 +321,10 @@ int z_clock_driver_init(const struct device *device)
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
/* Start a event timer in one tick */
npcx_itim_start_evt_tmr_by_tick(1);
ret = npcx_itim_start_evt_tmr_by_tick(1);
if (ret < 0) {
return ret;
}
}
return 0;