Skip to content

Commit 5fb0c44

Browse files
jinlianglixiaoxiang781216
authored andcommitted
arm/armv8-r: optimize generic timer initialization
1. Enable timer and irq finally to make sure timer callback was already registered. When the CPU resets, the values of some generic timer registers are undefined. Enabling the timer interrupt in advance may cause the timer to trigger early while the timer callback is not yet registered. This results in the timer ISR being executed, which masks the timer interrupt. Since the timer callback is not registered at this point, the timer interrupt is not unmasked, further causing the system scheduler to hang. 2. Remove timer mask for one-shot timer and that's in isr, irq/fiq is disabled. Masking generic timer is not necessary, and it may introduce risks, otherwise, mask/unmask must be pair in all situations. Signed-off-by: Jinliang Li <[email protected]>
1 parent 40bbe7f commit 5fb0c44

File tree

1 file changed

+7
-10
lines changed

1 file changed

+7
-10
lines changed

arch/arm/src/armv8-r/arm_arch_timer.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,6 @@ static int arm_arch_timer_compare_isr(int irq, void *regs, void *arg)
139139
struct arm_oneshot_lowerhalf_s *priv =
140140
(struct arm_oneshot_lowerhalf_s *)arg;
141141

142-
arm_arch_timer_set_irq_mask(true);
143-
144142
if (priv->callback)
145143
{
146144
/* Then perform the callback */
@@ -255,6 +253,11 @@ static int arm_tick_start(struct oneshot_lowerhalf_s *lower,
255253

256254
arm_arch_timer_set_compare(arm_arch_timer_count() +
257255
priv->cycle_per_tick * ticks);
256+
257+
/* Try to unmask the timer irq in timer controller
258+
* in case of arm_tick_cancel is called.
259+
*/
260+
258261
arm_arch_timer_set_irq_mask(false);
259262

260263
return OK;
@@ -345,14 +348,6 @@ static struct oneshot_lowerhalf_s *arm_oneshot_initialize(void)
345348
irq_attach(ARM_ARCH_TIMER_IRQ,
346349
arm_arch_timer_compare_isr, priv);
347350

348-
/* Enable int */
349-
350-
up_enable_irq(ARM_ARCH_TIMER_IRQ);
351-
352-
/* Start timer */
353-
354-
arm_arch_timer_enable(true);
355-
356351
tmrinfo("oneshot_initialize ok %p \n", &priv->lh);
357352

358353
return &priv->lh;
@@ -380,6 +375,8 @@ void up_timer_initialize(void)
380375
__func__, freq / 1000000, (freq / 10000) % 100);
381376

382377
up_alarm_set_lowerhalf(arm_oneshot_initialize());
378+
up_enable_irq(ARM_ARCH_TIMER_IRQ);
379+
arm_arch_timer_enable(true);
383380
}
384381

385382
#ifdef CONFIG_SMP

0 commit comments

Comments
 (0)