(port->uartclk + tolerance) / 16);
 }
 
+/*
+ * Note in order to avoid the tty port mutex deadlock don't use the next method
+ * within the uart port callbacks. Primarily it's supposed to be utilized to
+ * handle a sudden reference clock rate change.
+ */
+void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
+{
+       struct uart_8250_port *up = up_to_u8250p(port);
+       unsigned int baud, quot, frac = 0;
+       struct ktermios *termios;
+       unsigned long flags;
+
+       mutex_lock(&port->state->port.mutex);
+
+       if (port->uartclk == uartclk)
+               goto out_lock;
+
+       port->uartclk = uartclk;
+       termios = &port->state->port.tty->termios;
+
+       baud = serial8250_get_baud_rate(port, termios, NULL);
+       quot = serial8250_get_divisor(port, baud, &frac);
+
+       serial8250_rpm_get(up);
+       spin_lock_irqsave(&port->lock, flags);
+
+       uart_update_timeout(port, termios->c_cflag, baud);
+
+       serial8250_set_divisor(port, baud, quot, frac);
+       serial_port_out(port, UART_LCR, up->lcr);
+       serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+       serial8250_rpm_put(up);
+
+out_lock:
+       mutex_unlock(&port->state->port.mutex);
+}
+EXPORT_SYMBOL_GPL(serial8250_update_uartclk);
+
 void
 serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                          struct ktermios *old)
 
 
 extern int early_serial8250_setup(struct earlycon_device *device,
                                         const char *options);
+extern void serial8250_update_uartclk(struct uart_port *port,
+                                     unsigned int uartclk);
 extern void serial8250_do_set_termios(struct uart_port *port,
                struct ktermios *termios, struct ktermios *old);
 extern void serial8250_do_set_ldisc(struct uart_port *port,