From f7e5a103b66aa04e2c56354947ed836ba0e5e608 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 4 Sep 2023 09:34:05 +0200 Subject: [PATCH] drivers: serial: uart_cc13xx_cc26xx: fix race Fixing a race in tx/rx_constrained flag access. Signed-off-by: Florian Grandel --- drivers/serial/uart_cc13xx_cc26xx.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/serial/uart_cc13xx_cc26xx.c b/drivers/serial/uart_cc13xx_cc26xx.c index f47fdd0bbc9..e5bbf40b394 100644 --- a/drivers/serial/uart_cc13xx_cc26xx.c +++ b/drivers/serial/uart_cc13xx_cc26xx.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,12 @@ struct uart_cc13xx_cc26xx_config { uint32_t sys_clk_freq; }; +enum uart_cc13xx_cc26xx_pm_locks { + UART_CC13XX_CC26XX_PM_LOCK_TX, + UART_CC13XX_CC26XX_PM_LOCK_RX, + UART_CC13XX_CC26XX_PM_LOCK_COUNT, +}; + struct uart_cc13xx_cc26xx_data { struct uart_config uart_config; const struct pinctrl_dev_config *pcfg; @@ -35,8 +42,7 @@ struct uart_cc13xx_cc26xx_data { #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #ifdef CONFIG_PM Power_NotifyObj postNotify; - bool tx_constrained; - bool rx_constrained; + ATOMIC_DEFINE(pm_lock, UART_CC13XX_CC26XX_PM_LOCK_COUNT); #endif }; @@ -240,7 +246,7 @@ static void uart_cc13xx_cc26xx_irq_tx_enable(const struct device *dev) #ifdef CONFIG_PM struct uart_cc13xx_cc26xx_data *data = dev->data; - if (!data->tx_constrained) { + if (!atomic_test_and_set_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_TX)) { /* * When tx irq is enabled, it is implicit that we are expecting * to transmit using the uart, hence we should no longer go @@ -252,7 +258,6 @@ static void uart_cc13xx_cc26xx_irq_tx_enable(const struct device *dev) * would interfere with a transfer. */ pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->tx_constrained = true; } #endif @@ -268,9 +273,8 @@ static void uart_cc13xx_cc26xx_irq_tx_disable(const struct device *dev) #ifdef CONFIG_PM struct uart_cc13xx_cc26xx_data *data = dev->data; - if (data->tx_constrained) { + if (atomic_test_and_clear_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_TX)) { pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->tx_constrained = false; } #endif } @@ -294,9 +298,8 @@ static void uart_cc13xx_cc26xx_irq_rx_enable(const struct device *dev) * to receive from the uart, hence we can no longer go into * standby. */ - if (!data->rx_constrained) { + if (!atomic_test_and_set_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_RX)) { pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->rx_constrained = true; } #endif @@ -310,9 +313,8 @@ static void uart_cc13xx_cc26xx_irq_rx_disable(const struct device *dev) #ifdef CONFIG_PM struct uart_cc13xx_cc26xx_data *data = dev->data; - if (data->rx_constrained) { + if (atomic_test_and_clear_bit(data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_RX)) { pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); - data->rx_constrained = false; } #endif @@ -497,8 +499,8 @@ static const struct uart_driver_api uart_cc13xx_cc26xx_driver_api = { do { \ struct uart_cc13xx_cc26xx_data *dev_data = dev->data; \ \ - dev_data->rx_constrained = false; \ - dev_data->tx_constrained = false; \ + atomic_clear_bit(dev_data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_RX); \ + atomic_clear_bit(dev_data->pm_lock, UART_CC13XX_CC26XX_PM_LOCK_TX); \ \ /* Set Power dependencies */ \ if (DT_INST_REG_ADDR(n) == 0x40001000) { \