Patch "serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates" has been added to the 5.13-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates

to the 5.13-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     serial-8250-actually-allow-upf_magic_multiplier-baud.patch
and it can be found in the queue-5.13 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4fd479710993ffdaf609f70b7d11919e473b3703
Author: Maciej W. Rozycki <macro@xxxxxxxxxxx>
Date:   Thu Jun 10 20:38:34 2021 +0200

    serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates
    
    [ Upstream commit 78bcae8616ac277d6cb7f38e211493948ed73e30 ]
    
    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: <git://git.kernel.org/pub/scm/linux/kernel/git/ralf/linux.git>.
    
    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
    
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Maciej W. Rozycki <macro@xxxxxxxxxxx>
    Link: https://lore.kernel.org/r/alpine.DEB.2.21.2105190412280.29169@xxxxxxxxxxxxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index fc5ab2032282..ff3f13693def 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2629,6 +2629,21 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port,
 					     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.
@@ -2636,9 +2651,7 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port,
 	 * 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);
 }
 
 /*



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux