* [PATCH 1/2] serial: stm32: Return IRQ_NONE in the ISR if no handling happend
[not found] <cover.1713344161.git.u.kleine-koenig@pengutronix.de>
@ 2024-04-17 9:03 ` Uwe Kleine-König
2024-04-17 9:03 ` [PATCH 2/2] serial: stm32: Reset .throttled state in .startup() Uwe Kleine-König
1 sibling, 0 replies; 2+ messages in thread
From: Uwe Kleine-König @ 2024-04-17 9:03 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Maxime Coquelin
Cc: Andy Shevchenko, kernel, Alexandre Torgue, Valentin Caron,
Lino Sanfilippo, Thomas Gleixner, Erwan Le Ray, Peter Hurley,
Vladimir Zapolskiy, linux-serial, linux-stm32, linux-arm-kernel,
stable
If there is a stuck irq that the handler doesn't address, returning
IRQ_HANDLED unconditionally makes it impossible for the irq core to
detect the problem and disable the irq. So only return IRQ_HANDLED if
an event was handled.
A stuck irq is still problematic, but with this change at least it only
makes the UART nonfunctional instead of occupying the (usually only) CPU
by 100% and so stall the whole machine.
Fixes: 48a6092fb41f ("serial: stm32-usart: Add STM32 USART Driver")
Cc: stable@vger.kernel.org
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
drivers/tty/serial/stm32-usart.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 8c66abcfe6ca..2bea1d7c9858 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -849,6 +849,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 sr;
unsigned int size;
+ irqreturn_t ret = IRQ_NONE;
sr = readl_relaxed(port->membase + ofs->isr);
@@ -857,11 +858,14 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
(sr & USART_SR_TC)) {
stm32_usart_tc_interrupt_disable(port);
stm32_usart_rs485_rts_disable(port);
+ ret = IRQ_HANDLED;
}
- if ((sr & USART_SR_RTOF) && ofs->icr != UNDEF_REG)
+ if ((sr & USART_SR_RTOF) && ofs->icr != UNDEF_REG) {
writel_relaxed(USART_ICR_RTOCF,
port->membase + ofs->icr);
+ ret = IRQ_HANDLED;
+ }
if ((sr & USART_SR_WUF) && ofs->icr != UNDEF_REG) {
/* Clear wake up flag and disable wake up interrupt */
@@ -870,6 +874,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_WUFIE);
if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
pm_wakeup_event(tport->tty->dev, 0);
+ ret = IRQ_HANDLED;
}
/*
@@ -884,6 +889,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
uart_unlock_and_check_sysrq(port);
if (size)
tty_flip_buffer_push(tport);
+ ret = IRQ_HANDLED;
}
}
@@ -891,6 +897,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
uart_port_lock(port);
stm32_usart_transmit_chars(port);
uart_port_unlock(port);
+ ret = IRQ_HANDLED;
}
/* Receiver timeout irq for DMA RX */
@@ -900,9 +907,10 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
uart_unlock_and_check_sysrq(port);
if (size)
tty_flip_buffer_push(tport);
+ ret = IRQ_HANDLED;
}
- return IRQ_HANDLED;
+ return ret;
}
static void stm32_usart_set_mctrl(struct uart_port *port, unsigned int mctrl)
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 2/2] serial: stm32: Reset .throttled state in .startup()
[not found] <cover.1713344161.git.u.kleine-koenig@pengutronix.de>
2024-04-17 9:03 ` [PATCH 1/2] serial: stm32: Return IRQ_NONE in the ISR if no handling happend Uwe Kleine-König
@ 2024-04-17 9:03 ` Uwe Kleine-König
1 sibling, 0 replies; 2+ messages in thread
From: Uwe Kleine-König @ 2024-04-17 9:03 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Maxime Coquelin
Cc: Andy Shevchenko, kernel, Alexandre Torgue, Valentin Caron,
Lino Sanfilippo, Thomas Gleixner, Erwan Le Ray, Peter Hurley,
Vladimir Zapolskiy, linux-serial, linux-stm32, linux-arm-kernel,
stable
When an UART is opened that still has .throttled set from a previous
open, the RX interrupt is enabled but the irq handler doesn't consider
it. This easily results in a stuck irq with the effect to occupy the CPU
in a tight loop.
So reset the throttle state in .startup() to ensure that RX irqs are
handled.
Fixes: d1ec8a2eabe9 ("serial: stm32: update throttle and unthrottle ops for dma mode")
Cc: stable@vger.kernel.org
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
drivers/tty/serial/stm32-usart.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 2bea1d7c9858..e1e7bc04c579 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1080,6 +1080,7 @@ static int stm32_usart_startup(struct uart_port *port)
val |= USART_CR2_SWAP;
writel_relaxed(val, port->membase + ofs->cr2);
}
+ stm32_port->throttled = false;
/* RX FIFO Flush */
if (ofs->rqr != UNDEF_REG)
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-04-17 9:04 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <cover.1713344161.git.u.kleine-koenig@pengutronix.de>
2024-04-17 9:03 ` [PATCH 1/2] serial: stm32: Return IRQ_NONE in the ISR if no handling happend Uwe Kleine-König
2024-04-17 9:03 ` [PATCH 2/2] serial: stm32: Reset .throttled state in .startup() Uwe Kleine-König
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).