aboutsummaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorErwan Le Ray2021-10-20 17:03:30 +0200
committerGreg Kroah-Hartman2021-10-21 10:36:29 +0200
commitcc58d0a3f0a4755b9c808e065d9227c6e984e7db (patch)
treee87aaf29a10ebc4828e39579c3ce3bc137a3348c /drivers/tty
parent9db81eca10ba2d84177fa076704db3a5d76863c3 (diff)
serial: stm32: re-introduce an irq flag condition in usart_receive_chars
Re-introduce an irq flag condition in usart_receive_chars. This condition has been deleted by commit 75f4e830fa9c ("serial: do not restore interrupt state in sysrq helper"). This code was present to handle threaded case, and has been removed because it is no more needed in this case. Nevertheless an irq safe lock is still needed in some cases, when DMA should be stopped to receive errors or breaks in PIO mode. This patch is a precursor to the complete rework or stm32 serial driver DMA implementation. Signed-off-by: Erwan Le Ray <erwan.leray@foss.st.com> Link: https://lore.kernel.org/r/20211020150332.10214-2-erwan.leray@foss.st.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/stm32-usart.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 8f032e77b954..848e063db2ae 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -209,19 +209,22 @@ static unsigned long stm32_usart_get_char(struct uart_port *port, u32 *sr,
return c;
}
-static void stm32_usart_receive_chars(struct uart_port *port, bool threaded)
+static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag)
{
struct tty_port *tport = &port->state->port;
struct stm32_port *stm32_port = to_stm32_port(port);
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
- unsigned long c;
+ unsigned long c, flags;
u32 sr;
char flag;
- spin_lock(&port->lock);
+ if (irqflag)
+ spin_lock_irqsave(&port->lock, flags);
+ else
+ spin_lock(&port->lock);
while (stm32_usart_pending_rx(port, &sr, &stm32_port->last_res,
- threaded)) {
+ irqflag)) {
sr |= USART_SR_DUMMY_RX;
flag = TTY_NORMAL;
@@ -275,7 +278,10 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded)
uart_insert_char(port, sr, USART_SR_ORE, c, flag);
}
- uart_unlock_and_check_sysrq(port);
+ if (irqflag)
+ uart_unlock_and_check_sysrq_irqrestore(port, irqflag);
+ else
+ uart_unlock_and_check_sysrq(port);
tty_flip_buffer_push(tport);
}
@@ -496,10 +502,9 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr)
{
struct uart_port *port = ptr;
- struct stm32_port *stm32_port = to_stm32_port(port);
- if (stm32_port->rx_ch)
- stm32_usart_receive_chars(port, true);
+ /* Receiver timeout irq for DMA RX */
+ stm32_usart_receive_chars(port, false);
return IRQ_HANDLED;
}