]> git.baikalelectronics.ru Git - kernel.git/commitdiff
serial: 8250_dw: drop bogus uartclk optimisation
authorJohan Hovold <johan@kernel.org>
Fri, 15 Oct 2021 11:14:22 +0000 (13:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 21 Oct 2021 08:38:49 +0000 (10:38 +0200)
The driver was updating the port uartclk before setting the new rate in
an attempt to avoid having the clock notifier redundantly update the
divisors.

The set_termios() callback is however called under the termios semaphore
and tty-port mutex so the worker scheduled by the clock notifier will
block in serial8250_update_uartclk() until the uartclk and divisors have
been updated anyway.

Drop the unnecessary swaps and incorrect comment and simply update the
uartclk field if the clock-rate change was successful.

Tested-by: Serge Semin <fancer.lancer@gmail.com>
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20211015111422.1027-4-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_dw.c

index 5a2ff843ec5db4c219d01b25984149cb3c3bd518..53f57c3b9f42ccf2aac5c477ded1a35950162862 100644 (file)
@@ -338,15 +338,12 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
        rate = clk_round_rate(d->clk, newrate);
        if (rate > 0) {
                /*
-                * Preliminary set the uartclk to the new clock rate so the
-                * clock update event handler caused by the clk_set_rate()
-                * calling wouldn't actually update the UART divisor since
-                * we about to do this anyway.
+                * Note that any clock-notifer worker will block in
+                * serial8250_update_uartclk() until we are done.
                 */
-               swap(p->uartclk, rate);
                ret = clk_set_rate(d->clk, newrate);
-               if (ret)
-                       swap(p->uartclk, rate);
+               if (!ret)
+                       p->uartclk = rate;
        }
        clk_prepare_enable(d->clk);