From patchwork Sun Jul 10 16:44:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 590016 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 D91DEC43334 for ; Sun, 10 Jul 2022 16:45:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229724AbiGJQpb (ORCPT ); Sun, 10 Jul 2022 12:45:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229680AbiGJQpU (ORCPT ); Sun, 10 Jul 2022 12:45:20 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E281513E25; Sun, 10 Jul 2022 09:45:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1657471496; bh=r9kQ+eb8XdjZm2Ia2YL2lmH1Q4foW6xhwQY0wLK1kO0=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=Q+2VyhytvwOF/Ho43AS3sCGevrGN3OZMunGLb3xBpMl48zX/xQiNocBP1h11IBHbr YMO0M2doffF0EYPv5dn5oyXeWdmwpLpmNthrkyUlP6J0cEetzyz2xQZ97rpOMd6LAU d2n/dFbopqmN093Ux//1k2vRYZlLKtCm8NtjNvGo= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from localhost.localdomain ([46.223.3.243]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MHoNC-1oONqA1uYY-00Eu3u; Sun, 10 Jul 2022 18:44:56 +0200 From: Lino Sanfilippo To: gregkh@linuxfoundation.org, jirislaby@kernel.org Cc: ilpo.jarvinen@linux.intel.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, andriy.shevchenko@linux.intel.com, vz@mleia.com, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, lukas@wunner.de, p.rosenberger@kunbus.com, Lino Sanfilippo Subject: [PATCH v4 3/8] serial: core, 8250: set RS485 termination GPIO in serial core Date: Sun, 10 Jul 2022 18:44:37 +0200 Message-Id: <20220710164442.2958979-4-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710164442.2958979-1-LinoSanfilippo@gmx.de> References: <20220710164442.2958979-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:XurQd/pVhRtOn7OmlHi3+KPTToa5xwcFYC++6/bubt0RdZdvo6J gmhM2JkWta63OpaxAP0Y5e6LXwH/H+snbwgl/zqf7OOq/96WMEAQyPzh8pQjnhHb3+bpzVx OZpc/Wp308+PIBJipIYUqLakfsKJol2RctIFXlpPQEL348z1F+Oz/jCVQua1+k0ADNKzVe/ sfU9Z5eXrYB5e5OdxZ/kg== X-UI-Out-Filterresults: notjunk:1;V03:K0:XwqQq1X6clI=:DCwiGFcWHsjQeAfaCMj/Om TJnm0UR2TQiVt23i/ofuM4uMhE930cIXqxxoXhAai6QyLQ8qgvqUOFV0fY20XVS//qlSHaSAw e0AFhnqvHSgMVy9bjEhROTVXw7yIpXrblxc/TZd54aGJgP2llafFsm9qPzVYkBH85xxQ6+rsz pMW4sWfVaSOqTmWNfmrxWmfVDZoZW2VQVKhbsouUBQWPHnu7RWjV0foRfOYOevu+OEVoU+jxc cvX/2oWrYZph54eYD89xHu8Bxi1Frv885AbW/ay9Zzt+MSghCEAR65bNSz69khSJOKDKeviUi mC3gFOTXdbYjVtJ67GRisuYz7Go6+I8S+WlrQ31TMpN4EVhi4m4we0B63zGDRrRzm2EwTWbBD EG82W9iu5GCqBpqnYumwNXhadNKIrOhaJ+MKGNSOA3vI8n2YY+y0CfNEQDjgMoD9y4umvdoC+ Fo9VGh9mTSM7IGH44JUZMQv54ER0Fc4mgXdxFzUTRZ8PXwdAQQHojsx8yKmiI9J5JLl/Lx3W/ pBLsfqiWcoHyXxAlpY8pUB/ySNU1pMIe44cJU60G8ygVxyzJcnsEE4L+qqViYAlqr7aB7PNHY CYFbTSntQbuPDMAe0l2eLLLscber3pmCq06MZht4Xks9zWLBKYiDkQROtGKYRuIDq08hcUSik MTVpcyy6nXsk7xeswcs9UfuOt7DJq+rrCqSB0yCKAB8zPKQDgHbCH/CGud4LmOv46iEmT2gEn 9sQu0NIfwiyK7UcGpreZA3uRl8GZItODXlI9+6RrzKccLDwAqkw3Vq9v3o3CEytAtkT2xe6+j Ni1HrE8dbHrrA7ts7whPh0AbK8i9uwu6zgpnYhM2OJKqMPUSZ8xbp4GWV0SeDTcRhOIziOiuY dnH8PgTurz8tyI4TeyXgHDWiB2pMerIKmiZpLVeyIYhVBCesXCO7XjeD0LOeyvlsYzcQW78gc JUVUsyQQmO6BZiUtlbkabCvyoR5i1rUaC8oVhcIkOyJJnuAPAyneU9zzaYZboGtpZDHCWlemM hhKY6RO4OJ2ez5iwS6GvqQ9wiylSkfSgfYz/f3dU9NzTZKy1ICjqWm3HZHYh3gvl1wqoD35Ba 9LJM8Xiv1CXhoO2Ls8FDpMyvX+A7wDcNfDRy23pWQO0rIcaBrQYEItUdA== Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org From: Lino Sanfilippo In serial8250_em485_config() the termination GPIO is set with the uart_port spinlock held. This is an issue if setting the GPIO line can sleep (e.g. since the concerning GPIO expander is connected via SPI or I2C). Fix this by setting the termination line outside of the uart_port spinlock in the serial core and using gpiod_set_value_cansleep() which instead of gpiod_set_value() allows it to sleep. Beside fixing the termination GPIO line setting for the 8250 driver this change also makes setting the termination GPIO generic for all UART drivers. Signed-off-by: Lino Sanfilippo --- drivers/tty/serial/8250/8250_port.c | 3 --- drivers/tty/serial/serial_core.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index ed2a606f2da7..72252d956f17 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -676,9 +676,6 @@ int serial8250_em485_config(struct uart_port *port, struct ktermios *termios, rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; } - gpiod_set_value(port->rs485_term_gpio, - rs485->flags & SER_RS485_TERMINATE_BUS); - /* * Both serial8250_em485_init() and serial8250_em485_destroy() * are idempotent. diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 1db44cde76f6..047ec51dbd41 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1358,12 +1358,23 @@ static void uart_sanitize_serial_rs485(struct uart_port *port, struct serial_rs4 memset(rs485->padding1, 0, sizeof(rs485->padding1)); } +static void uart_set_rs485_termination(struct uart_port *port, + const struct serial_rs485 *rs485) +{ + if (!(rs485->flags & SER_RS485_ENABLED)) + return; + + gpiod_set_value_cansleep(port->rs485_term_gpio, + !!(rs485->flags & SER_RS485_TERMINATE_BUS)); +} + int uart_rs485_config(struct uart_port *port) { struct serial_rs485 *rs485 = &port->rs485; int ret; uart_sanitize_serial_rs485(port, rs485); + uart_set_rs485_termination(port, rs485); ret = port->rs485_config(port, NULL, rs485); if (ret) @@ -1406,6 +1417,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, if (ret) return ret; uart_sanitize_serial_rs485(port, &rs485); + uart_set_rs485_termination(port, &rs485); spin_lock_irqsave(&port->lock, flags); ret = port->rs485_config(port, &tty->termios, &rs485);