• Serge Semin's avatar
    serial: 8250_dw: Fix common clocks usage race condition · cc816969
    Serge Semin authored
    
    
    The race condition may happen if the UART reference clock is shared with
    some other device (on Baikal-T1 SoC it's another DW UART port). In this
    case if that device changes the clock rate while serial console is using
    it the DW 8250 UART port might not only end up with an invalid uartclk
    value saved, but may also experience a distorted output data since
    baud-clock could have been changed. In order to fix this lets at least
    try to adjust the 8250 port setting like UART clock rate in case if the
    reference clock rate change is discovered. The driver will call the new
    method to update 8250 UART port clock rate settings. It's done by means of
    the clock event notifier registered at the port startup and unregistered
    in the shutdown callback method.
    
    Note 1. In order to avoid deadlocks we had to execute the UART port update
    method in a dedicated deferred work. This is due to (in my opinion
    redundant) the clock update implemented in the dw8250_set_termios()
    method.
    Note 2. Before the ref clock is manually changed by the custom
    set_termios() function we swap the port uartclk value with new rate
    adjusted to be suitable for the requested baud. It is necessary in
    order to effectively disable a functionality of the ref clock events
    handler for the current UART port, since uartclk update will be done
    a bit further in the generic serial8250_do_set_termios() function.
    Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
    
    Link: https://lore.kernel.org/r/20200723003357.26897-5-Sergey.Semin@baikalelectronics.ru
    
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    cc816969
8250_dw.c 18.9 KB