This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit ea29217442c532418b3d1d766ee10150580ca1fd Author: hujun5 <[email protected]> AuthorDate: Thu Sep 5 11:19:43 2024 +0800 arm64: fix tickless mode in SMP Signed-off-by: hujun5 <[email protected]> --- arch/arm64/src/common/arm64_arch_timer.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/arm64/src/common/arm64_arch_timer.c b/arch/arm64/src/common/arm64_arch_timer.c index 39f0923b42..9f72decc2e 100644 --- a/arch/arm64/src/common/arm64_arch_timer.c +++ b/arch/arm64/src/common/arm64_arch_timer.c @@ -70,6 +70,8 @@ struct arm64_oneshot_lowerhalf_s void *arg; /* Argument that is passed to the handler */ uint64_t cycle_per_tick; /* cycle per tick */ oneshot_callback_t callback; /* Internal handler that receives callback */ + bool running; /* True: timer is running */ + bool init[CONFIG_SMP_NCPUS]; /* True: timer is init */ }; /**************************************************************************** @@ -155,7 +157,7 @@ static int arm64_arch_timer_compare_isr(int irq, void *regs, void *arg) arm64_arch_timer_set_irq_mask(true); - if (priv->callback) + if (priv->callback && priv->running) { /* Then perform the callback */ @@ -226,6 +228,7 @@ static int arm64_tick_cancel(struct oneshot_lowerhalf_s *lower, /* Disable int */ + priv->running = false; arm64_arch_timer_set_irq_mask(true); return OK; @@ -266,6 +269,20 @@ static int arm64_tick_start(struct oneshot_lowerhalf_s *lower, priv->callback = callback; priv->arg = arg; + if (!priv->init[this_cpu()]) + { + /* Enable int */ + + up_enable_irq(ARM_ARCH_TIMER_IRQ); + + /* Start timer */ + + arm64_arch_timer_enable(true); + priv->init[this_cpu()] = true; + } + + priv->running = true; + next_cycle = arm64_arch_timer_count() / priv->cycle_per_tick * priv->cycle_per_tick + ticks * priv->cycle_per_tick; @@ -365,14 +382,6 @@ struct oneshot_lowerhalf_s *arm64_oneshot_initialize(void) irq_attach(ARM_ARCH_TIMER_IRQ, arm64_arch_timer_compare_isr, priv); - /* Enable int */ - - up_enable_irq(ARM_ARCH_TIMER_IRQ); - - /* Start timer */ - - arm64_arch_timer_enable(true); - tmrinfo("oneshot_initialize ok %p \n", &priv->lh); return &priv->lh;
