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 <lijinliang1@lixiang.com>
This commit is contained in:
Jinliang Li 2024-08-16 15:21:08 +08:00 committed by Xiang Xiao
parent 40bbe7f3e9
commit 5fb0c44f38

View file

@ -139,8 +139,6 @@ static int arm_arch_timer_compare_isr(int irq, void *regs, void *arg)
struct arm_oneshot_lowerhalf_s *priv =
(struct arm_oneshot_lowerhalf_s *)arg;
arm_arch_timer_set_irq_mask(true);
if (priv->callback)
{
/* Then perform the callback */
@ -255,6 +253,11 @@ static int arm_tick_start(struct oneshot_lowerhalf_s *lower,
arm_arch_timer_set_compare(arm_arch_timer_count() +
priv->cycle_per_tick * ticks);
/* Try to unmask the timer irq in timer controller
* in case of arm_tick_cancel is called.
*/
arm_arch_timer_set_irq_mask(false);
return OK;
@ -345,14 +348,6 @@ static struct oneshot_lowerhalf_s *arm_oneshot_initialize(void)
irq_attach(ARM_ARCH_TIMER_IRQ,
arm_arch_timer_compare_isr, priv);
/* Enable int */
up_enable_irq(ARM_ARCH_TIMER_IRQ);
/* Start timer */
arm_arch_timer_enable(true);
tmrinfo("oneshot_initialize ok %p \n", &priv->lh);
return &priv->lh;
@ -380,6 +375,8 @@ void up_timer_initialize(void)
__func__, freq / 1000000, (freq / 10000) % 100);
up_alarm_set_lowerhalf(arm_oneshot_initialize());
up_enable_irq(ARM_ARCH_TIMER_IRQ);
arm_arch_timer_enable(true);
}
#ifdef CONFIG_SMP