From patchwork Thu Jun 10 18:38:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 458237 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-20.2 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CBF4C48BE5 for ; Thu, 10 Jun 2021 18:38:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 54DF8613F5 for ; Thu, 10 Jun 2021 18:38:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230481AbhFJSkg (ORCPT ); Thu, 10 Jun 2021 14:40:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230508AbhFJSkf (ORCPT ); Thu, 10 Jun 2021 14:40:35 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [IPv6:2001:4190:8020::4]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id BD388C061574; Thu, 10 Jun 2021 11:38:38 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id 1FBF79200BB; Thu, 10 Jun 2021 20:38:34 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 19DB59200B4; Thu, 10 Jun 2021 20:38:34 +0200 (CEST) Date: Thu, 10 Jun 2021 20:38:34 +0200 (CEST) From: "Maciej W. Rozycki" To: Greg Kroah-Hartman , Jiri Slaby , Thomas Bogendoerfer cc: linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/5] serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Support for magic baud rate divisors of 32770 and 32769 used with SMSC Super I/O chips for extra baud rates of 230400 and 460800 respectively where base rate is 115200[1] has been added around Linux 2.5.64, which predates our repo history, but the origin could be identified as commit 2a717aad772f ("Merge with Linux 2.5.64.") with the old MIPS/Linux repo also at: . Code that is now in `serial8250_do_get_divisor' was added back then to `serial8250_get_divisor', but that code would only ever trigger if one of the higher baud rates was actually requested, and that cannot ever happen, because the earlier call to `serial8250_get_baud_rate' never returns them. This is because it calls `uart_get_baud_rate' with the maximum requested being the base rate, that is clk/16 or 115200 for SMSC chips at their nominal clock rate. Fix it then and allow UPF_MAGIC_MULTIPLIER baud rates to be selected, by requesting the maximum baud rate of clk/4 rather than clk/16 if the flag has been set. Also correct the minimum baud rate, observing that these ports only support actual (non-magic) divisors of up to 32767 only. References: [1] "FDC37M81x, PC98/99 Compliant Enhanced Super I/O Controller with Keyboard/Mouse Wake-Up", Standard Microsystems Corporation, Rev. 03/27/2000, Table 31 - "Baud Rates", p. 77 Signed-off-by: Maciej W. Rozycki Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") --- drivers/tty/serial/8250/8250_port.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) linux-serial-8250-magic-multiplier-baud-rate.diff Index: linux-malta-cbus-uart/drivers/tty/serial/8250/8250_port.c =================================================================== --- linux-malta-cbus-uart.orig/drivers/tty/serial/8250/8250_port.c +++ linux-malta-cbus-uart/drivers/tty/serial/8250/8250_port.c @@ -2659,6 +2659,21 @@ static unsigned int serial8250_get_baud_ struct ktermios *old) { unsigned int tolerance = port->uartclk / 100; + unsigned int min; + unsigned int max; + + /* + * Handle magic divisors for baud rates above baud_base on SMSC + * Super I/O chips. Enable custom rates of clk/4 and clk/8, but + * disable divisor values beyond 32767, which are unavailable. + */ + if (port->flags & UPF_MAGIC_MULTIPLIER) { + min = port->uartclk / 16 / UART_DIV_MAX >> 1; + max = (port->uartclk + tolerance) / 4; + } else { + min = port->uartclk / 16 / UART_DIV_MAX; + max = (port->uartclk + tolerance) / 16; + } /* * Ask the core to calculate the divisor for us. @@ -2666,9 +2681,7 @@ static unsigned int serial8250_get_baud_ * slower than nominal still match standard baud rates without * causing transmission errors. */ - return uart_get_baud_rate(port, termios, old, - port->uartclk / 16 / UART_DIV_MAX, - (port->uartclk + tolerance) / 16); + return uart_get_baud_rate(port, termios, old, min, max); } /* From patchwork Thu Jun 10 18:38:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 458236 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.2 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06E9FC48BDF for ; Thu, 10 Jun 2021 18:38:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E638161407 for ; Thu, 10 Jun 2021 18:38:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231174AbhFJSkm (ORCPT ); Thu, 10 Jun 2021 14:40:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231179AbhFJSkl (ORCPT ); Thu, 10 Jun 2021 14:40:41 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [IPv6:2001:4190:8020::4]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1DE11C061574; Thu, 10 Jun 2021 11:38:45 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id 708B29200C0; Thu, 10 Jun 2021 20:38:44 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 6DE549200B4; Thu, 10 Jun 2021 20:38:44 +0200 (CEST) Date: Thu, 10 Jun 2021 20:38:44 +0200 (CEST) From: "Maciej W. Rozycki" To: Greg Kroah-Hartman , Jiri Slaby , Thomas Bogendoerfer cc: linux-mips@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/5] serial: core, 8250: Add a hook for extra port property reporting In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org Add a hook for `uart_report_port' to let serial ports report extra properties beyond `irq' and `base_baud'. Use it with the 8250 backend to report extra baud rates supported above the base rate for ports with the UPF_MAGIC_MULTIPLIER property, so that people have a way to find out that they are supported with their system, e.g.: Serial: 8250/16550 driver, 5 ports, IRQ sharing enabled printk: console [ttyS0] disabled serial8250.0: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200 [+230400, 460800]) is a 16550A printk: console [ttyS0] enabled printk: console [ttyS0] enabled printk: bootconsole [uart8250] disabled printk: bootconsole [uart8250] disabled serial8250.0: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200 [+230400, 460800]) is a 16550A serial8250.0: ttyS2 at MMIO 0x1f000900 (irq = 20, base_baud = 230400) is a 16550A Otherwise there is no clear way to figure this out. Signed-off-by: Maciej W. Rozycki --- drivers/tty/serial/8250/8250_core.c | 10 ++++++++++ drivers/tty/serial/serial_core.c | 11 +++++++++-- include/linux/serial_core.h | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-) linux-serial-core-baud-extra.diff Index: linux-malta-cbus-uart/drivers/tty/serial/8250/8250_core.c =================================================================== --- linux-malta-cbus-uart.orig/drivers/tty/serial/8250/8250_core.c +++ linux-malta-cbus-uart/drivers/tty/serial/8250/8250_core.c @@ -952,6 +952,13 @@ static struct uart_8250_port *serial8250 return NULL; } +static void serial8250_report_magic(struct uart_port *port, + char *report_buf, size_t report_size) +{ + snprintf(report_buf, report_size, + " [+%d, %d]", port->uartclk / 8, port->uartclk / 4); +} + static void serial_8250_overrun_backoff_work(struct work_struct *work) { struct uart_8250_port *up = @@ -1048,6 +1055,9 @@ int serial8250_register_8250_port(struct } } + if (up->port.flags & UPF_MAGIC_MULTIPLIER) + uart->port.report_extra = serial8250_report_magic; + serial8250_set_defaults(uart); /* Possibly override default I/O functions. */ Index: linux-malta-cbus-uart/drivers/tty/serial/serial_core.c =================================================================== --- linux-malta-cbus-uart.orig/drivers/tty/serial/serial_core.c +++ linux-malta-cbus-uart/drivers/tty/serial/serial_core.c @@ -2309,6 +2309,7 @@ int uart_resume_port(struct uart_driver static inline void uart_report_port(struct uart_driver *drv, struct uart_port *port) { + char report_extra[64]; char address[64]; switch (port->iotype) { @@ -2333,11 +2334,17 @@ uart_report_port(struct uart_driver *drv break; } - pr_info("%s%s%s at %s (irq = %d, base_baud = %d) is a %s\n", + if (port->report_extra) + port->report_extra(port, report_extra, sizeof(report_extra)); + else + report_extra[0] = '\0'; + + pr_info("%s%s%s at %s (irq = %d, base_baud = %d%s) is a %s\n", port->dev ? dev_name(port->dev) : "", port->dev ? ": " : "", port->name, - address, port->irq, port->uartclk / 16, uart_type(port)); + address, port->irq, port->uartclk / 16, report_extra, + uart_type(port)); } static void Index: linux-malta-cbus-uart/include/linux/serial_core.h =================================================================== --- linux-malta-cbus-uart.orig/include/linux/serial_core.h +++ linux-malta-cbus-uart/include/linux/serial_core.h @@ -135,6 +135,9 @@ struct uart_port { struct serial_rs485 *rs485); int (*iso7816_config)(struct uart_port *, struct serial_iso7816 *iso7816); + void (*report_extra)(struct uart_port *port, + char *report_buf, + size_t report_size); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */