Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 49 additions & 26 deletions arch/arm/src/imx9/imx9_lpuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ struct imx9_uart_s
const bool userts; /* input flow control (RTS) available */
const bool rs485mode; /* We are in RS485 (RTS on TX) mode */
const bool inviflow; /* Invert RTS sense */
spinlock_t lock; /* Spinlock */
uint32_t baud; /* Configured baud */
uint32_t ie; /* Saved enabled interrupts */
uint8_t irq; /* IRQ associated with this UART */
Expand Down Expand Up @@ -627,6 +628,7 @@ static struct imx9_uart_s g_lpuart1priv =
.irq = IMX9_IRQ_LPUART1,
.parity = CONFIG_LPUART1_PARITY,
.bits = CONFIG_LPUART1_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART1_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART1_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -686,6 +688,7 @@ static struct imx9_uart_s g_lpuart2priv =
.irq = IMX9_IRQ_LPUART2,
.parity = CONFIG_LPUART2_PARITY,
.bits = CONFIG_LPUART2_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART2_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART2_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -745,6 +748,7 @@ static struct imx9_uart_s g_lpuart3priv =
.irq = IMX9_IRQ_LPUART3,
.parity = CONFIG_LPUART3_PARITY,
.bits = CONFIG_LPUART3_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART3_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART3_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -804,6 +808,7 @@ static struct imx9_uart_s g_lpuart4priv =
.irq = IMX9_IRQ_LPUART4,
.parity = CONFIG_LPUART4_PARITY,
.bits = CONFIG_LPUART4_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART4_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART4_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -863,6 +868,7 @@ static struct imx9_uart_s g_lpuart5priv =
.irq = IMX9_IRQ_LPUART5,
.parity = CONFIG_LPUART5_PARITY,
.bits = CONFIG_LPUART5_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART5_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART5_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -922,6 +928,7 @@ static struct imx9_uart_s g_lpuart6priv =
.irq = IMX9_IRQ_LPUART6,
.parity = CONFIG_LPUART6_PARITY,
.bits = CONFIG_LPUART6_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART6_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART6_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -981,6 +988,7 @@ static struct imx9_uart_s g_lpuart7priv =
.irq = IMX9_IRQ_LPUART7,
.parity = CONFIG_LPUART7_PARITY,
.bits = CONFIG_LPUART7_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART7_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART7_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -1040,6 +1048,7 @@ static struct imx9_uart_s g_lpuart8priv =
.irq = IMX9_IRQ_LPUART8,
.parity = CONFIG_LPUART8_PARITY,
.bits = CONFIG_LPUART8_BITS,
.lock = SP_UNLOCKED,
.stopbits2 = CONFIG_LPUART8_2STOP,
# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART8_OFLOWCONTROL)
.usects = true,
Expand Down Expand Up @@ -1122,13 +1131,11 @@ static int imx9_dma_nextrx(struct imx9_uart_s *priv)
* Name: imx9_disableuartint
****************************************************************************/

static inline void imx9_disableuartint(struct imx9_uart_s *priv,
uint32_t *ie)
static inline void imx9_disableuartint_nolock(struct imx9_uart_s *priv,
uint32_t *ie)
{
irqstate_t flags;
uint32_t regval;

flags = spin_lock_irqsave(NULL);
regval = imx9_serialin(priv, IMX9_LPUART_CTRL_OFFSET);

/* Return the current Rx and Tx interrupt state */
Expand All @@ -1140,29 +1147,45 @@ static inline void imx9_disableuartint(struct imx9_uart_s *priv,

regval &= ~LPUART_ALL_INTS;
imx9_serialout(priv, IMX9_LPUART_CTRL_OFFSET, regval);
spin_unlock_irqrestore(NULL, flags);
}

static inline void imx9_disableuartint(struct imx9_uart_s *priv,
uint32_t *ie)
{
irqstate_t flags;

flags = spin_lock_irqsave(&priv->lock);
imx9_disableuartint_nolock(priv, ie);
spin_unlock_irqrestore(&priv->lock, flags);
}

/****************************************************************************
* Name: imx9_restoreuartint
****************************************************************************/

static inline void imx9_restoreuartint_nolock(struct imx9_uart_s *priv,
uint32_t ie)
{
uint32_t regval;

regval = imx9_serialin(priv, IMX9_LPUART_CTRL_OFFSET);
regval &= ~LPUART_ALL_INTS;
regval |= ie;
imx9_serialout(priv, IMX9_LPUART_CTRL_OFFSET, regval);
}

static inline void imx9_restoreuartint(struct imx9_uart_s *priv,
uint32_t ie)
uint32_t ie)
{
irqstate_t flags;
uint32_t regval;

/* Enable/disable any interrupts that are currently disabled but should be
* enabled/disabled.
*/

flags = spin_lock_irqsave(NULL);
regval = imx9_serialin(priv, IMX9_LPUART_CTRL_OFFSET);
regval &= ~LPUART_ALL_INTS;
regval |= ie;
imx9_serialout(priv, IMX9_LPUART_CTRL_OFFSET, regval);
spin_unlock_irqrestore(NULL, flags);
flags = spin_lock_irqsave(&priv->lock);
imx9_restoreuartint_nolock(priv, ie);
spin_unlock_irqrestore(&priv->lock, flags);
}

