From patchwork Thu Sep 28 22:12:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 727556 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 41BB9E743CC for ; Thu, 28 Sep 2023 22:13:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232547AbjI1WNw (ORCPT ); Thu, 28 Sep 2023 18:13:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230325AbjI1WNv (ORCPT ); Thu, 28 Sep 2023 18:13:51 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A524019D; Thu, 28 Sep 2023 15:13:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1695939213; x=1696544013; i=linosanfilippo@gmx.de; bh=nLuCqydJpbT7/9fmhJ6R8xv1g0Gm3uYcudny9uknJvc=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=iMdIbDs6hkKyO856ypck2MXVe5QSCjVfBVZtwzeeo3qsdnLk0KaFYCX6cCcPWZc7C4B/TpruqPt 4A6ra1eTSbEIOEQRdZSWh5jd6V2/cEw7i2LsOKCjGvKgpeBUfF0lsdPRy/9xTpnqtNX+oWaP9L7DD qErLrh4tCmfG9Vm2h09MiDoVskACydDsxPo234Iycl6FMIGvCsXL7Bpl9Ey1lrzG/1j7xZcCQWGg4 YyfN0eLKCwRCNwAwwvGObHYQMQF17SHRLLW+Wh2MLryoF/OdWsSXTo+waRfPD7vgv84nxrY668Hpq RICKPpXJMrVm+OX3r8LU1mVsbx/d3RFRybKA== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from Venus.speedport.ip ([84.162.21.41]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MTRR0-1rDNVw3oyq-00TnOw; Fri, 29 Sep 2023 00:13:32 +0200 From: Lino Sanfilippo To: gregkh@linuxfoundation.org, jirislaby@kernel.org Cc: shawnguo@kernel.org, s.hauer@pengutronix.de, ilpo.jarvinen@linux.intel.com, mcoquelin.stm32@gmail.com, alexandre.torgue@foss.st.com, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, l.sanfilippo@kunbus.com, LinoSanfilippo@gmx.de, lukas@wunner.de, p.rosenberger@kunbus.com, stable@vger.kernel.org Subject: [PATCH 1/6] serial: Do not hold the port lock when setting rx-during-tx GPIO Date: Fri, 29 Sep 2023 00:12:41 +0200 Message-Id: <20230928221246.13689-2-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230928221246.13689-1-LinoSanfilippo@gmx.de> References: <20230928221246.13689-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:3LQwxQSDEDvmzvUu0aiddYpQ6pCaYOyJGCzvgx6N1RGoFucwpwd 3OBRNEhvnDQUFl3ZSJeLSpSHx6WPuD4ZC+TGJCE3NVcaVAAT7VizG1Qgpy7gFmsXUDF/8lo cAXHjM5NSa2V5YALy7fTQK4Yp67C3csXzbv8L3KHUNMikH1jm7yJJBgbKtBZEoGFjT/iON8 BhjCpmToMVvydbOSb3wXg== UI-OutboundReport: notjunk:1;M01:P0:4UOvIHl79A4=;Eoatoxh+nvzVe0uNQsm1zZ1tOjV 4aQyuaiODTgaMd68fC0bW3uCoO7z5ot+NwiDsqIgX12Rg8ucC/zS6K3V309p+3fF+Bw1Uk7KI drox1azOMHM/vq7Ubn6wAqVjQ97DQtUXw5QRLfIS+RytZ7IfO0wkSb9fk+8XIMT8yEykUCk9D X78uwN21LKE3lqPUWzvBbP6datfMNPfgX6bVNFdWEcmzj6Cnl9dno3LSzJ874btGg8/zumhUp pn8lP+9lt9AaEzjasDwSn9dTbBF2q4GbAjGYkC90sl0kDjU5zlhCIE5YIx1ZjYnHqrqUyBJsP wRtX56Tnwu2rpIJMBTOySi3UlWo7LD0gQKCumNO8NumryDvK0hY2Ib7mnYjUK9BGEZvtwluY6 dkOUmqxyss5mOLh0lC2y1mSN/AjCLK+MFPzJ1AS4+3V8KbZW+uqFJ5AzCAP4EJGlaQhvdbMp3 2LG7QGcjWJFU/VA/b8m4/G1RxZ1Slhg2m5J7+LzpsDUzG5ebHRsy/R7MGcFRZ/s90XZflM1H7 azTLULNgU+DrswSTBs7ffDSsOWS4EGyURcPntyo0W3/WTbXfiIOi8Hq4D5e12UYwdk5aAHE9a VjDCPD42LzXROlcoeTpQnX9vokKmRdpiTbR6QKndUrVR1qxmRve+4nTOT7W6Ewx4xLPVRfuZM uMrmAeAx9WtKVnSO7xp3r1kuz5gC/X+nWGvqNS+3YyfVaV1aPBs6fA/iMZmndJS7HHOr4EB06 3GpA07E7aEUuTln7YYwRzHnaA5WOzf7EGvJ524JIDQxuxOjg7DRRvfeq5Zf86+wNoXxFADGTQ /mq4bAG0imdfTsHCIyPeS69V0IIg0PD5rfY3yV6LjaDKJUgtIPWtUfvdGJQnLv2X3D52so/Xk SIc/ceRfVJKmxCqY22B6tzdmFI16wsZHLVYQR8Q6IFZqB4ja7uf0dYWyzAeprKk2f9NrsOjck 8SB5Qqpd4WoU4zNLwyBV/4eHrrU= Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org From: Lino Sanfilippo Both the imx and stm32 driver set the rx-during-tx GPIO in the rs485_config() function by means of gpiod_set_value(). Since rs485_config() is called with the port lock held, this can be an problem in case that setting the GPIO line can sleep (e.g. if a GPIO expander is used which is connected via SPI or I2C). Avoid this issue by setting the GPIO outside of the port lock in the serial core and by using gpiod_set_value_cansleep() instead of gpiod_set_value(). Since now both the term and the rx-during-tx GPIO are set within the serial core use a common function uart_set_rs485_gpios() to set both. With moving it into the serial core setting the rx-during-tx GPIO is now automatically done for all drivers that support such a GPIO. Cc: stable@vger.kernel.org Signed-off-by: Lino Sanfilippo --- drivers/tty/serial/imx.c | 4 ---- drivers/tty/serial/serial_core.c | 10 ++++++---- drivers/tty/serial/stm32-usart.c | 5 +---- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 13cb78340709..edb2ec6a5567 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1947,10 +1947,6 @@ static int imx_uart_rs485_config(struct uart_port *port, struct ktermios *termio rs485conf->flags & SER_RS485_RX_DURING_TX) imx_uart_start_rx(port); - if (port->rs485_rx_during_tx_gpio) - gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, - !!(rs485conf->flags & SER_RS485_RX_DURING_TX)); - return 0; } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 7bdc21d5e13b..ef0500be3553 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1391,14 +1391,16 @@ 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) +static void uart_set_rs485_gpios(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)); + gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, + !!(rs485->flags & SER_RS485_RX_DURING_TX)); } static int uart_rs485_config(struct uart_port *port) @@ -1407,7 +1409,7 @@ static int uart_rs485_config(struct uart_port *port) int ret; uart_sanitize_serial_rs485(port, rs485); - uart_set_rs485_termination(port, rs485); + uart_set_rs485_gpios(port, rs485); ret = port->rs485_config(port, NULL, rs485); if (ret) @@ -1449,7 +1451,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); + uart_set_rs485_gpios(port, &rs485); spin_lock_irqsave(&port->lock, flags); ret = port->rs485_config(port, &tty->termios, &rs485); diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 5e9cf0c48813..8eb13bf055f2 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -226,10 +226,7 @@ static int stm32_usart_config_rs485(struct uart_port *port, struct ktermios *ter stm32_usart_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); - if (port->rs485_rx_during_tx_gpio) - gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, - !!(rs485conf->flags & SER_RS485_RX_DURING_TX)); - else + if (!port->rs485_rx_during_tx_gpio) rs485conf->flags |= SER_RS485_RX_DURING_TX; if (rs485conf->flags & SER_RS485_ENABLED) {