Patch "serial: 8250_port: fix runtime PM use in __do_stop_tx_rs485()" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
serial: 8250_port: fix runtime PM use in __do_stop_tx_rs485()
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
serial-8250_port-fix-runtime-pm-use-in-__do_stop_tx_rs485.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
b3965767d86cf4534dfe1affbde0453d3224ed7fMon Sep 17 00:00:00 2001
From: Andy Shevchenko <[email protected]>
Date: Wed, 31 Aug 2016 19:46:55 +0300
Subject: serial: 8250_port: fix runtime PM use in __do_stop_tx_rs485()
From: Andy Shevchenko <[email protected]>
commit b3965767d86cf4534dfe1affbde0453d3224ed7f upstream.
There are calls to serial8250_rpm_{get|put}() in __do_stop_tx_rs485() that are certainly placed in a wrong location. I dunno how it had been tested with runtime PM enabled because it is obvious "sleep in atomic context" error.
Besides that serial8250_rpm_get() is called immediately after an IO just happened. It implies that the device is already powered on, see implementation of serial8250_em485_rts_after_send() and serial8250_clear_fifos() for the details.
There is no bug have been seen due to, as I can guess, use of auto suspend mode when scheduled transaction to suspend is invoked quite lately than it's needed for a few writes to the port. It might be possible to trigger a warning if stop_tx_timer fires when device is suspended.
Refactor the code to use runtime PM only in case of timer function.
--- drivers/tty/serial/8250/8250_port.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/tty/serial/8250/8250_port.c +5 -6
@@ -1415,12 +1415,8 @@ static void __do_stop_tx_rs485(struct uaif (!(p->port.rs485.flags &SER_RS485_RX_DURING_TX )) {serial8250_clear_fifos (p); -serial8250_rpm_get (p); - p->ier |=UART_IER_RLSI |UART_IER_RDI ;serial_port_out (&p->port,UART_IER , p->ier); - -serial8250_rpm_put (p); } }
@@ -1430,6 +1426,7 @@ static void serial8250_em485_handle_stopstruct uart_8250_em485 *em485 = p->em485;unsigned long flags; +serial8250_rpm_get (p);spin_lock_irqsave (&p->port.lock, flags);if (em485 && em485->active_timer == &em485->stop_tx_timer) {
@@ -1437,6 +1434,7 @@ static void serial8250_em485_handle_stop em485->active_timer =NULL ; }spin_unlock_irqrestore (&p->port.lock, flags); +serial8250_rpm_put (p); }static void __stop_tx_rs485 (struct uart_8250_port *p)
@@ -1476,7 +1474,7 @@ static inline void __stop_tx(struct uartunsigned char lsr =serial_in (p,UART_LSR );/* * To provide required timeing and allow FIFO transfer, -* __stop_tx_rs485 must be called only when both FIFO and +* __stop_tx_rs485() must be called only when both FIFO and * shift register are empty. It is for device driver to enable * interrupt on TEMT. */
@@ -1485,9 +1483,10 @@ static inline void __stop_tx(struct uartdel_timer (&em485->start_tx_timer); em485->active_timer =NULL ; + +__stop_tx_rs485 (p); }__do_stop_tx (p); -__stop_tx_rs485 (p); }static void serial8250_stop_tx (struct uart_port *port)
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/serial-8250_dw-check-the-data-pclk-when-get-apb_pclk.patch queue-4.7/serial-8250_port-fix-runtime-pm-use-in-__do_stop_tx_rs485.patch