From 8411a97b85c9d12b9268284aab9c1537e8d8f202 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Fri, 20 Dec 2024 19:07:08 +0800 Subject: [PATCH] use small lock in following files arch/xtensa/src/esp32s3/esp32s3_rtc_lowerhalf.c arch/z16/src/z16f/z16f_serial.c arch/z80/src/z8/z8_serial.c boards/arm/max326xx/max32660-evsys/src/max326_button.c boards/arm/stm32/stm32f4discovery/src/stm32_gs2200m.c drivers/i2c/i2c_bitbang.c drivers/power/supply/act8945a.c drivers/serial/uart_pci_16550.c drivers/serial/uart_pl011.c drivers/wireless/bluetooth/bt_uart_shim.c Signed-off-by: hujun5 --- .../src/esp32s3/esp32s3_rtc_lowerhalf.c | 12 ++-- arch/z16/src/z16f/z16f_serial.c | 50 +++++++++++----- arch/z80/src/z8/z8_serial.c | 59 ++++++++++++------- .../max32660-evsys/src/max326_button.c | 12 +++- .../stm32f4discovery/src/stm32_gs2200m.c | 18 +++--- drivers/i2c/i2c_bitbang.c | 6 +- drivers/power/supply/act8945a.c | 15 +++-- drivers/serial/uart_pci_16550.c | 11 +++- drivers/serial/uart_pl011.c | 14 +++-- drivers/wireless/bluetooth/bt_uart_shim.c | 6 +- include/nuttx/serial/uart_16550.h | 2 + 11 files changed, 138 insertions(+), 67 deletions(-) diff --git a/arch/xtensa/src/esp32s3/esp32s3_rtc_lowerhalf.c b/arch/xtensa/src/esp32s3/esp32s3_rtc_lowerhalf.c index 115b764e2c..483625e492 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_rtc_lowerhalf.c +++ b/arch/xtensa/src/esp32s3/esp32s3_rtc_lowerhalf.c @@ -61,6 +61,7 @@ struct esp32s3_lowerhalf_s */ const struct rtc_ops_s *ops; + spinlock_t lock; #ifdef CONFIG_RTC_ALARM /* Alarm callback information */ @@ -116,6 +117,7 @@ static const struct rtc_ops_s g_rtc_ops = static struct esp32s3_lowerhalf_s g_rtc_lowerhalf = { .ops = &g_rtc_ops, + .lock = SP_UNLOCKED, }; /**************************************************************************** @@ -376,6 +378,7 @@ static int rtc_lh_setalarm(struct rtc_lowerhalf_s *lower, static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower, const struct lower_setrelative_s *alarminfo) { + struct esp32s3_lowerhalf_s *priv = (struct esp32s3_lowerhalf_s *)lower; struct lower_setalarm_s setalarm; time_t seconds; int ret = -EINVAL; @@ -387,7 +390,7 @@ static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower, if (alarminfo->reltime > 0) { - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&priv->lock); seconds = alarminfo->reltime; gmtime_r(&seconds, (struct tm *)&setalarm.time); @@ -399,7 +402,7 @@ static int rtc_lh_setrelative(struct rtc_lowerhalf_s *lower, setalarm.priv = alarminfo->priv; ret = rtc_lh_setalarm(lower, &setalarm); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); } return ret; @@ -466,6 +469,7 @@ static int rtc_lh_cancelalarm(struct rtc_lowerhalf_s *lower, int alarmid) static int rtc_lh_rdalarm(struct rtc_lowerhalf_s *lower, struct lower_rdalarm_s *alarminfo) { + struct esp32s3_lowerhalf_s *priv = (struct esp32s3_lowerhalf_s *)lower; struct timespec ts; int ret; irqstate_t flags; @@ -474,13 +478,13 @@ static int rtc_lh_rdalarm(struct rtc_lowerhalf_s *lower, DEBUGASSERT((RTC_ALARM0 <= alarminfo->id) && (alarminfo->id < RTC_ALARM_LAST)); - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&priv->lock); ret = up_rtc_rdalarm(&ts, alarminfo->id); localtime_r((const time_t *)&ts.tv_sec, (struct tm *)alarminfo->time); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); return ret; } diff --git a/arch/z16/src/z16f/z16f_serial.c b/arch/z16/src/z16f/z16f_serial.c index b45ad9dede..e432a76bd5 100644 --- a/arch/z16/src/z16f/z16f_serial.c +++ b/arch/z16/src/z16f/z16f_serial.c @@ -70,6 +70,7 @@ struct z16f_uart_s uint8_t rxirq; /* RX IRQ associated with this UART */ uint8_t txirq; /* RX IRQ associated with this UART */ uint8_t parity; /* 0=none, 1=odd, 2=even */ + spinlock_t lock; /* */ bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ }; @@ -139,6 +140,7 @@ static struct z16f_uart_s g_uart0priv = Z16F_IRQ_UART0RX, /* rxirq */ Z16F_IRQ_UART0TX, /* txirq */ CONFIG_UART0_PARITY, /* parity */ + SP_UNLOCKED, /* Spinlock */ CONFIG_UART0_2STOP /* stopbits2 */ }; @@ -157,6 +159,7 @@ static struct z16f_uart_s g_uart1priv = Z16F_IRQ_UART1RX, /* rxirq */ Z16F_IRQ_UART1TX, /* txirq */ CONFIG_UART1_PARITY, /* parity */ + SP_UNLOCKED, /* Spinlock */ CONFIG_UART1_2STOP /* stopbits2 */ }; @@ -215,16 +218,16 @@ static uart_dev_t g_uart1port; static uint8_t z16f_disableuartirq(struct uart_dev_s *dev) { struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags = spin_lock_irqsave(&priv->lock); uint8_t state = priv->rxenabled ? STATE_RXENABLED : STATE_DISABLED | priv->txenabled ? STATE_TXENABLED : STATE_DISABLED; - z16f_txint(dev, false); - z16f_rxint(dev, false); + z16f_txint_nolock(dev, false); + z16f_rxint_nolock(dev, false); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); return state; } @@ -234,12 +237,13 @@ static uint8_t z16f_disableuartirq(struct uart_dev_s *dev) static void z16f_restoreuartirq(struct uart_dev_s *dev, uint8_t state) { - irqstate_t flags = spin_lock_irqsave(NULL); + struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; + irqstate_t flags = spin_lock_irqsave(&priv->lock); - z16f_txint(dev, (state & STATE_TXENABLED) ? true : false); - z16f_rxint(dev, (state & STATE_RXENABLED) ? true : false); + z16f_txint_nolock(dev, (state & STATE_TXENABLED) ? true : false); + z16f_rxint_nolock(dev, (state & STATE_RXENABLED) ? true : false); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** @@ -507,10 +511,9 @@ static int z16f_receive(struct uart_dev_s *dev, uint32_t *status) * ****************************************************************************/ -static void z16f_rxint(struct uart_dev_s *dev, bool enable) +static void z16f_rxint_nolock(struct uart_dev_s *dev, bool enable) { - struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; - irqstate_t flags = enter_critical_section(); + struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; if (enable) { @@ -524,7 +527,15 @@ static void z16f_rxint(struct uart_dev_s *dev, bool enable) } priv->rxenabled = enable; - leave_critical_section(flags); +} + +static void z16f_rxint(struct uart_dev_s *dev, bool enable) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; + irqstate_t flags = spin_lock_irqsave(&priv->lock); + + z16f_rxint_nolock(dev, enable); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** @@ -564,10 +575,9 @@ static void z16f_send(struct uart_dev_s *dev, int ch) * ****************************************************************************/ -static void z16f_txint(struct uart_dev_s *dev, bool enable) +static void z16f_txint_nolock(struct uart_dev_s *dev, bool enable) { - struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; - irqstate_t flags = enter_critical_section(); + struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; if (enable) { @@ -587,7 +597,15 @@ static void z16f_txint(struct uart_dev_s *dev, bool enable) } priv->txenabled = enable; - leave_critical_section(flags); +} + +static void z16f_txint(struct uart_dev_s *dev, bool enable) +{ + struct z16f_uart_s *priv = (struct z16f_uart_s *)dev->priv; + irqstate_t flags = spin_lock_irqsave(&priv->lock); + + z16f_txint_nolock(dev, enable); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** diff --git a/arch/z80/src/z8/z8_serial.c b/arch/z80/src/z8/z8_serial.c index 09516c2093..feb63355f4 100644 --- a/arch/z80/src/z8/z8_serial.c +++ b/arch/z80/src/z8/z8_serial.c @@ -70,6 +70,7 @@ struct z8_uart_s uint8_t rxirq; /* RX IRQ associated with this UART */ uint8_t txirq; /* RX IRQ associated with this UART */ uint8_t parity; /* 0=none, 1=odd, 2=even */ + spinlock_t lock; /* Spinlock */ bool stopbits2; /* true: Configure with 2 stop bits * (instead of 1) */ }; @@ -134,6 +135,7 @@ static struct z8_uart_s g_uart0priv = Z8_UART0_RX_IRQ, /* rxirq */ Z8_UART0_TX_IRQ, /* txirq */ CONFIG_UART0_PARITY, /* parity */ + SP_UNLOCKED, /* Spinlock */ CONFIG_UART0_2STOP /* stopbits2 */ }; @@ -179,6 +181,7 @@ static struct z8_uart_s g_uart1priv = Z8_UART1_RX_IRQ, /* rxirq */ Z8_UART1_TX_IRQ, /* txirq */ CONFIG_UART1_PARITY, /* parity */ + SP_UNLOCKED, /* Spinlock */ CONFIG_UART1_2STOP /* stopbits2 */ }; @@ -254,17 +257,17 @@ static inline uint8_t z8_getuart(FAR struct z8_uart_s *priv, uint8_t offset) static uint8_t z8_disableuartirq(FAR struct uart_dev_s *dev) { - struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; - irqstate_t flags = spin_lock_irqsave(NULL); - uint8_t state = priv->rxenabled ? - STATE_RXENABLED : STATE_DISABLED | \ - priv->txenabled ? - STATE_TXENABLED : STATE_DISABLED; + struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; + irqstate_t flags = spin_lock_irqsave(&priv->lock); + uint8_t state = priv->rxenabled ? + STATE_RXENABLED : STATE_DISABLED | \ + priv->txenabled ? + STATE_TXENABLED : STATE_DISABLED; - z8_txint(dev, false); - z8_rxint(dev, false); + z8_txint_nolock(dev, false); + z8_rxint_nolock(dev, false); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); return state; } @@ -274,12 +277,12 @@ static uint8_t z8_disableuartirq(FAR struct uart_dev_s *dev) static void z8_restoreuartirq(FAR struct uart_dev_s *dev, uint8_t state) { - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags = spin_lock_irqsave(&priv->lock); - z8_txint(dev, (state & STATE_TXENABLED) ? true : false); - z8_rxint(dev, (state & STATE_RXENABLED) ? true : false); + z8_txint_nolock(dev, (state & STATE_TXENABLED) ? true : false); + z8_rxint_nolock(dev, (state & STATE_RXENABLED) ? true : false); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** @@ -582,10 +585,9 @@ static int z8_receive(FAR struct uart_dev_s *dev, FAR uint32_t *status) * ****************************************************************************/ -static void z8_rxint(FAR struct uart_dev_s *dev, bool enable) +static void z8_rxint_nolock(FAR struct uart_dev_s *dev, bool enable) { - struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; - irqstate_t flags = enter_critical_section(); + struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; if (enable) { @@ -599,7 +601,15 @@ static void z8_rxint(FAR struct uart_dev_s *dev, bool enable) } priv->rxenabled = enable; - leave_critical_section(flags); +} + +static void z8_rxint(FAR struct uart_dev_s *dev, bool enable) +{ + struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; + irqstate_t flags = spin_lock_irqsave(&priv->lock); + + z8_rxint_nolock(dev, enable); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** @@ -638,10 +648,9 @@ static void z8_send(FAR struct uart_dev_s *dev, int ch) * ****************************************************************************/ -static void z8_txint(FAR struct uart_dev_s *dev, bool enable) +static void z8_txint_nolock(FAR struct uart_dev_s *dev, bool enable) { - struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; - irqstate_t flags = enter_critical_section(); + struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; if (enable) { @@ -655,7 +664,15 @@ static void z8_txint(FAR struct uart_dev_s *dev, bool enable) } priv->txenabled = enable; - leave_critical_section(flags); +} + +static void z8_txint(FAR struct uart_dev_s *dev, bool enable) +{ + struct z8_uart_s *priv = (struct z8_uart_s *)dev->priv; + irqstate_t flags = spin_lock_irqsave(&priv->lock); + + z8_txint_nolock(dev, enable); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** diff --git a/boards/arm/max326xx/max32660-evsys/src/max326_button.c b/boards/arm/max326xx/max32660-evsys/src/max326_button.c index 7dee8e905f..26f88d1df9 100644 --- a/boards/arm/max326xx/max32660-evsys/src/max326_button.c +++ b/boards/arm/max326xx/max32660-evsys/src/max326_button.c @@ -43,6 +43,14 @@ #ifdef CONFIG_ARCH_BUTTONS +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_PIOB_IRQ) && defined(CONFIG_ARCH_IRQBUTTONS) +static spinlock_t g_max326_lock = SP_UNLOCKED; +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -108,7 +116,7 @@ int board_button_irq(int id, xcpt_t irqhandler, void *arg) * following operations are atomic. */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&g_max326_lock); /* Are we attaching or detaching? */ @@ -127,7 +135,7 @@ int board_button_irq(int id, xcpt_t irqhandler, void *arg) irq_detach(BUTTON_IRQ); } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_max326_lock, flags); ret = OK; } diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_gs2200m.c b/boards/arm/stm32/stm32f4discovery/src/stm32_gs2200m.c index 22113a6f8d..18ecefc81d 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32_gs2200m.c +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_gs2200m.c @@ -67,6 +67,8 @@ static void gs2200m_reset(bool); * Private Data ****************************************************************************/ +static spinlock_t g_gs2200m_lock = SP_UNLOCKED; + static const struct gs2200m_lower_s g_wifi_lower = { .attach = gs2200m_irq_attach, @@ -106,17 +108,18 @@ static int gs2200m_irq_attach(xcpt_t handler, void *arg) static void gs2200m_irq_enable(void) { - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags; uint32_t dready = 0; wlinfo("== ec:%" PRId32 " called=%" PRId32 "\n", _enable_count, _n_called++); + flags = spin_lock_irqsave(&g_gs2200m_lock); if (0 == _enable_count) { /* Check if irq has been asserted */ - dready = gs2200m_dready(NULL); + dready = gs2200m_dready(&g_gs2200m_lock); /* NOTE: stm32 does not support level-triggered irq */ @@ -126,7 +129,7 @@ static void gs2200m_irq_enable(void) _enable_count++; - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_gs2200m_lock, flags); if (dready) { @@ -143,11 +146,12 @@ static void gs2200m_irq_enable(void) static void gs2200m_irq_disable(void) { - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags; wlinfo("== ec:%" PRId32 " called=%" PRId32 "\n", _enable_count, _n_called++); + flags = spin_lock_irqsave(&g_gs2200m_lock); _enable_count--; if (0 == _enable_count) @@ -156,7 +160,7 @@ static void gs2200m_irq_disable(void) false, NULL, NULL); } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_gs2200m_lock, flags); } /**************************************************************************** @@ -165,7 +169,7 @@ static void gs2200m_irq_disable(void) static uint32_t gs2200m_dready(int *ec) { - irqstate_t flags = spin_lock_irqsave(NULL); + irqstate_t flags = spin_lock_irqsave(&g_gs2200m_lock); uint32_t r = stm32_gpioread(GPIO_GS2200M_INT); @@ -176,7 +180,7 @@ static uint32_t gs2200m_dready(int *ec) *ec = _enable_count; } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&g_gs2200m_lock, flags); return r; } diff --git a/drivers/i2c/i2c_bitbang.c b/drivers/i2c/i2c_bitbang.c index e99c3b3a4e..dd9a84f61d 100644 --- a/drivers/i2c/i2c_bitbang.c +++ b/drivers/i2c/i2c_bitbang.c @@ -48,6 +48,7 @@ struct i2c_bitbang_dev_s { struct i2c_master_s i2c; struct i2c_bitbang_lower_dev_s *lower; + spinlock_t lock; #ifndef CONFIG_I2C_BITBANG_NO_DELAY int32_t delay; @@ -116,7 +117,7 @@ static int i2c_bitbang_transfer(FAR struct i2c_master_s *dev, /* Lock to enforce timings */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&priv->lock); for (i = 0; i < count; i++) { @@ -245,7 +246,7 @@ out: i2c_bitbang_set_scl(priv, true, false); i2c_bitbang_set_sda(priv, true); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); return ret; } @@ -391,6 +392,7 @@ FAR struct i2c_master_s *i2c_bitbang_initialize( dev->i2c.ops = &g_i2c_ops; dev->lower = lower; dev->lower->ops->initialize(dev->lower); + spin_lock_init(&dev->lock); return &dev->i2c; } diff --git a/drivers/power/supply/act8945a.c b/drivers/power/supply/act8945a.c index c8c3a32d34..6bf7aada70 100644 --- a/drivers/power/supply/act8945a.c +++ b/drivers/power/supply/act8945a.c @@ -298,6 +298,7 @@ struct regulator_act8945a_priv int i2c_freq; FAR const struct regulator_desc_s *regulators; FAR struct regulator_dev_s *rdev; + spinlock_t lock; }; struct act8945a_dev_s @@ -457,9 +458,9 @@ static int act8945a_getreg(FAR struct regulator_act8945a_priv *priv, /* Write the register address */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&priv->lock); ret = i2c_write(priv->i2c, &config, ®addr, sizeof(regaddr)); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); if (ret < 0) { act8945a_err("ERROR: i2c_write failed: %d\n", ret); @@ -468,9 +469,9 @@ static int act8945a_getreg(FAR struct regulator_act8945a_priv *priv, /* Restart and read 8 bits from the register */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&priv->lock); ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval)); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); if (ret < 0) { act8945a_err("ERROR: i2c_read failed: %d\n", ret); @@ -525,9 +526,9 @@ static int act8945a_putreg(FAR struct regulator_act8945a_priv *priv, /* Write the register address followed by the data (no RESTART) */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&priv->lock); ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer)); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&priv->lock, flags); if (ret < 0) { @@ -1031,6 +1032,8 @@ int act8945a_initialize(FAR struct i2c_master_s *i2c, unsigned int vsel) priv->i2c_addr = ACT8945A_SLAVE_ADDRESS; priv->i2c_freq = ACT8945A_BUS_SPEED; + spin_lock_init(&priv->lock); + /* Early test to see if we can read the ACT8945A. * * We do this by writing a data pattern into the 4 scratch bits of SYS1 diff --git a/drivers/serial/uart_pci_16550.c b/drivers/serial/uart_pci_16550.c index 28f886e2ff..a2a27b421a 100644 --- a/drivers/serial/uart_pci_16550.c +++ b/drivers/serial/uart_pci_16550.c @@ -239,6 +239,7 @@ static struct pci_u16550_priv_s g_pci_u16550_priv0 = .flow = true, #endif .rxtrigger = 2, + .lock = SP_UNLOCKED }, /* PCI specific data */ @@ -287,6 +288,7 @@ static struct pci_u16550_priv_s g_pci_u16550_priv1 = .flow = true, #endif .rxtrigger = 2, + .lock = SP_UNLOCKED }, /* PCI specific data */ @@ -335,6 +337,7 @@ static struct pci_u16550_priv_s g_pci_u16550_priv2 = .flow = true, #endif .rxtrigger = 2, + .lock = SP_UNLOCKED }, /* PCI specific data */ @@ -381,6 +384,7 @@ static struct pci_u16550_priv_s g_pci_u16550_priv3 = .flow = true, #endif .rxtrigger = 2, + .lock = SP_UNLOCKED }, /* PCI specific data */ @@ -755,6 +759,7 @@ static int pci_u16550_probe(FAR struct pci_device_s *dev) #ifdef CONFIG_16550_PCI_CONSOLE void up_putc(int ch) { + FAR struct u16550_s *priv = CONSOLE_DEV.priv; irqstate_t flags; /* Console not initialized yet */ @@ -768,9 +773,9 @@ void up_putc(int ch) * interrupts from firing in the serial driver code. */ - flags = spin_lock_irqsave(NULL); - u16550_putc(CONSOLE_DEV.priv, ch); - spin_unlock_irqrestore(NULL, flags); + flags = spin_lock_irqsave(&priv->lock); + u16550_putc(priv, ch); + spin_unlock_irqrestore(&priv->lock, flags); } #endif diff --git a/drivers/serial/uart_pl011.c b/drivers/serial/uart_pl011.c index 3532584747..4ce110c453 100644 --- a/drivers/serial/uart_pl011.c +++ b/drivers/serial/uart_pl011.c @@ -228,6 +228,7 @@ struct pl011_uart_port_s struct pl011_data data; struct pl011_config config; unsigned int irq_num; + spinlock_t lock; }; static int pl011_setup(FAR struct uart_dev_s *dev); @@ -307,6 +308,7 @@ static struct pl011_uart_port_s g_uart0priv = }, .irq_num = CONFIG_UART0_IRQ, + .lock = SP_UNLOCKED, }; /* I/O buffers */ @@ -350,6 +352,7 @@ static struct pl011_uart_port_s g_uart1priv = }, .irq_num = CONFIG_UART1_IRQ, + .lock = SP_UNLOCKED, }; /* I/O buffers */ @@ -393,6 +396,7 @@ static struct pl011_uart_port_s g_uart2priv = }, .irq_num = CONFIG_UART2_IRQ, + .lock = SP_UNLOCKED, }; /* I/O buffers */ @@ -436,6 +440,7 @@ static struct pl011_uart_port_s g_uart3priv = }, .irq_num = CONFIG_UART3_IRQ, + .lock = SP_UNLOCKED, }; /* I/O buffers */ @@ -670,12 +675,13 @@ static void pl011_send(FAR struct uart_dev_s *dev, int ch) static void pl011_putc(struct uart_dev_s *dev, int ch) { + FAR struct pl011_uart_port_s *sport = dev->priv; irqstate_t flags; - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&sport->lock); while (!pl011_txempty(dev)); pl011_send(dev, ch); - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&sport->lock, flags); } /*************************************************************************** @@ -737,7 +743,7 @@ static void pl011_txint(FAR struct uart_dev_s *dev, bool enable) FAR struct pl011_uart_port_s *sport = dev->priv; irqstate_t flags; - flags = enter_critical_section(); + flags = spin_lock_irqsave(&sport->lock); if (enable) { @@ -754,7 +760,7 @@ static void pl011_txint(FAR struct uart_dev_s *dev, bool enable) pl011_irq_tx_disable(sport); } - leave_critical_section(flags); + spin_unlock_irqrestore(&sport->lock, flags); } /*************************************************************************** diff --git a/drivers/wireless/bluetooth/bt_uart_shim.c b/drivers/wireless/bluetooth/bt_uart_shim.c index 73c07c69c5..f91e73b24e 100644 --- a/drivers/wireless/bluetooth/bt_uart_shim.c +++ b/drivers/wireless/bluetooth/bt_uart_shim.c @@ -59,6 +59,7 @@ struct hciuart_state_s struct file f; /* File structure */ struct pollfd p; /* Poll structure */ + spinlock_t lock; /* Spinlock */ }; struct hciuart_config_s @@ -120,7 +121,7 @@ hciuart_rxattach(FAR const struct btuart_lowerhalf_s *lower, /* If the callback is NULL, then we are detaching */ - flags = spin_lock_irqsave(NULL); + flags = spin_lock_irqsave(&state->lock); if (callback == NULL) { /* Disable Rx callbacks and detach the Rx callback */ @@ -137,7 +138,7 @@ hciuart_rxattach(FAR const struct btuart_lowerhalf_s *lower, state->callback = callback; } - spin_unlock_irqrestore(NULL, flags); + spin_unlock_irqrestore(&state->lock, flags); } /**************************************************************************** @@ -373,6 +374,7 @@ FAR struct btuart_lowerhalf_s *btuart_shim_getdevice(FAR const char *path) s->p.events = POLLIN; s->p.arg = n; s->p.cb = hciuart_rxpollcb; + spin_lock_init(&s->lock); /* Hook the routines in */ diff --git a/include/nuttx/serial/uart_16550.h b/include/nuttx/serial/uart_16550.h index ad77ca391b..9acd75a87a 100644 --- a/include/nuttx/serial/uart_16550.h +++ b/include/nuttx/serial/uart_16550.h @@ -30,6 +30,7 @@ #include #include +#include #ifdef CONFIG_16550_UART @@ -376,6 +377,7 @@ struct u16550_s #endif #endif uart_datawidth_t rxtrigger; /* RX trigger level */ + spinlock_t lock; /* Spinlock */ }; /****************************************************************************