From patchwork Thu Aug 22 09:11:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Portia Stephens X-Patchwork-Id: 1975366 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WqHWn0RZhz1ybW for ; Thu, 22 Aug 2024 19:11:49 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1sh3r6-0001Mo-Em; Thu, 22 Aug 2024 09:11:44 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1sh3r3-0001Jn-SG for kernel-team@lists.ubuntu.com; Thu, 22 Aug 2024 09:11:41 +0000 Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 9B32D3F12E for ; Thu, 22 Aug 2024 09:11:41 +0000 (UTC) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-201f45e20b1so6463455ad.2 for ; Thu, 22 Aug 2024 02:11:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724317899; x=1724922699; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BsjkRqsbHna9+7ebCbf15pBNrC7LJlp2Cu6arQb9ZDA=; b=ftBNMPHSCaLX9Uitqq1jS7k9q+0xIxke09VMHiALCRX+hkoqAFavbeX9q8dPl0k/SB AaoHdxsHEXprg9Bu9ZRybG1JlowGe/MMBjgC+AAK6Y35Tsv7iIyCTTDIg/t9Aoy6Etpg Sz/FT489GKlPP6ZISBLlGGClobPFQpI7sFw+qInH+TyC7yjt46t/MZrppW23T+tPwQ/z FSrd/V6kScVQYr/rj43vzCc1uL8JL5RJYVeDZqwoHm2HvtN3TRmGt+RK1N7plxT+YEn/ O4MDs/4Fe7GTNIx41MZDPSWHeo5RXtzqp/BLqGfty+WaY7x4OeL69pXXj0D+fDZuA1Yd DyNQ== X-Gm-Message-State: AOJu0YyuGUCTiHz8T+7ykbgU+irGSX8f0+MprqYRPxK0cFfC0jmR4aYk ay2ahuwnTGSRjIQLzOtLj/0t92LTLGkBJAYCVhcmJ2bqSqG861nN1sGym3wgKB50RjF+g0BdAqf WTyR/q63D5uTGsk2lOtIfmWCEMW6Pkv7/y1E/pfBDfviPz6SjOqfIBkwX0Cbgquf7f1tsUFWTjJ Oju9iN2K04Dg== X-Received: by 2002:a17:902:e751:b0:202:2fc8:da35 with SMTP id d9443c01a7336-203681aab11mr60126385ad.55.1724317899379; Thu, 22 Aug 2024 02:11:39 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGknnBTKu7g/joeW8hHS9rwze/M//FSM3T6MBl9eKPm0rUt2bykakshEFxtQsIdo0xm1i2O8Q== X-Received: by 2002:a17:902:e751:b0:202:2fc8:da35 with SMTP id d9443c01a7336-203681aab11mr60126165ad.55.1724317898835; Thu, 22 Aug 2024 02:11:38 -0700 (PDT) Received: from localhost ([159.196.41.205]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2038556a2f7sm8388955ad.9.2024.08.22.02.11.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Aug 2024 02:11:38 -0700 (PDT) From: Portia Stephens To: kernel-team@lists.ubuntu.com Subject: [SRU] [jammy:linux-xilinx-zynqmp 04/14] serial: take termios_rwsem for ->rs485_config() & pass termios as param Date: Thu, 22 Aug 2024 19:11:07 +1000 Message-Id: <20240822091117.1760423-5-portia.stephens@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240822091117.1760423-1-portia.stephens@canonical.com> References: <20240822091117.1760423-1-portia.stephens@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ilpo Järvinen BugLink: https://bugs.launchpad.net/bugs/2055237 To be able to alter ADDRB within ->rs485_config(), take termios_rwsem before calling ->rs485_config() and pass termios. Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20220624204210.11112-5-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman [updated ulite_config_rs485] (cherry picked from commit ae50bb2752836277ae15aa4e9d99074d6d947946) Signed-off-by: Portia Stephens --- drivers/staging/uartlite-rs485/uartlite-rs485.c | 1 + drivers/tty/serial/8250/8250.h | 3 ++- drivers/tty/serial/8250/8250_exar.c | 9 +++++---- drivers/tty/serial/8250/8250_fintek.c | 2 +- drivers/tty/serial/8250/8250_lpc18xx.c | 2 +- drivers/tty/serial/8250/8250_pci.c | 2 +- drivers/tty/serial/8250/8250_port.c | 3 ++- drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/ar933x_uart.c | 2 +- drivers/tty/serial/atmel_serial.c | 2 +- drivers/tty/serial/fsl_lpuart.c | 4 ++-- drivers/tty/serial/imx.c | 2 +- drivers/tty/serial/max310x.c | 2 +- drivers/tty/serial/mcf.c | 3 ++- drivers/tty/serial/omap-serial.c | 3 ++- drivers/tty/serial/sc16is7xx.c | 2 +- drivers/tty/serial/serial_core.c | 16 +++++++++++----- drivers/tty/serial/stm32-usart.c | 2 +- include/linux/serial_core.h | 1 + 19 files changed, 38 insertions(+), 25 deletions(-) diff --git a/drivers/staging/uartlite-rs485/uartlite-rs485.c b/drivers/staging/uartlite-rs485/uartlite-rs485.c index 66dcdbe7e847f..a09f6deb52735 100644 --- a/drivers/staging/uartlite-rs485/uartlite-rs485.c +++ b/drivers/staging/uartlite-rs485/uartlite-rs485.c @@ -398,6 +398,7 @@ static void ulite_pm(struct uart_port *port, unsigned int state, } static int ulite_config_rs485(struct uart_port *port, + struct ktermios *termios, struct serial_rs485 *rs485conf) { port->rs485 = *rs485conf; diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index d9500a25e03ab..3426eba6d3b2f 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -181,7 +181,8 @@ void serial8250_rpm_put(struct uart_8250_port *p); void serial8250_rpm_get_tx(struct uart_8250_port *p); void serial8250_rpm_put_tx(struct uart_8250_port *p); -int serial8250_em485_config(struct uart_port *port, struct serial_rs485 *rs485); +int serial8250_em485_config(struct uart_port *port, struct ktermios *termios, + struct serial_rs485 *rs485); void serial8250_em485_start_tx(struct uart_8250_port *p); void serial8250_em485_stop_tx(struct uart_8250_port *p); void serial8250_em485_destroy(struct uart_8250_port *p); diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 48769e059772a..d861979889b06 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -122,7 +122,8 @@ struct exar8250; struct exar8250_platform { - int (*rs485_config)(struct uart_port *, struct serial_rs485 *); + int (*rs485_config)(struct uart_port *, struct ktermios *, + struct serial_rs485 *); const struct serial_rs485 *rs485_supported; int (*register_gpio)(struct pci_dev *, struct uart_8250_port *); void (*unregister_gpio)(struct uart_8250_port *); @@ -419,7 +420,7 @@ static void xr17v35x_unregister_gpio(struct uart_8250_port *port) port->port.private_data = NULL; } -static int generic_rs485_config(struct uart_port *port, +static int generic_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED); @@ -453,7 +454,7 @@ static const struct exar8250_platform exar8250_default_platform = { .rs485_supported = &generic_rs485_supported, }; -static int iot2040_rs485_config(struct uart_port *port, +static int iot2040_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED); @@ -483,7 +484,7 @@ static int iot2040_rs485_config(struct uart_port *port, value |= mode; writeb(value, p + UART_EXAR_MPIOLVL_7_0); - return generic_rs485_config(port, rs485); + return generic_rs485_config(port, termios, rs485); } static const struct serial_rs485 iot2040_rs485_supported = { diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index dba5950b8d0e2..b03de7c0a360f 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c @@ -191,7 +191,7 @@ static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min, return -ENODEV; } -static int fintek_8250_rs485_config(struct uart_port *port, +static int fintek_8250_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { uint8_t config = 0; diff --git a/drivers/tty/serial/8250/8250_lpc18xx.c b/drivers/tty/serial/8250/8250_lpc18xx.c index 570e25d6f37e3..780e81e3336ea 100644 --- a/drivers/tty/serial/8250/8250_lpc18xx.c +++ b/drivers/tty/serial/8250/8250_lpc18xx.c @@ -32,7 +32,7 @@ struct lpc18xx_uart_data { int line; }; -static int lpc18xx_rs485_config(struct uart_port *port, +static int lpc18xx_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { struct uart_8250_port *up = up_to_u8250p(port); diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 1d842bb8d9469..2d4876339b676 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1647,7 +1647,7 @@ pci_brcm_trumanage_setup(struct serial_private *priv, #define FINTEK_RTS_INVERT BIT(5) /* We should do proper H/W transceiver setting before change to RS485 mode */ -static int pci_fintek_rs485_config(struct uart_port *port, +static int pci_fintek_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { struct pci_dev *pci_dev = to_pci_dev(port->dev); diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 2d595a646bb89..d7dd643661265 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -659,7 +659,8 @@ EXPORT_SYMBOL_GPL(serial8250_em485_destroy); * if the uart is incapable of driving RTS as a Transmit Enable signal in * hardware, relying on software emulation instead. */ -int serial8250_em485_config(struct uart_port *port, struct serial_rs485 *rs485) +int serial8250_em485_config(struct uart_port *port, struct ktermios *termios, + struct serial_rs485 *rs485) { struct uart_8250_port *up = up_to_u8250p(port); diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 1db98f76b1144..53b96fc843cc0 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2294,7 +2294,7 @@ static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser) return ret; } -static int pl011_rs485_config(struct uart_port *port, +static int pl011_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { struct uart_amba_port *uap = diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 0f2677695b521..ab74fc151b2b7 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -580,7 +580,7 @@ static const struct uart_ops ar933x_uart_ops = { .verify_port = ar933x_uart_verify_port, }; -static int ar933x_config_rs485(struct uart_port *port, +static int ar933x_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485conf) { struct ar933x_uart_port *up = diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 98a3f36b40b92..654862589fa4e 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -284,7 +284,7 @@ static void atmel_tasklet_schedule(struct atmel_uart_port *atmel_port, } /* Enable or disable the rs485 support */ -static int atmel_config_rs485(struct uart_port *port, +static int atmel_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485conf) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 9f1be9ce47e03..8f91d3136669d 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1338,7 +1338,7 @@ static void lpuart_dma_rx_free(struct uart_port *port) sport->dma_rx_cookie = -EINVAL; } -static int lpuart_config_rs485(struct uart_port *port, +static int lpuart_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { struct lpuart_port *sport = container_of(port, @@ -1389,7 +1389,7 @@ static int lpuart_config_rs485(struct uart_port *port, return 0; } -static int lpuart32_config_rs485(struct uart_port *port, +static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { struct lpuart_port *sport = container_of(port, diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 0587beaaea08d..6113d5bdcffe8 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1944,7 +1944,7 @@ static void imx_uart_poll_put_char(struct uart_port *port, unsigned char c) #endif /* called with port.lock taken and irqs off or from .probe without locking */ -static int imx_uart_rs485_config(struct uart_port *port, +static int imx_uart_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485conf) { struct imx_port *sport = (struct imx_port *)port; diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 714c23f9504fc..6a1833d820f9f 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1035,7 +1035,7 @@ static void max310x_rs_proc(struct work_struct *ws) MAX310X_MODE2_ECHOSUPR_BIT, mode2); } -static int max310x_rs485_config(struct uart_port *port, +static int max310x_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { struct max310x_one *one = to_max310x_port(port); diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index c7cec7d036203..8b57fd1cac804 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -432,7 +432,8 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) /****************************************************************************/ /* Enable or disable the RS485 support */ -static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) +static int mcf_config_rs485(struct uart_port *port, struct ktermios *termios, + struct serial_rs485 *rs485) { unsigned char mr1, mr2; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 0862941862c8b..a91c91f4231dc 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1339,7 +1339,8 @@ static inline void serial_omap_add_console_port(struct uart_omap_port *up) /* Enable or disable the rs485 support */ static int -serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) +serial_omap_config_rs485(struct uart_port *port, struct ktermios *termios, + struct serial_rs485 *rs485) { struct uart_omap_port *up = to_uart_omap_port(port); unsigned int mode; diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 0066a0e235164..f0c82c3ab224a 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -969,7 +969,7 @@ static void sc16is7xx_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); } -static int sc16is7xx_config_rs485(struct uart_port *port, +static int sc16is7xx_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index f18bbfab745b4..2170721186f6b 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1290,7 +1290,7 @@ static int uart_get_rs485_config(struct uart_port *port, return 0; } -static int uart_set_rs485_config(struct uart_port *port, +static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, struct serial_rs485 __user *rs485_user) { struct serial_rs485 rs485; @@ -1330,7 +1330,7 @@ static int uart_set_rs485_config(struct uart_port *port, memset(rs485.padding, 0, sizeof(rs485.padding)); spin_lock_irqsave(&port->lock, flags); - ret = port->rs485_config(port, &rs485); + ret = port->rs485_config(port, &tty->termios, &rs485); if (!ret) { port->rs485 = rs485; @@ -1444,6 +1444,10 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) if (ret != -ENOIOCTLCMD) goto out; + /* rs485_config requires more locking than others */ + if (cmd == TIOCGRS485) + down_write(&tty->termios_rwsem); + mutex_lock(&port->mutex); uport = uart_port_check(state); @@ -1467,7 +1471,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) break; case TIOCSRS485: - ret = uart_set_rs485_config(uport, uarg); + ret = uart_set_rs485_config(tty, uport, uarg); break; case TIOCSISO7816: @@ -1484,6 +1488,8 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) } out_up: mutex_unlock(&port->mutex); + if (cmd == TIOCGRS485) + up_write(&tty->termios_rwsem); out: return ret; } @@ -2324,7 +2330,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) if (!(uport->rs485.flags & SER_RS485_ENABLED)) ops->set_mctrl(uport, uport->mctrl); else - uport->rs485_config(uport, &uport->rs485); + uport->rs485_config(uport, NULL, &uport->rs485); ops->start_tx(uport); spin_unlock_irq(&uport->lock); tty_port_set_initialized(port, 1); @@ -2442,7 +2448,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, if (!(port->rs485.flags & SER_RS485_ENABLED)) port->ops->set_mctrl(port, port->mctrl); else - port->rs485_config(port, &port->rs485); + port->rs485_config(port, NULL, &port->rs485); spin_unlock_irqrestore(&port->lock, flags); if (uart_console(port)) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 3b7d4481edbea..c0d6e61986355 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -145,7 +145,7 @@ static void stm32_usart_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE, *cr1 |= rs485_deat_dedt; } -static int stm32_usart_config_rs485(struct uart_port *port, +static int stm32_usart_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485conf) { struct stm32_port *stm32_port = to_stm32_port(port); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 75a34a0fa7546..5e52bb1419330 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -132,6 +132,7 @@ struct uart_port { unsigned int old); void (*handle_break)(struct uart_port *); int (*rs485_config)(struct uart_port *, + struct ktermios *termios, struct serial_rs485 *rs485); int (*iso7816_config)(struct uart_port *, struct serial_iso7816 *iso7816);