Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933477AbcJUJTQ (ORCPT ); Fri, 21 Oct 2016 05:19:16 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:46870 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933193AbcJUJTM (ORCPT ); Fri, 21 Oct 2016 05:19:12 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "Matwey V. Kornilov" , Yegor Yefremov , Andy Shevchenko Subject: [PATCH 4.7 03/45] serial: 8250_port: fix runtime PM use in __do_stop_tx_rs485() Date: Fri, 21 Oct 2016 11:17:23 +0200 Message-Id: <20161021091427.386657314@linuxfoundation.org> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20161021091427.214431885@linuxfoundation.org> References: <20161021091427.214431885@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2993 Lines: 87 4.7-stable review patch. If anyone has any objections, please let me know. ------------------ From: Andy Shevchenko 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. Fixes: 0c66940d584d ("tty/serial/8250: fix RS485 half-duplex RX") Cc: "Matwey V. Kornilov" Tested-by: Yegor Yefremov Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1415,12 +1415,8 @@ static void __do_stop_tx_rs485(struct ua if (!(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_stop struct 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 uart unsigned 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 uart del_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)