[linux-yocto] [PATCH 02/15] serial: 8250_port: factor out serial8250_do_restore_context()
Nilesh Bacchewar
nilesh.bacchewar at intel.com
Thu Nov 17 15:06:18 PST 2016
From: Andy Shevchenko <andriy.shevchenko at 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.shevchenko at 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
More information about the linux-yocto
mailing list