From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77232C3A59F for ; Wed, 23 Nov 2022 12:42:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236631AbiKWMmI (ORCPT ); Wed, 23 Nov 2022 07:42:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236846AbiKWMlt (ORCPT ); Wed, 23 Nov 2022 07:41:49 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E588E6B20D; Wed, 23 Nov 2022 04:41:24 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 72F9861C3D; Wed, 23 Nov 2022 12:41:24 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E1C4C433D6; Wed, 23 Nov 2022 12:41:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1669207283; bh=o31dvPJDA1lCb0EgEV4isP01gfzZoaAvNCc6o8K5Bas=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Vn0buG7dYQPK81ujIcBTSwvVoDdKKjl503QjLz5yB3qLHB2vwZLo72U+W3P1idmRw KKLmGxzMAJIqT09+unbw9gOY7zwqoLv/Ycovannto+xPmF4Gh6PupmsxPUbCPyYSo7 jZAjIx5i09DQlzDqoBwQ2oosiPA22OWU8jXhcqJgkJ1YEPRph+Vi0EJAqVoK0yW4WJ HFy3Yb82LSx9hQ/LiD/nVSUYFSwlUg0ZBw38iPPWB13pBwDc3ObDNPJFM2sNsGiHEE PUEPXdnyHinI461RplWqaBqaiFbWLj9uQ6z+TiIOU7UWvR/AocTl4KnQBNYXpMMmbr gHilrRqhtu1qA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Lukas Wunner , Jan Kiszka , Su Bao Cheng , Matthias Schiffer , Greg Kroah-Hartman , Sasha Levin , jirislaby@kernel.org, ilpo.jarvinen@linux.intel.com, tony@atomide.com, andriy.shevchenko@linux.intel.com, linux-serial@vger.kernel.org Subject: [PATCH AUTOSEL 6.0 09/44] serial: 8250: 8250_omap: Avoid RS485 RTS glitch on ->set_termios() Date: Wed, 23 Nov 2022 07:40:18 -0500 Message-Id: <20221123124057.264822-9-sashal@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221123124057.264822-1-sashal@kernel.org> References: <20221123124057.264822-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lukas Wunner [ Upstream commit 038ee49fef18710bedd38b531d173ccd746b2d8d ] RS485-enabled UART ports on TI Sitara SoCs with active-low polarity exhibit a Transmit Enable glitch on ->set_termios(): omap8250_restore_regs(), which is called from omap_8250_set_termios(), sets the TCRTLR bit in the MCR register and clears all other bits, including RTS. If RTS uses active-low polarity, it is now asserted for no reason. The TCRTLR bit is subsequently cleared by writing up->mcr to the MCR register. That variable is always zero, so the RTS bit is still cleared (incorrectly so if RTS is active-high). (up->mcr is not, as one might think, a cache of the MCR register's current value. Rather, it only caches a single bit of that register, the AFE bit. And it only does so if the UART supports the AFE bit, which OMAP does not. For details see serial8250_do_set_termios() and serial8250_do_set_mctrl().) Finally at the end of omap8250_restore_regs(), the MCR register is restored (and RTS deasserted) by a call to up->port.ops->set_mctrl() (which equals serial8250_set_mctrl()) and serial8250_em485_stop_tx(). So there's an RTS glitch between setting TCRTLR and calling serial8250_em485_stop_tx(). Avoid by using a read-modify-write when setting TCRTLR. While at it, drop a redundant initialization of up->mcr. As explained above, the variable isn't used by the driver and it is already initialized to zero because it is part of the static struct serial8250_ports[] declared in 8250_core.c. (Static structs are initialized to zero per section 6.7.8 nr. 10 of the C99 standard.) Cc: Jan Kiszka Cc: Su Bao Cheng Tested-by: Matthias Schiffer Signed-off-by: Lukas Wunner Link: https://lore.kernel.org/r/6554b0241a2c7fd50f32576fdbafed96709e11e8.1664278942.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/8250/8250_omap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 38ee3e42251a..8b30ae553d0a 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -292,6 +292,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up) { struct omap8250_priv *priv = up->port.private_data; struct uart_8250_dma *dma = up->dma; + u8 mcr = serial8250_in_MCR(up); if (dma && dma->tx_running) { /* @@ -308,7 +309,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up) serial_out(up, UART_EFR, UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); - serial8250_out_MCR(up, UART_MCR_TCRTLR); + serial8250_out_MCR(up, mcr | UART_MCR_TCRTLR); serial_out(up, UART_FCR, up->fcr); omap8250_update_scr(up, priv); @@ -324,7 +325,8 @@ static void omap8250_restore_regs(struct uart_8250_port *up) serial_out(up, UART_LCR, 0); /* drop TCR + TLR access, we setup XON/XOFF later */ - serial8250_out_MCR(up, up->mcr); + serial8250_out_MCR(up, mcr); + serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); @@ -669,7 +671,6 @@ static int omap_8250_startup(struct uart_port *port) pm_runtime_get_sync(port->dev); - up->mcr = 0; serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); serial_out(up, UART_LCR, UART_LCR_WLEN8); -- 2.35.1