Skip to content

Commit 962d8df

Browse files
RuibinChangkartben
authored andcommitted
drivers/counter/it8xxx2: fix loss timer interrupt potential risk
1.correct timer register control flow 2.select timer interrupt rising edge trigger, instead of default level trigger Stress test: top timer fires interrupt every 300ms for 18 hours. The result is that we don't lose any interrupts. Signed-off-by: Ruibin Chang <Ruibin.Chang@ite.com.tw>
1 parent b150b3d commit 962d8df

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

drivers/counter/counter_ite_it8xxx2.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ LOG_MODULE_REGISTER(counter_it8xxx2, CONFIG_COUNTER_LOG_LEVEL);
2424
/* ETnCTLR bit definitions (for n = 7 ~ 8) */
2525
#define ET_COMB BIT(3) /* only defined in ET7CTRL */
2626
#define ET_TC BIT(2)
27+
#define ET_RST_EN (ET_RST | ET_EN)
2728
#define ET_RST BIT(1)
2829
#define ET_EN BIT(0)
2930

@@ -35,8 +36,10 @@ struct counter_it8xxx2_config {
3536
mm_reg_t base;
3637
/* alarm timer irq */
3738
int alarm_irq;
39+
int alarm_flag;
3840
/* top timer irq */
3941
int top_irq;
42+
int top_flag;
4043
void (*irq_config_func)(const struct device *dev);
4144
};
4245

@@ -89,7 +92,7 @@ static int counter_it8xxx2_start(const struct device *dev)
8992
{
9093
LOG_DBG("starting top timer");
9194

92-
counter_it8xxx2_write8(dev, ET_EN | ET_RST, ET8CTRL);
95+
counter_it8xxx2_write8(dev, ET_RST_EN, ET8CTRL);
9396

9497
return 0;
9598
}
@@ -141,17 +144,17 @@ static int counter_it8xxx2_set_alarm(const struct device *dev, uint8_t chan_id,
141144

142145
irq_disable(config->alarm_irq);
143146

147+
counter_it8xxx2_write8(dev, counter_it8xxx2_read8(dev, ET7CTRL) & ~ET_EN, ET7CTRL);
148+
144149
counter_it8xxx2_write32(dev, alarm_cfg->ticks, ET7CNTLLR);
145150

146151
data->alarm_callback = alarm_cfg->callback;
147152
data->alarm_user_data = alarm_cfg->user_data;
148153

149-
LOG_DBG("%p Counter alarm set to %u ticks", dev, alarm_cfg->ticks);
150-
151-
counter_it8xxx2_write8(dev, counter_it8xxx2_read8(dev, ET7CTRL) | ET_EN | ET_RST, ET7CTRL);
152-
153154
ite_intc_isr_clear(config->alarm_irq);
154155

156+
counter_it8xxx2_write8(dev, counter_it8xxx2_read8(dev, ET7CTRL) | ET_RST_EN, ET7CTRL);
157+
155158
irq_enable(config->alarm_irq);
156159

157160
return 0;
@@ -212,14 +215,17 @@ static int counter_it8xxx2_set_top_value(const struct device *dev,
212215

213216
irq_disable(config->top_irq);
214217

218+
/* disable top timer */
219+
counter_it8xxx2_write8(dev, counter_it8xxx2_read8(dev, ET8CTRL) & ~ET_EN, ET8CTRL);
220+
215221
/* set new top value */
216222
counter_it8xxx2_write32(dev, top_cfg->ticks, ET8CNTLLR);
217223

218-
/* re-enable and reset timer */
219-
counter_it8xxx2_write8(dev, counter_it8xxx2_read8(dev, ET8CTRL) | ET_EN | ET_RST, ET8CTRL);
220-
221224
ite_intc_isr_clear(config->top_irq);
222225

226+
/* re-enable and reset timer */
227+
counter_it8xxx2_write8(dev, counter_it8xxx2_read8(dev, ET8CTRL) | ET_RST_EN, ET8CTRL);
228+
223229
irq_enable(config->top_irq);
224230

225231
return 0;
@@ -273,18 +279,34 @@ static void counter_it8xxx2_top_isr(const struct device *dev)
273279
static int counter_it8xxx2_init(const struct device *dev)
274280
{
275281
const struct counter_it8xxx2_config *config = dev->config;
282+
uint8_t et7_ctrl = counter_it8xxx2_read8(dev, ET7CTRL);
283+
uint8_t et8_ctrl = counter_it8xxx2_read8(dev, ET8CTRL);
276284

277285
LOG_DBG("max top value = 0x%08x", config->info.max_top_value);
278286
LOG_DBG("frequency = %d", config->info.freq);
279287
LOG_DBG("channels = %d", config->info.channels);
280288

281-
/* set the top value of top timer */
282-
counter_it8xxx2_write32(dev, config->info.max_top_value, ET8CNTLLR);
289+
/* First time enable: enable and re-start timer -> disable timer */
290+
counter_it8xxx2_write8(dev, et7_ctrl | ET_RST_EN, ET7CTRL);
291+
counter_it8xxx2_write8(dev, et7_ctrl & ~ET_EN, ET7CTRL);
292+
counter_it8xxx2_write8(dev, et8_ctrl | ET_RST_EN, ET8CTRL);
293+
counter_it8xxx2_write8(dev, et8_ctrl & ~ET_EN, ET8CTRL);
283294

284-
/* set the frequencies of alarm timer and top timer */
295+
/* Set rising edge trigger of alarm timer and top timer */
296+
ite_intc_irq_polarity_set(config->alarm_irq, config->alarm_flag);
297+
ite_intc_irq_polarity_set(config->top_irq, config->top_flag);
298+
299+
/* Clear interrupt status of alarm timer and top timer */
300+
ite_intc_isr_clear(config->alarm_irq);
301+
ite_intc_isr_clear(config->top_irq);
302+
303+
/* Select clock source of alarm timer and top timer */
285304
counter_it8xxx2_write8(dev, ETnPSR_32768HZ, ET7PSR);
286305
counter_it8xxx2_write8(dev, ETnPSR_32768HZ, ET8PSR);
287306

307+
/* Set top value ticks to top timer */
308+
counter_it8xxx2_write32(dev, config->info.max_top_value, ET8CNTLLR);
309+
288310
config->irq_config_func(dev);
289311

290312
return 0;
@@ -319,7 +341,9 @@ static DEVICE_API(counter, counter_it8xxx2_driver_api) = {
319341
}, \
320342
.base = DT_INST_REG_ADDR(n), \
321343
.alarm_irq = DT_INST_IRQN_BY_IDX(n, 0), \
344+
.alarm_flag = DT_INST_IRQ_BY_IDX(n, 0, flags), \
322345
.top_irq = DT_INST_IRQN_BY_IDX(n, 1), \
346+
.top_flag = DT_INST_IRQ_BY_IDX(n, 1, flags), \
323347
.irq_config_func = counter_it8xxx2_cfg_func_##n, \
324348
}; \
325349
\

0 commit comments

Comments
 (0)