#include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/math64.h>
 #include <linux/security.h>
 
 #include <linux/irq.h>
 uart_update_timeout(struct uart_port *port, unsigned int cflag,
                    unsigned int baud)
 {
-       unsigned int size;
+       unsigned int size = tty_get_frame_size(cflag);
+       u64 frame_time;
 
-       size = tty_get_frame_size(cflag) * port->fifosize;
+       frame_time = (u64)size * NSEC_PER_SEC;
+       size *= port->fifosize;
 
        /*
         * Figure the timeout to send the above number of bits.
         * Add .02 seconds of slop
         */
        port->timeout = (HZ * size) / baud + HZ/50;
+       port->frame_time = DIV64_U64_ROUND_UP(frame_time, baud);
 }
 EXPORT_SYMBOL(uart_update_timeout);
 
         * Note: we have to use pretty tight timings here to satisfy
         * the NIST-PCTS.
         */
-       char_time = (port->timeout - HZ/50) / port->fifosize;
-       char_time = char_time / 5;
-       if (char_time == 0)
-               char_time = 1;
+       char_time = max(nsecs_to_jiffies(port->frame_time / 5), 1UL);
+
        if (timeout && timeout < char_time)
                char_time = timeout;
 
 
        int                     hw_stopped;             /* sw-assisted CTS flow state */
        unsigned int            mctrl;                  /* current modem ctrl settings */
        unsigned int            timeout;                /* character-based timeout */
+       unsigned int            frame_time;             /* frame timing in ns */
        unsigned int            type;                   /* port type */
        const struct uart_ops   *ops;
        unsigned int            custom_divisor;