mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-22 18:01:13 +07:00
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: 1da177e4c3
("Linux-2.6.12-rc2")
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Link: https://lore.kernel.org/r/alpine.DEB.2.21.2105190412280.29169@angie.orcam.me.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
5db39ad3fa
commit
c850b52e47
@ -2635,6 +2635,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.
|
||||
@ -2642,9 +2657,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user