/****************************************************************************
Expand Down Expand Up @@ -1759,15 +1782,15 @@ static int imx9_ioctl(struct file *filep, int cmd, unsigned long arg)
* implement TCSADRAIN / TCSAFLUSH
*/

flags = spin_lock_irqsave(NULL);
imx9_disableuartint(priv, &ie);
flags = spin_lock_irqsave(&priv->lock);
imx9_disableuartint_nolock(priv, &ie);
ret = dev->ops->setup(dev);

/* Restore the interrupt state */

imx9_restoreuartint(priv, ie);
imx9_restoreuartint_nolock(priv, ie);
priv->ie = ie;
spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&priv->lock, flags);
}
}
break;
Expand All @@ -1779,8 +1802,8 @@ static int imx9_ioctl(struct file *filep, int cmd, unsigned long arg)
uint32_t regval;
struct imx9_uart_s *priv = (struct imx9_uart_s *)dev;

flags = spin_lock_irqsave(NULL);
regval = imx9_serialin(priv, IMX9_LPUART_CTRL_OFFSET);
flags = spin_lock_irqsave(&priv->lock);
regval = imx9_serialin(priv, IMX9_LPUART_CTRL_OFFSET);

if ((arg & SER_SINGLEWIRE_ENABLED) != 0)
{
Expand All @@ -1793,7 +1816,7 @@ static int imx9_ioctl(struct file *filep, int cmd, unsigned long arg)

imx9_serialout(priv, IMX9_LPUART_CTRL_OFFSET, regval);

spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&priv->lock, flags);
}
break;
#endif
Expand All @@ -1806,7 +1829,7 @@ static int imx9_ioctl(struct file *filep, int cmd, unsigned long arg)
uint32_t regval;
struct imx9_uart_s *priv = (struct imx9_uart_s *)dev;

flags = spin_lock_irqsave(NULL);
flags = spin_lock_irqsave(&priv->lock);
ctrl = imx9_serialin(priv, IMX9_LPUART_CTRL_OFFSET);
stat = imx9_serialin(priv, IMX9_LPUART_STAT_OFFSET);
regval = ctrl;
Expand Down Expand Up @@ -1845,7 +1868,7 @@ static int imx9_ioctl(struct file *filep, int cmd, unsigned long arg)
imx9_serialout(priv, IMX9_LPUART_STAT_OFFSET, stat);
imx9_serialout(priv, IMX9_LPUART_CTRL_OFFSET, ctrl);

spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&priv->lock, flags);
}
break;
#endif
Expand Down Expand Up @@ -1899,7 +1922,7 @@ static void imx9_rxint(struct uart_dev_s *dev, bool enable)

/* Enable interrupts for data available at Rx */

flags = spin_lock_irqsave(NULL);
flags = spin_lock_irqsave(&priv->lock);
if (enable)
{
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
Expand All @@ -1915,7 +1938,7 @@ static void imx9_rxint(struct uart_dev_s *dev, bool enable)
regval &= ~LPUART_ALL_INTS;
regval |= priv->ie;
imx9_serialout(priv, IMX9_LPUART_CTRL_OFFSET, regval);
spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&priv->lock, flags);
}
#endif

Expand Down Expand Up @@ -2320,7 +2343,7 @@ static void imx9_txint(struct uart_dev_s *dev, bool enable)

/* Enable interrupt for TX complete */

flags = spin_lock_irqsave(NULL);
flags = spin_lock_irqsave(&priv->lock);
if (enable)
{
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
Expand All @@ -2336,7 +2359,7 @@ static void imx9_txint(struct uart_dev_s *dev, bool enable)
regval &= ~LPUART_ALL_INTS;
regval |= priv->ie;
imx9_serialout(priv, IMX9_LPUART_CTRL_OFFSET, regval);
spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&priv->lock, flags);
}
#endif

Expand Down
Loading