From patchwork Wed May 6 23:31:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 11532035 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 321FB913 for ; Wed, 6 May 2020 23:32:24 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 100FA20735 for ; Wed, 6 May 2020 23:32:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="dz/Vgf2B" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 100FA20735 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=baikalelectronics.ru Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=z9Tm6t4nG9Fkmbpxfxv6BaFZ7GZ/TOb5kTzr1FZ92OI=; b=dz/Vgf2B1k5v3/ 1SWkPSGjEb6jjr+sPkW5pVYQ6m5IH1AI8EJJ+jDW6KDhbVMZwMAAF425COQRyaV7LMTxlpXsJYi78 U74vjyAFz/DSfCTUrua3TtGtHVV+uhPjaNntsMRPAsOHApQZi8i5Iowgk0g5akpCozrDUmnDnCZ47 au/5EdAaTpBrXfXMOG7gjGQEMInwrGGP2TUpJdOo2TzzvLoo/DWKdY7PO2eTUk6xFiQthRYubkIO3 zynXFRixo3WU+6WL6TEZ+vA6uewXGUmpDJBay6jJfAY15AtrWLf79eCl3VK3P7tbmImv1ZjpiatBB ZibuxL7Yx1aShLFJcclw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jWTWY-0002Zo-HM; Wed, 06 May 2020 23:32:22 +0000 Received: from ns2.baikalelectronics.com ([94.125.187.42] helo=mail.baikalelectronics.ru) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jWTW7-00025B-CB; Wed, 06 May 2020 23:31:57 +0000 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 2DBD4803087B; Wed, 6 May 2020 23:31:53 +0000 (UTC) X-Virus-Scanned: amavisd-new at baikalelectronics.ru Received: from mail.baikalelectronics.ru ([127.0.0.1]) by localhost (mail.baikalelectronics.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wQ_eRoPPIA7H; Thu, 7 May 2020 02:31:52 +0300 (MSK) From: Serge Semin To: Thomas Bogendoerfer , Greg Kroah-Hartman , Jiri Slaby Subject: [PATCH v3 2/4] serial: 8250: Add 8250 port clock update method Date: Thu, 7 May 2020 02:31:33 +0300 Message-ID: <20200506233136.11842-3-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20200506233136.11842-1-Sergey.Semin@baikalelectronics.ru> References: <20200323024611.16039-1-Sergey.Semin@baikalelectronics.ru> <20200506233136.11842-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200506_163155_767469_1724E887 X-CRM114-Status: GOOD ( 13.05 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vignesh Raghavendra , Catalin Marinas , Dmitry Safonov <0x7f454c46@gmail.com>, Yegor Yefremov , Serge Semin , Stefan Roese , Will Deacon , Paul Burton , Russell King , Long Cheng , linux-arm-kernel@lists.infradead.org, linux-serial@vger.kernel.org, Arnd Bergmann , Maxime Ripard , Alexey Malahov , linux-mediatek@lists.infradead.org, Thomas Gleixner , Andy Shevchenko , Mika Westerberg , Allison Randal , linux-mips@vger.kernel.org, Ralf Baechle , linux-kernel@vger.kernel.org, Serge Semin , Lukas Wunner Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org Some platforms can be designed in a way so the UART port reference clock might be asynchronously changed at some point. In Baikal-T1 SoC this may happen due to the reference clock being shared between two UART ports, on the Allwinner SoC the reference clock is derived from the CPU clock, so any CPU frequency change should get to be known/reflected by/in the UART controller as well. But it's not enough to just update the uart_port->uartclk field of the corresponding UART port, the 8250 controller reference clock divisor should be altered so to preserve current baud rate setting. All of these things is done in a coherent way by calling the serial8250_update_uartclk() method provided in this patch. Though note that it isn't supposed to be called from within the UART port callbacks because the locks using to the protect the UART port data are already taken in there. Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Arnd Bergmann Cc: Long Cheng Cc: Andy Shevchenko Cc: Maxime Ripard Cc: Catalin Marinas Cc: Will Deacon Cc: Russell King Cc: linux-mips@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-mediatek@lists.infradead.org --- drivers/tty/serial/8250/8250_port.c | 38 +++++++++++++++++++++++++++++ include/linux/serial_8250.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 4d83c85a7389..484ff9df1432 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2628,6 +2628,44 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, (port->uartclk + tolerance) / 16); } +/* + * Note in order to avoid the tty port mutex deadlock don't use the next method + * within the uart port callbacks. Primarily it's supposed to be utilized to + * handle a sudden reference clock rate change. + */ +void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) +{ + struct uart_8250_port *up = up_to_u8250p(port); + unsigned int baud, quot, frac = 0; + struct ktermios *termios; + unsigned long flags; + + mutex_lock(&port->state->port.mutex); + + if (port->uartclk == uartclk) + goto out_lock; + + port->uartclk = uartclk; + termios = &port->state->port.tty->termios; + + baud = serial8250_get_baud_rate(port, termios, NULL); + quot = serial8250_get_divisor(port, baud, &frac); + + spin_lock_irqsave(&port->lock, flags); + + uart_update_timeout(port, termios->c_cflag, baud); + + serial8250_set_divisor(port, baud, quot, frac); + serial_port_out(port, UART_LCR, up->lcr); + serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); + + spin_unlock_irqrestore(&port->lock, flags); + +out_lock: + mutex_unlock(&port->state->port.mutex); +} +EXPORT_SYMBOL(serial8250_update_uartclk); + void serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 6545f8cfc8fa..2b70f736b091 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -155,6 +155,8 @@ extern int early_serial_setup(struct uart_port *port); extern int early_serial8250_setup(struct earlycon_device *device, const char *options); +extern void serial8250_update_uartclk(struct uart_port *port, + unsigned int uartclk); extern void serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old); extern void serial8250_do_set_ldisc(struct uart_port *port,