3131#include <errno.h>
3232#include <debug.h>
3333
34- #include <nuttx/irq .h>
34+ #include <nuttx/spinlock .h>
3535#include <nuttx/arch.h>
3636
3737#include "arm_internal.h"
4040#include "a1x_pio.h"
4141#include "a1x_irq.h"
4242
43+ /****************************************************************************
44+ * Private Data
45+ ****************************************************************************/
46+
47+ static spinlock_t g_irq_lock = SP_UNLOCKED ;
48+
4349/****************************************************************************
4450 * Private Functions
4551 ****************************************************************************/
5359 ****************************************************************************/
5460
5561#if defined(CONFIG_DEBUG_IRQ_INFO )
56- static void a1x_dumpintc (const char * msg , int irq )
62+ static void a1x_dumpintc_nolock (const char * msg , int irq )
5763{
58- irqstate_t flags ;
59-
6064 /* Dump some relevant ARMv7 register contents */
6165
62- flags = enter_critical_section ();
63-
6466 irqinfo ("ARMv7 (%s, irq=%d):\n" , msg , irq );
6567 irqinfo (" CPSR: %08x SCTLR: %08x\n" , flags , cp15_rdsctlr ());
6668
@@ -95,10 +97,20 @@ static void a1x_dumpintc(const char *msg, int irq)
9597 getreg32 (A1X_INTC_PRIO0 ), getreg32 (A1X_INTC_PRIO1 ),
9698 getreg32 (A1X_INTC_PRIO2 ), getreg32 (A1X_INTC_PRIO3 ),
9799 getreg32 (A1X_INTC_PRIO4 ));
100+ }
101+
102+ static void a1x_dumpintc (const char * msg , int irq )
103+ {
104+ irqstate_t flags ;
105+
106+ flags = spin_lock_irqsave (& g_irq_lock );
107+
108+ a1x_dumpintc_nolock (msg , irq );
98109
99- leave_critical_section ( flags );
110+ spin_unlock_irqrestore ( & g_irq_lock , flags );
100111}
101112#else
113+ # define a1x_dumpintc_nolock (msg , irq )
102114# define a1x_dumpintc (msg , irq )
103115#endif
104116
@@ -297,7 +309,7 @@ void up_disable_irq(int irq)
297309 {
298310 /* These operations must be atomic */
299311
300- flags = enter_critical_section ( );
312+ flags = spin_lock_irqsave ( & g_irq_lock );
301313
302314 /* Make sure that the interrupt is disabled. */
303315
@@ -313,8 +325,8 @@ void up_disable_irq(int irq)
313325 regval |= INTC_MASK (irq );
314326 putreg32 (regval , regaddr );
315327
316- a1x_dumpintc ("disable" , irq );
317- leave_critical_section ( flags );
328+ a1x_dumpintc_nolock ("disable" , irq );
329+ spin_unlock_irqrestore ( & g_irq_lock , flags );
318330 }
319331
320332#ifdef CONFIG_A1X_PIO_IRQ
@@ -345,7 +357,7 @@ void up_enable_irq(int irq)
345357 {
346358 /* These operations must be atomic */
347359
348- flags = enter_critical_section ( );
360+ flags = spin_lock_irqsave ( & g_irq_lock );
349361
350362 /* Make sure that the interrupt is enabled. */
351363
@@ -361,8 +373,8 @@ void up_enable_irq(int irq)
361373 regval &= ~INTC_MASK (irq );
362374 putreg32 (regval , regaddr );
363375
364- a1x_dumpintc ("enable" , irq );
365- leave_critical_section ( flags );
376+ a1x_dumpintc_nolock ("enable" , irq );
377+ spin_unlock_irqrestore ( & g_irq_lock , flags );
366378 }
367379
368380#ifdef CONFIG_A1X_PIO_IRQ
@@ -398,7 +410,7 @@ int up_prioritize_irq(int irq, int priority)
398410 {
399411 /* These operations must be atomic */
400412
401- flags = enter_critical_section ( );
413+ flags = spin_lock_irqsave ( & g_irq_lock );
402414
403415 /* Set the new priority */
404416
@@ -408,8 +420,8 @@ int up_prioritize_irq(int irq, int priority)
408420 regval |= INTC_PRIO (irq , priority );
409421 putreg32 (regval , regaddr );
410422
411- a1x_dumpintc ("prioritize" , irq );
412- leave_critical_section ( flags );
423+ a1x_dumpintc_nolock ("prioritize" , irq );
424+ spin_unlock_irqrestore ( & g_irq_lock , flags );
413425 return OK ;
414426 }
415427
0 commit comments