From patchwork Tue Jul 14 12:41:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 11662799 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 2B085618 for ; Tue, 14 Jul 2020 12:43:18 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 0328D208FE for ; Tue, 14 Jul 2020 12:43:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="B0Chw2EB" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0328D208FE 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-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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:In-Reply-To:References:List-Owner; bh=Hd5bWLVnub47Ijiul+7GyoKwXwPozdfA5E2O8Ra3aEM=; b=B0Chw2EB8EkR2VDU+YB+ByxlZS fl3KTqw7ZBE18a1aU+GNZG8cxBxZY7gMlHnmRS4g0geKPuBim9fiI4tBv8nAInlsxeMUxyuWD/2Qa 7VpXfStftMcb4Yym/AJU/9Vz+AudEVUozrne1JAfsLKTC8t+e6t8x/Z0HF9Ope4DkfSTVNgnoHaVo SxiuDnQWqp1rTaNVDrZB7X/fyexbGUcoABZCWmjuCQsddwb9wwWgyxqCMAisKHIYeTaawx66v/pVs apQjQ+1I2/qIEufKqtWDfe+glsMgTyycEYiP/YAVzAXz7ATQg6cJqMBodH5WliH1JKcpkTH23ZiVI FFGFQYJw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jvKFX-0003vC-1t; Tue, 14 Jul 2020 12:41:31 +0000 Received: from ns2.baikalelectronics.ru ([94.125.187.42] helo=mail.baikalelectronics.ru) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jvKFQ-0003qb-52; Tue, 14 Jul 2020 12:41:25 +0000 Received: from localhost (unknown [127.0.0.1]) by mail.baikalelectronics.ru (Postfix) with ESMTP id F1F208030809; Tue, 14 Jul 2020 12:41:19 +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 wvIaP-V6CogS; Tue, 14 Jul 2020 15:41:18 +0300 (MSK) From: Serge Semin To: Greg Kroah-Hartman , Jiri Slaby , Matthias Brugger Subject: [PATCH] serial: 8250_mtk: Fix high-speed baud rates clamping Date: Tue, 14 Jul 2020 15:41:12 +0300 Message-ID: <20200714124113.20918-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-20200714_084124_638896_33E2C9EE X-CRM114-Status: GOOD ( 15.10 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.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-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chromeos-bluetooth-upstreaming , Vignesh Raghavendra , linux-kernel@vger.kernel.org, Serge Semin , Alexey Malahov , Serge Semin , BlueZ , Lukas Wunner , linux-mediatek@lists.infradead.org, stable@vger.kernel.org, linux-serial@vger.kernel.org, Daniel Winkler , abhishekpandit@chromium.org, Aaron Sierra , Andy Shevchenko , linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Commit 7b668c064ec3 ("serial: 8250: Fix max baud limit in generic 8250 port") fixed limits of a baud rate setting for a generic 8250 port. In other words since that commit the baud rate has been permitted to be within [uartclk / 16 / UART_DIV_MAX; uartclk / 16], which is absolutely normal for a standard 8250 UART port. But there are custom 8250 ports, which provide extended baud rate limits. In particular the Mediatek 8250 port can work with baud rates up to "uartclk" speed. Normally that and any other peculiarity is supposed to be handled in a custom set_termios() callback implemented in the vendor-specific 8250-port glue-driver. Currently that is how it's done for the most of the vendor-specific 8250 ports, but for some reason for Mediatek a solution has been spread out to both the glue-driver and to the generic 8250-port code. Due to that a bug has been introduced, which permitted the extended baud rate limit for all even for standard 8250-ports. The bug has been fixed by the commit 7b668c064ec3 ("serial: 8250: Fix max baud limit in generic 8250 port") by narrowing the baud rates limit back down to the normal bounds. Unfortunately by doing so we also broke the Mediatek-specific extended bauds feature. A fix of the problem described above is twofold. First since we can't get back the extended baud rate limits feature to the generic set_termios() function and that method supports only a standard baud rates range, the requested baud rate must be locally stored before calling it and then restored back to the new termios structure after the generic set_termios() finished its magic business. By doing so we still use the serial8250_do_set_termios() method to set the LCR/MCR/FCR/etc. registers, while the extended baud rate setting procedure will be performed later in the custom Mediatek-specific set_termios() callback. Second since a true baud rate is now fully calculated in the custom set_termios() method we need to locally update the port timeout by calling the uart_update_timeout() function. After the fixes described above are implemented in the 8250_mtk.c driver, the Mediatek 8250-port should get back to normally working with extended baud rates. Link: https://lore.kernel.org/linux-serial/20200701211337.3027448-1-danielwinkler@google.com Fixes: 7b668c064ec3 ("serial: 8250: Fix max baud limit in generic 8250 port") Reported-by: Daniel Winkler Signed-off-by: Serge Semin Tested-by: Claire Chang --- Folks, sorry for a delay with the problem fix. A solution is turned out to be a bit more complicated than I originally thought in my comment to the Daniel revert-patch. Please also note, that I don't have a Mediatek hardware to test the solution suggested in the patch. The code is written as on so called the tip of the pen after digging into the 8250_mtk.c and 8250_port.c drivers code. So please Daniel or someone with Mediatek 8250-port available on a board test this patch first and report about the results in reply to this emailing thread. After that, if your conclusion is positive and there is no objection against the solution design the patch can be merged in. Cc: Alexey Malahov Cc: Daniel Winkler Cc: Aaron Sierra Cc: Andy Shevchenko Cc: Lukas Wunner Cc: Vignesh Raghavendra Cc: linux-serial@vger.kernel.org Cc: linux-mediatek@lists.infradead.org Cc: BlueZ Cc: chromeos-bluetooth-upstreaming Cc: abhishekpandit@chromium.org Cc: stable@vger.kernel.org --- drivers/tty/serial/8250/8250_mtk.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index f839380c2f4c..98b8a3e30733 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -306,8 +306,21 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, } #endif + /* + * Store the requested baud rate before calling the generic 8250 + * set_termios method. Standard 8250 port expects bauds to be + * no higher than (uartclk / 16) so the baud will be clamped if it + * gets out of that bound. Mediatek 8250 port supports speed + * higher than that, therefore we'll get original baud rate back + * after calling the generic set_termios method and recalculate + * the speed later in this method. + */ + baud = tty_termios_baud_rate(termios); + serial8250_do_set_termios(port, termios, old); + tty_termios_encode_baud_rate(termios, baud, baud); + /* * Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS) * @@ -339,6 +352,11 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, */ spin_lock_irqsave(&port->lock, flags); + /* + * Update the per-port timeout. + */ + uart_update_timeout(port, termios->c_cflag, baud); + /* set DLAB we have cval saved in up->lcr from the call to the core */ serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); serial_dl_write(up, quot);