Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c68f6e2e authored by Pali Rohár's avatar Pali Rohár Committed by Greg Kroah-Hartman
Browse files

serial: mvebu-uart: correctly report configured baudrate value



commit 4f532c1e25319e42996ec18a1f473fd50c8e575d upstream.

Functions tty_termios_encode_baud_rate() and uart_update_timeout() should
be called with the baudrate value which was set to hardware. Linux then
report exact values via ioctl(TCGETS2) to userspace.

Change mvebu_uart_baud_rate_set() function to return baudrate value which
was set to hardware and propagate this value to above mentioned functions.

With this change userspace would see precise value in termios c_ospeed
field.

Fixes: 68a0db1d ("serial: mvebu-uart: add function to change baudrate")
Cc: stable <stable@kernel.org>
Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarPali Rohár <pali@kernel.org>
Link: https://lore.kernel.org/r/20220628100922.10717-1-pali@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2230428f
Loading
Loading
Loading
Loading
+13 −12
Original line number Diff line number Diff line
@@ -443,13 +443,13 @@ static void mvebu_uart_shutdown(struct uart_port *port)
	}
}

static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
static unsigned int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
{
	unsigned int d_divisor, m_divisor;
	u32 brdv, osamp;

	if (!port->uartclk)
		return -EOPNOTSUPP;
		return 0;

	/*
	 * The baudrate is derived from the UART clock thanks to two divisors:
@@ -473,7 +473,7 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
	osamp &= ~OSAMP_DIVISORS_MASK;
	writel(osamp, port->membase + UART_OSAMP);

	return 0;
	return DIV_ROUND_CLOSEST(port->uartclk, d_divisor * m_divisor);
}

static void mvebu_uart_set_termios(struct uart_port *port,
@@ -510,15 +510,11 @@ static void mvebu_uart_set_termios(struct uart_port *port,
	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,
						  min_baud, max_baud);
	} else {
		tty_termios_encode_baud_rate(termios, baud, baud);
		uart_update_timeout(port, termios->c_cflag, baud);
	}
	baud = mvebu_uart_baud_rate_set(port, baud);

	/* In case baudrate cannot be changed, report previous old value */
	if (baud == 0 && old)
		baud = tty_termios_baud_rate(old);

	/* Only the following flag changes are supported */
	if (old) {
@@ -529,6 +525,11 @@ static void mvebu_uart_set_termios(struct uart_port *port,
		termios->c_cflag |= CS8;
	}

	if (baud != 0) {
		tty_termios_encode_baud_rate(termios, baud, baud);
		uart_update_timeout(port, termios->c_cflag, baud);
	}

	spin_unlock_irqrestore(&port->lock, flags);
}