aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250/8250_fsl.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2021-07-14 10:04:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-21 12:53:26 +0200
commit853a9ae29e978d37f5dfa72622a68c9ae3d7fa89 (patch)
treec3f2b62c6447e6b7fae006107281233aa99dfcce /drivers/tty/serial/8250/8250_fsl.c
parentserial: tegra: Only print FIFO error message when an error occurs (diff)
downloadlinux-stable-853a9ae29e978d37f5dfa72622a68c9ae3d7fa89.tar.xz
linux-stable-853a9ae29e978d37f5dfa72622a68c9ae3d7fa89.zip
serial: 8250: fix handle_irq locking
The 8250 handle_irq callback is not just called from the interrupt handler but also from a timer callback when polling (e.g. for ports without an interrupt line). Consequently the callback must explicitly disable interrupts to avoid a potential deadlock with another interrupt in polled mode. Add back an irqrestore-version of the sysrq port-unlock helper and use it in the 8250 callbacks that need it. Fixes: 75f4e830fa9c ("serial: do not restore interrupt state in sysrq helper") Cc: stable@vger.kernel.org # 5.13 Cc: Joel Stanley <joel@jms.id.au> Cc: Andrew Jeffery <andrew@aj.id.au> Reported-by: kernel test robot <oliver.sang@intel.com> Signed-off-by: Johan Hovold <johan@kernel.org> Link: https://lore.kernel.org/r/20210714080427.28164-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250/8250_fsl.c')
-rw-r--r--drivers/tty/serial/8250/8250_fsl.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
index 4e75d2e4f87c..fc65a2293ce9 100644
--- a/drivers/tty/serial/8250/8250_fsl.c
+++ b/drivers/tty/serial/8250/8250_fsl.c
@@ -30,10 +30,11 @@ struct fsl8250_data {
int fsl8250_handle_irq(struct uart_port *port)
{
unsigned char lsr, orig_lsr;
+ unsigned long flags;
unsigned int iir;
struct uart_8250_port *up = up_to_u8250p(port);
- spin_lock(&up->port.lock);
+ spin_lock_irqsave(&up->port.lock, flags);
iir = port->serial_in(port, UART_IIR);
if (iir & UART_IIR_NO_INT) {
@@ -82,7 +83,7 @@ int fsl8250_handle_irq(struct uart_port *port)
up->lsr_saved_flags = orig_lsr;
- uart_unlock_and_check_sysrq(&up->port);
+ uart_unlock_and_check_sysrq_irqrestore(&up->port, flags);
return 1;
}