lkml.org 
[lkml]   [2022]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 52/62] serial: mvebu-uart: correctly report configured baudrate value
    Date
    From: Pali Rohár <pali@kernel.org>

    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: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate")
    Cc: stable <stable@kernel.org>
    Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
    Signed-off-by: Pali Rohár <pali@kernel.org>
    Link: https://lore.kernel.org/r/20220628100922.10717-1-pali@kernel.org
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/tty/serial/mvebu-uart.c | 25 +++++++++++++------------
    1 file changed, 13 insertions(+), 12 deletions(-)

    --- a/drivers/tty/serial/mvebu-uart.c
    +++ b/drivers/tty/serial/mvebu-uart.c
    @@ -442,14 +442,14 @@ static void mvebu_uart_shutdown(struct u
    }
    }

    -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)
    {
    struct mvebu_uart *mvuart = to_mvuart(port);
    unsigned int d_divisor, m_divisor;
    u32 brdv;

    if (IS_ERR(mvuart->clk))
    - return -PTR_ERR(mvuart->clk);
    + return 0;

    /*
    * The baudrate is derived from the UART clock thanks to two divisors:
    @@ -469,7 +469,7 @@ static int mvebu_uart_baud_rate_set(stru
    brdv |= d_divisor;
    writel(brdv, port->membase + UART_BRDV);

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

    static void mvebu_uart_set_termios(struct uart_port *port,
    @@ -506,15 +506,11 @@ static void mvebu_uart_set_termios(struc
    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) {
    @@ -525,6 +521,11 @@ static void mvebu_uart_set_termios(struc
    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);
    }


    \
     
     \ /
      Last update: 2022-07-27 18:37    [W:2.889 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site