]> Pileus Git - ~andy/linux/blobdiff - drivers/tty/serial/8250/8250_core.c
Merge branch 'for-3.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[~andy/linux] / drivers / tty / serial / 8250 / 8250_core.c
index 61ecd709a7229aa7d7d6fcc91326a8eda0861fa8..69932b7556cf822194413f2da0278d9bd3f4cb13 100644 (file)
@@ -2432,6 +2432,24 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 
        serial_dl_write(up, quot);
 
+       /*
+        * XR17V35x UARTs have an extra fractional divisor register (DLD)
+        *
+        * We need to recalculate all of the registers, because DLM and DLL
+        * are already rounded to a whole integer.
+        *
+        * When recalculating we use a 32x clock instead of a 16x clock to
+        * allow 1-bit for rounding in the fractional part.
+        */
+       if (up->port.type == PORT_XR17V35X) {
+               unsigned int baud_x32 = (port->uartclk * 2) / baud;
+               u16 quot = baud_x32 / 32;
+               u8 quot_frac = DIV_ROUND_CLOSEST(baud_x32 % 32, 2);
+
+               serial_dl_write(up, quot);
+               serial_port_out(port, 0x2, quot_frac & 0xf);
+       }
+
        /*
         * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
         * is written without DLAB set, this mode will be disabled.