4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Redfearn matt.redfearn@mips.com
commit 0ff3ab701963a845d52337ded7eebf2d1a14fe00 upstream.
If either uartclk or baud are 0, avoid calculating and setting a divisor based on them since the output will almost certainly be garbage.
This also allows platforms such as the MIPS generic kernel, which has no way to know a valid BASE_BASE for the board it is actually booted on at compile time, to set BASE_BAUD to 0 and avoid early_8250 setting a bad divisor.
This fixes a regression caused by commit 31cb9a8575ca ("earlycon: initialise baud field of earlycon device structure"), which changed the behavior of of_setup_earlycon such that it sets a baud rate in the earlycon structure where previously it was left as 0. All boards supported by the MIPS generic kernel started outputting garbage from the boot console due to an incorrect divisor being set.
Fixes: 31cb9a8575ca ("earlycon: initialise baud field of earlycon device structure") Signed-off-by: Matt Redfearn matt.redfearn@mips.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/tty/serial/8250/8250_early.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -125,12 +125,14 @@ static void __init init_port(struct earl serial8250_early_out(port, UART_FCR, 0); /* no fifo */ serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */
- divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); - c = serial8250_early_in(port, UART_LCR); - serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB); - serial8250_early_out(port, UART_DLL, divisor & 0xff); - serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff); - serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); + if (port->uartclk && device->baud) { + divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); + c = serial8250_early_in(port, UART_LCR); + serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB); + serial8250_early_out(port, UART_DLL, divisor & 0xff); + serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff); + serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); + } }
int __init early_serial8250_setup(struct earlycon_device *device,