From: Andy Shevchenko <andriy.shevche...@linux.intel.com>

Backport:
 - Upstream-Status: Pending.
 
[https://bitbucket.org/andy-shev/linux/commits/fe798435558f5214855a60ac15df4fe6d48e956c?at=master]

The new function serial8250_do_restore_context() is used to write the saved
register values to the hardware. It is used in serial8250_do_set_termios() and
will be used by the individual drivers to restore context when resuming.

Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
---
 drivers/tty/serial/8250/8250_port.c | 65 ++++++++++++++++++++++++-------------
 include/linux/serial_8250.h         |  5 +++
 2 files changed, 47 insertions(+), 23 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_port.c 
b/drivers/tty/serial/8250/8250_port.c
index 342e2f1..d8d52db 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2246,6 +2246,42 @@ serial8250_get_baud_rate(struct uart_port *port, struct 
ktermios *termios,
                                  (port->uartclk + tolerance) / 16);
 }
 
+void serial8250_do_restore_context(struct uart_port *port)
+{
+       struct uart_8250_port *up = up_to_u8250p(port);
+
+       /* Write extended features at first */
+       if (up->capabilities & UART_CAP_EFR) {
+               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
+               if (port->flags & UPF_EXAR_EFR)
+                       serial_port_out(port, UART_XR_EFR, up->efr);
+               else
+                       serial_port_out(port, UART_EFR, up->efr);
+       }
+
+       serial8250_set_divisor(port, up->baud, up->quot, up->frac);
+
+       /*
+        * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
+        * is written without DLAB set, this mode will be disabled.
+        */
+       if (port->type == PORT_16750)
+               serial_port_out(port, UART_FCR, up->fcr);
+
+       serial_port_out(port, UART_LCR, up->lcr);       /* reset DLAB */
+       if (port->type != PORT_16750) {
+               /* emulated UARTs (Lucent Venus 167x) need two steps */
+               if (up->fcr & UART_FCR_ENABLE_FIFO)
+                       serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
+               serial_port_out(port, UART_FCR, up->fcr);       /* set fcr */
+       }
+       serial8250_set_mctrl(port, port->mctrl);
+
+       /* Enable interrupts at last */
+       serial_port_out(port, UART_IER, up->ier);
+}
+EXPORT_SYMBOL_GPL(serial8250_do_restore_context);
+
 void
 serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                          struct ktermios *old)
@@ -2268,6 +2304,9 @@ serial8250_do_set_termios(struct uart_port *port, struct 
ktermios *termios,
        spin_lock_irqsave(&port->lock, flags);
 
        up->lcr = cval;                                 /* Save computed LCR */
+       up->baud = baud;                                /* Save baud rate */
+       up->quot = quot;                                /* Save quot */
+       up->frac = frac;                                /* Save fraction */
 
        if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
                /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */
@@ -2336,8 +2375,6 @@ serial8250_do_set_termios(struct uart_port *port, struct 
ktermios *termios,
        if (up->capabilities & UART_CAP_RTOIE)
                up->ier |= UART_IER_RTOIE;
 
-       serial_port_out(port, UART_IER, up->ier);
-
        if (up->capabilities & UART_CAP_EFR) {
                unsigned char efr = 0;
                /*
@@ -2348,30 +2385,12 @@ serial8250_do_set_termios(struct uart_port *port, 
struct ktermios *termios,
                if (termios->c_cflag & CRTSCTS)
                        efr |= UART_EFR_CTS;
 
-               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
-               if (port->flags & UPF_EXAR_EFR)
-                       serial_port_out(port, UART_XR_EFR, efr);
-               else
-                       serial_port_out(port, UART_EFR, efr);
+               up->efr = efr;
        }
 
-       serial8250_set_divisor(port, baud, quot, frac);
+       /* Write saved values to the registers */
+       serial8250_do_restore_context(port);
 
-       /*
-        * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
-        * is written without DLAB set, this mode will be disabled.
-        */
-       if (port->type == PORT_16750)
-               serial_port_out(port, UART_FCR, up->fcr);
-
-       serial_port_out(port, UART_LCR, up->lcr);       /* reset DLAB */
-       if (port->type != PORT_16750) {
-               /* emulated UARTs (Lucent Venus 167x) need two steps */
-               if (up->fcr & UART_FCR_ENABLE_FIFO)
-                       serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
-               serial_port_out(port, UART_FCR, up->fcr);       /* set fcr */
-       }
-       serial8250_set_mctrl(port, port->mctrl);
        spin_unlock_irqrestore(&port->lock, flags);
        serial8250_rpm_put(up);
 
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index faa0e03..d23b2d4 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -92,6 +92,7 @@ struct uart_8250_port {
        bool                    fifo_bug;       /* min RX trigger if enabled */
        unsigned int            tx_loadsz;      /* transmit fifo load size */
        unsigned char           acr;
+       unsigned char           efr;
        unsigned char           fcr;
        unsigned char           ier;
        unsigned char           lcr;
@@ -100,6 +101,9 @@ struct uart_8250_port {
        unsigned char           mcr_force;      /* mask of forced bits */
        unsigned char           cur_iotype;     /* Running I/O type */
        unsigned int            rpm_tx_active;
+       unsigned int            baud;
+       unsigned int            quot;
+       unsigned int            frac;
        unsigned char           canary;         /* non-zero during system sleep
                                                 *   if no_console_suspend
                                                 */
@@ -138,6 +142,7 @@ extern int early_serial_setup(struct uart_port *port);
 
 extern int early_serial8250_setup(struct earlycon_device *device,
                                         const char *options);
+void serial8250_do_restore_context(struct uart_port *port);
 extern void serial8250_do_set_termios(struct uart_port *port,
                struct ktermios *termios, struct ktermios *old);
 extern int serial8250_do_startup(struct uart_port *port);
-- 
1.9.1

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to