lkml.org 
[lkml]   [2020]   [Jun]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] serial: 8250_port: Fix imprecise external abort for mctrl if inactive
Date
We can get an imprecise external abort on uart_shutdown() at
serial8250_do_set_mctrl() if the UART is autoidled.

We don't want to add PM runtime calls to serial8250_do_set_mctrl()
beyond checking the usage count as it gets called from interrupts
disabled and spinlock held from uart_update_mctrl().

We can just bail out early from serial8250_do_set_mctrl() if the UART
is inactive. We have uart_shutdown() call uart_port_dtr_rts() with
value of 0 just to disable DTR and RTS.

Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Merlijn Wajer <merlijn@wizzup.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Vignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
drivers/tty/serial/8250/8250_port.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2001,11 +2001,20 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
return serial8250_do_get_mctrl(port);
}

+/*
+ * Called from uart_update_mctrl() with spinlock held, so we don't want
+ * add PM runtime calls here beyond checking the usage count. If the
+ * UART is not active, we can just bail out early.
+ */
void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct uart_8250_port *up = up_to_u8250p(port);
unsigned char mcr;

+ if (up->capabilities & UART_CAP_RPM &&
+ !pm_runtime_get_if_in_use(up->port.dev))
+ return;
+
if (port->rs485.flags & SER_RS485_ENABLED) {
if (serial8250_in_MCR(up) & UART_MCR_RTS)
mctrl |= TIOCM_RTS;
@@ -2018,6 +2027,9 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;

serial8250_out_MCR(up, mcr);
+
+ if (up->capabilities & UART_CAP_RPM)
+ pm_runtime_put(up->port.dev);
}
EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl);

--
2.26.2
\
 
 \ /
  Last update: 2020-06-02 02:20    [W:0.050 / U:0.104 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site