serial: mvebu-uart: initialize over sampling stack register
authorMiquel Raynal <miquel.raynal@bootlin.com>
Fri, 23 Nov 2018 15:45:30 +0000 (16:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Nov 2018 08:20:17 +0000 (09:20 +0100)
The baudrate derivation relies on the state of the programmable over
sampling stack (OSAMP register) being empty, while never initializing
it.

Set all the fields of this register to 0 (except reserved areas) to
ensure a x16 divisor, as assumed by the driver.

The suspend/resume callbacks are untouched because they already
save/restore correctly this register.

Suggested-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/mvebu-uart.c

index df6e4d8cdbd6094da85a24bc992176145925f13c..231f751d1ef48b42e4a9820c73408242862035e9 100644 (file)
@@ -73,6 +73,7 @@
 
 #define UART_OSAMP             0x14
 #define  OSAMP_DEFAULT_DIVISOR 16
+#define  OSAMP_DIVISORS_MASK   0x3F3F3F3F
 
 #define MVEBU_NR_UARTS         2
 
@@ -446,7 +447,7 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 {
        struct mvebu_uart *mvuart = to_mvuart(port);
        unsigned int d_divisor, m_divisor;
-       u32 brdv;
+       u32 brdv, osamp;
 
        if (IS_ERR(mvuart->clk))
                return -PTR_ERR(mvuart->clk);
@@ -469,6 +470,10 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
        brdv |= d_divisor;
        writel(brdv, port->membase + UART_BRDV);
 
+       osamp = readl(port->membase + UART_OSAMP);
+       osamp &= ~OSAMP_DIVISORS_MASK;
+       writel(osamp, port->membase + UART_OSAMP);
+
        return 0;
 }