X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=drivers%2Ftty%2Fserial%2F8250%2F8250_core.c;h=69932b7556cf822194413f2da0278d9bd3f4cb13;hb=614cd4a4ac3daf725508e372bce2160e2d8039a9;hp=61ecd709a7229aa7d7d6fcc91326a8eda0861fa8;hpb=7431105b143098c3fc0ced8f9974b792f76198d7;p=~andy%2Flinux diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 61ecd709a72..69932b7556c 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -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.