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;

Reply via email to