From 3057f4c69ec631fc3ba204f478142c5128659ba1 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Fri, 20 Dec 2024 14:26:55 +0800 Subject: [PATCH] use small lock in: arch/arm/src/imxrt/imxrt_wdog.c arch/arm/src/kinetis/kinetis_edma.c arch/arm/src/lc823450/lc823450_dvfs2.c arch/arm/src/lc823450/lc823450_timer.c arch/arm/src/lpc54xx/lpc54_lowputc.c Signed-off-by: hujun5 --- arch/arm/src/imxrt/imxrt_wdog.c | 21 ++++++++------ arch/arm/src/kinetis/kinetis_edma.c | 39 +++++++++++++++++--------- arch/arm/src/lc823450/lc823450_dvfs2.c | 18 ++++++------ arch/arm/src/lc823450/lc823450_timer.c | 24 ++++++++-------- arch/arm/src/lpc54xx/lpc54_lowputc.c | 30 ++++++-------------- 5 files changed, 71 insertions(+), 61 deletions(-) diff --git a/arch/arm/src/imxrt/imxrt_wdog.c b/arch/arm/src/imxrt/imxrt_wdog.c index e2fa7b4d33b52..d085c21bcc16d 100644 --- a/arch/arm/src/imxrt/imxrt_wdog.c +++ b/arch/arm/src/imxrt/imxrt_wdog.c @@ -73,6 +73,7 @@ struct imxrt_wdog_lower const struct watchdog_ops_s *ops; /* Lower half operations */ uint32_t timeout; uint32_t enabled; + spinlock_t lock; }; /**************************************************************************** @@ -239,12 +240,14 @@ static int imxrt_wdog_stop(struct watchdog_lowerhalf_s *lower) static int imxrt_wdog_keepalive(struct watchdog_lowerhalf_s *lower) { - irqstate_t flags = spin_lock_irqsave(NULL); + struct imxrt_wdog_lower *priv = (struct imxrt_wdog_lower *)lower; + + irqstate_t flags = spin_lock_irqsave(&priv->lock); putreg16(WDOG_KEEP_ALIVE_KEY1, IMXRT_WDOG1_WSR); putreg16(WDOG_KEEP_ALIVE_KEY2, IMXRT_WDOG1_WSR); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); return OK; } @@ -314,7 +317,7 @@ static int imxrt_wdog_settimeout(struct watchdog_lowerhalf_s *lower, priv->timeout = timeout; - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags = spin_lock_irqsave(&priv->lock); /* write timer value to WCR WT register */ @@ -328,7 +331,7 @@ static int imxrt_wdog_settimeout(struct watchdog_lowerhalf_s *lower, putreg16(WDOG_KEEP_ALIVE_KEY1, IMXRT_WDOG1_WSR); putreg16(WDOG_KEEP_ALIVE_KEY2, IMXRT_WDOG1_WSR); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); return OK; } @@ -360,14 +363,14 @@ void imxrt_wdog_initialize(void) priv->ops = &g_wdgops; priv->timeout = WDOG_MIN; + spin_lock_init(&g_wdgdev.lock); + /* Register the watchdog driver at the path */ wdinfo("Entry: devpath=%s\n", DEVPATH); watchdog_register(DEVPATH, (struct watchdog_lowerhalf_s *)priv); } -#endif /* CONFIG_WATCHDOG && CONFIG_IMXRT_WDOG */ - /**************************************************************************** * Name: imxrt_wdog_disable * @@ -395,9 +398,11 @@ void imxrt_wdog_disable_all(void) putreg16(reg, IMXRT_WDOG2_WCR); } - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_wdgdev.lock); putreg32(RTWDOG_UPDATE_KEY, IMXRT_RTWDOG_CNT); putreg32(0xffff, IMXRT_RTWDOG_TOVAL); modifyreg32(IMXRT_RTWDOG_CS, RTWDOG_CS_EN, RTWDOG_CS_UPDATE); - leave_critical_section(flags); + spin_unlock_irqrestore(&g_wdgdev.lock, flags); } + +#endif /* CONFIG_WATCHDOG && CONFIG_IMXRT_WDOG */ \ No newline at end of file diff --git a/arch/arm/src/kinetis/kinetis_edma.c b/arch/arm/src/kinetis/kinetis_edma.c index 18c9f3c287321..1f9d57f22d439 100644 --- a/arch/arm/src/kinetis/kinetis_edma.c +++ b/arch/arm/src/kinetis/kinetis_edma.c @@ -155,6 +155,7 @@ struct kinetis_edma_s static struct kinetis_edma_s g_edma = { .chlock = NXMUTEX_INITIALIZER, + .lock = SP_UNLOCKED, #if CONFIG_KINETIS_EDMA_NTCD > 0 .dsem = SEM_INITIALIZER(CONFIG_KINETIS_EDMA_NTCD), #endif @@ -197,15 +198,16 @@ static struct kinetis_edmatcd_s *kinetis_tcd_alloc(void) * waiting. */ - flags = enter_critical_section(); nxsem_wait_uninterruptible(&g_edma.dsem); + flags = spin_lock_irqsave(&g_edma.lock); + /* Now there should be a TCD in the free list reserved just for us */ tcd = (struct kinetis_edmatcd_s *)sq_remfirst(&g_tcd_free); DEBUGASSERT(tcd != NULL); - leave_critical_section(flags); + spin_unlock_irqrestore(&g_edma.lock, flags); return tcd; } #endif @@ -219,7 +221,7 @@ static struct kinetis_edmatcd_s *kinetis_tcd_alloc(void) ****************************************************************************/ #if CONFIG_KINETIS_EDMA_NTCD > 0 -static void kinetis_tcd_free(struct kinetis_edmatcd_s *tcd) +static void kinetis_tcd_free_nolock(struct kinetis_edmatcd_s *tcd) { irqstate_t flags; @@ -228,10 +230,24 @@ static void kinetis_tcd_free(struct kinetis_edmatcd_s *tcd) * a TCD. */ - flags = spin_lock_irqsave(NULL); sq_addlast((sq_entry_t *)tcd, &g_tcd_free); nxsem_post(&g_edma.dsem); - spin_unlock_irqrestore(NULL, flags); +} + +static void kinetis_tcd_free(struct kinetis_edmatcd_s *tcd) +{ + irqstate_t flags; + + /* Add the the TCD to the end of the free list and post the 'dsem', + * possibly waking up another thread that might be waiting for + * a TCD. + */ + + flags = spin_lock_irqsave(&g_edma.lock); + sched_lock(); + kinetis_tcd_free_nolock(tcd); + sched_unlock(); + spin_unlock_irqrestore(&g_edma.lock, flags); } #endif @@ -469,7 +485,7 @@ static void kinetis_dmaterminate(struct kinetis_dmach_s *dmach, int result) next = dmach->flags & EDMA_CONFIG_LOOPDEST ? NULL : (struct kinetis_edmatcd_s *)tcd->dlastsga; - kinetis_tcd_free(tcd); + kinetis_tcd_free_nolock(tcd); } dmach->head = NULL; @@ -1114,7 +1130,7 @@ int kinetis_dmach_start(DMACH_HANDLE handle, edma_callback_t callback, /* Save the callback info. This will be invoked when the DMA completes */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_edma.lock); dmach->callback = callback; dmach->arg = arg; @@ -1139,7 +1155,7 @@ int kinetis_dmach_start(DMACH_HANDLE handle, edma_callback_t callback, putreg8(regval8, KINETIS_EDMA_SERQ); } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_edma.lock, flags); return OK; } @@ -1162,14 +1178,11 @@ int kinetis_dmach_start(DMACH_HANDLE handle, edma_callback_t callback, void kinetis_dmach_stop(DMACH_HANDLE handle) { struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle; - irqstate_t flags; dmainfo("dmach: %p\n", dmach); DEBUGASSERT(dmach != NULL); - flags = spin_lock_irqsave(NULL); kinetis_dmaterminate(dmach, -EINTR); - spin_unlock_irqrestore(NULL, flags); } /**************************************************************************** @@ -1267,7 +1280,7 @@ void kinetis_dmasample(DMACH_HANDLE handle, struct kinetis_dmaregs_s *regs) /* eDMA Global Registers */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_edma.lock); regs->cr = getreg32(KINETIS_EDMA_CR); /* Control */ regs->es = getreg32(KINETIS_EDMA_ES); /* Error Status */ @@ -1302,7 +1315,7 @@ void kinetis_dmasample(DMACH_HANDLE handle, struct kinetis_dmaregs_s *regs) regaddr = KINETIS_DMAMUX_CHCFG(chan); regs->dmamux = getreg32(regaddr); /* Channel configuration */ - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_edma.lock, flags); } #endif /* CONFIG_DEBUG_DMA */ diff --git a/arch/arm/src/lc823450/lc823450_dvfs2.c b/arch/arm/src/lc823450/lc823450_dvfs2.c index 6f70dbaff0ec1..66db5119f320d 100644 --- a/arch/arm/src/lc823450/lc823450_dvfs2.c +++ b/arch/arm/src/lc823450/lc823450_dvfs2.c @@ -68,6 +68,8 @@ * Private Data ****************************************************************************/ +static spinlock_t g_dvfs_lock = SP_UNLOCKED; + typedef struct freq_entry { uint16_t freq; @@ -428,7 +430,7 @@ static void lc823450_dvfs_do_auto(uint32_t idle[]) void lc823450_dvfs_get_idletime(uint64_t idletime[]) { - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags = spin_lock_irqsave(&g_dvfs_lock); /* First, copy g_idle_totaltime to the caller */ @@ -448,7 +450,7 @@ void lc823450_dvfs_get_idletime(uint64_t idletime[]) } #endif - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_dvfs_lock, flags); } /**************************************************************************** @@ -504,7 +506,7 @@ void lc823450_dvfs_tick_callback(void) void lc823450_dvfs_enter_idle(void) { - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags = spin_lock_irqsave(&g_dvfs_lock); int me = this_cpu(); @@ -544,7 +546,7 @@ void lc823450_dvfs_enter_idle(void) lc823450_dvfs_set_div(_dvfs_cur_idx, 1); exit_with_error: - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_dvfs_lock, flags); } /**************************************************************************** @@ -554,7 +556,7 @@ void lc823450_dvfs_enter_idle(void) void lc823450_dvfs_exit_idle(int irq) { - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags = spin_lock_irqsave(&g_dvfs_lock); int me = this_cpu(); uint64_t d; @@ -596,7 +598,7 @@ void lc823450_dvfs_exit_idle(int irq) _dvfs_cpu_is_active[me] = 1; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_dvfs_lock, flags); } /**************************************************************************** @@ -628,7 +630,7 @@ int lc823450_dvfs_set_freq(int freq) return -1; } - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_dvfs_lock); switch (freq) { @@ -656,6 +658,6 @@ int lc823450_dvfs_set_freq(int freq) lc823450_dvfs_set_div(idx, 0); } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_dvfs_lock, flags); return ret; } diff --git a/arch/arm/src/lc823450/lc823450_timer.c b/arch/arm/src/lc823450/lc823450_timer.c index d17d049bbbac2..926eeb828f5fb 100644 --- a/arch/arm/src/lc823450/lc823450_timer.c +++ b/arch/arm/src/lc823450/lc823450_timer.c @@ -148,6 +148,8 @@ static void hrt_usleep_add(struct hrt_s *phrt); * Private Data ****************************************************************************/ +static spinlock_t g_hrt_timer_queue_lock = SP_UNLOCKED; + #ifdef CHECK_INTERVAL static bool _timer_val = true; #endif @@ -185,7 +187,7 @@ static void hrt_queue_refresh(void) struct hrt_s *tmp; irqstate_t flags; - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_hrt_timer_queue_lock); elapsed = (uint64_t)getreg32(MT20CNT) * (1000 * 1000) * 10 / XT1OSC_CLK; for (pent = hrt_timer_queue.head; pent; pent = dq_next(pent)) @@ -204,9 +206,9 @@ static void hrt_queue_refresh(void) if (tmp->usec <= 0) { dq_rem(pent, &hrt_timer_queue); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_hrt_timer_queue_lock, flags); nxsem_post(&tmp->sem); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_hrt_timer_queue_lock); goto cont; } else @@ -215,7 +217,7 @@ static void hrt_queue_refresh(void) } } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_hrt_timer_queue_lock, flags); } #endif @@ -230,7 +232,7 @@ static void hrt_usleep_setup(void) struct hrt_s *head; irqstate_t flags; - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_hrt_timer_queue_lock); head = container_of(hrt_timer_queue.head, struct hrt_s, ent); if (head == NULL) { @@ -238,7 +240,7 @@ static void hrt_usleep_setup(void) modifyreg32(MCLKCNTEXT1, MCLKCNTEXT1_MTM2C_CLKEN, 0x0); modifyreg32(MCLKCNTEXT1, MCLKCNTEXT1_MTM2_CLKEN, 0x0); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_hrt_timer_queue_lock, flags); return; } @@ -260,7 +262,7 @@ static void hrt_usleep_setup(void) /* Enable MTM2-Ch0 */ putreg32(1, MT2OPR); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_hrt_timer_queue_lock, flags); } #endif @@ -299,7 +301,7 @@ static void hrt_usleep_add(struct hrt_s *phrt) hrt_queue_refresh(); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_hrt_timer_queue_lock); /* add phrt to hrt_timer_queue */ @@ -321,7 +323,7 @@ static void hrt_usleep_add(struct hrt_s *phrt) dq_addlast(&phrt->ent, &hrt_timer_queue); } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_hrt_timer_queue_lock, flags); hrt_usleep_setup(); } @@ -699,7 +701,7 @@ int up_rtc_gettime(struct timespec *tp) irqstate_t flags; uint64_t f; - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_hrt_timer_queue_lock); /* Get the elapsed time */ @@ -710,7 +712,7 @@ int up_rtc_gettime(struct timespec *tp) f = up_get_timer_fraction(); elapsed += f; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_hrt_timer_queue_lock, flags); tmrinfo("elapsed = %lld\n", elapsed); diff --git a/arch/arm/src/lpc54xx/lpc54_lowputc.c b/arch/arm/src/lpc54xx/lpc54_lowputc.c index a9145c06ada4d..14fb4d004c413 100644 --- a/arch/arm/src/lpc54xx/lpc54_lowputc.c +++ b/arch/arm/src/lpc54xx/lpc54_lowputc.c @@ -244,6 +244,8 @@ ****************************************************************************/ #ifdef HAVE_USART_CONSOLE +static spinlock_t g_console_lock = SP_UNLOCKED; + /* USART console configuration */ static const struct uart_config_s g_console_config = @@ -784,31 +786,17 @@ void arm_lowputc(char ch) #ifdef HAVE_USART_CONSOLE irqstate_t flags; - for (; ; ) - { - /* Wait for the transmit FIFO to be not full */ + /* Wait for the transmit FIFO to be not full */ - while ((getreg32(CONSOLE_BASE + LPC54_USART_FIFOSTAT_OFFSET) & - USART_FIFOSTAT_TXNOTFULL) == 0) - { - } + flags = spin_lock_irqsave(&g_console_lock); + while ((getreg32(CONSOLE_BASE + LPC54_USART_FIFOSTAT_OFFSET) & + USART_FIFOSTAT_TXNOTFULL) == 0); - /* Disable interrupts so that the fest test and the transmission are - * atomic. - */ + /* Send the character */ - flags = spin_lock_irqsave(NULL); - if ((getreg32(CONSOLE_BASE + LPC54_USART_FIFOSTAT_OFFSET) & - USART_FIFOSTAT_TXNOTFULL) != 0) - { - /* Send the character */ + putreg32((uint32_t)ch, CONSOLE_BASE + LPC54_USART_FIFOWR_OFFSET); - putreg32((uint32_t)ch, CONSOLE_BASE + LPC54_USART_FIFOWR_OFFSET); - spin_unlock_irqrestore(NULL, flags); - return; - } + spin_unlock_irqrestore(&g_console_lock, flags); - spin_unlock_irqrestore(NULL, flags); - } #endif }