summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2021-06-25 00:49:02 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-14 16:56:50 +0200
commit347af865b6a20d2f498644f612c0e09d2eeba199 (patch)
treed904142c2fe330928dfc0f5651325cb22f26abcd
parent9ad82f0412c04f7cf8a8522a5dca633a0c40135a (diff)
downloadlinux-stable-347af865b6a20d2f498644f612c0e09d2eeba199.tar.gz
linux-stable-347af865b6a20d2f498644f612c0e09d2eeba199.tar.bz2
linux-stable-347af865b6a20d2f498644f612c0e09d2eeba199.zip
serial: mvebu-uart: correctly calculate minimal possible baudrate
[ Upstream commit deeaf963569a0d9d1b08babb771f61bb501a5704 ] For default (x16) scheme which is currently used by mvebu-uart.c driver, maximal divisor of UART base clock is 1023*16. Therefore there is limit for minimal supported baudrate. This change calculate it correctly and prevents setting invalid divisor 0 into hardware registers. Signed-off-by: Pali Rohár <pali@kernel.org> Fixes: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate") Link: https://lore.kernel.org/r/20210624224909.6350-4-pali@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/tty/serial/mvebu-uart.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index 9638ae6aae79..1e26220c7852 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -481,7 +481,7 @@ static void mvebu_uart_set_termios(struct uart_port *port,
struct ktermios *old)
{
unsigned long flags;
- unsigned int baud;
+ unsigned int baud, min_baud, max_baud;
spin_lock_irqsave(&port->lock, flags);
@@ -500,16 +500,21 @@ static void mvebu_uart_set_termios(struct uart_port *port,
port->ignore_status_mask |= STAT_RX_RDY(port) | STAT_BRK_ERR;
/*
+ * Maximal divisor is 1023 * 16 when using default (x16) scheme.
* Maximum achievable frequency with simple baudrate divisor is 230400.
* Since the error per bit frame would be of more than 15%, achieving
* higher frequencies would require to implement the fractional divisor
* feature.
*/
- baud = uart_get_baud_rate(port, termios, old, 0, 230400);
+ min_baud = DIV_ROUND_UP(port->uartclk, 1023 * 16);
+ max_baud = 230400;
+
+ baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
if (mvebu_uart_baud_rate_set(port, baud)) {
/* No clock available, baudrate cannot be changed */
if (old)
- baud = uart_get_baud_rate(port, old, NULL, 0, 230400);
+ baud = uart_get_baud_rate(port, old, NULL,
+ min_baud, max_baud);
} else {
tty_termios_encode_baud_rate(termios, baud, baud);
uart_update_timeout(port, termios->c_cflag, baud);