summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2021-10-15 13:14:22 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-10-21 10:38:49 +0200
commit74365bc138ab03bdac205047aac02f8db0a479fa (patch)
tree6f47e5d493a5524a41b3ddadb6823491abf72bf2 /drivers/tty
parentd2248ca8d6ba867fd9b2317af730ba73284d0989 (diff)
serial: 8250_dw: drop bogus uartclk optimisation
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>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250_dw.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 5a2ff843ec5d..53f57c3b9f42 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -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);