aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2011-10-11 20:05:43 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-15 15:13:41 -0500
commit9636b755da7b498094bdf15b4ce9f6fd16995e4e (patch)
tree8c3351fd307b2a8c9af4d6139ff3841ef8ff4eb2
parenteca9dfa846a3d0eeb865e290851f4bfe4fb34fdd (diff)
tty/serial: Prevent drop of DCD on suspend for Tegra UARTs
On Tegra UARTs (except UART1), the DTR / DCD / DSR lines are not externally accessible. Instead, the DTR line internally appears to be looped back to be the input to the DCD and DSR lines. The net effect of this is that when we drop DTR (like when we suspend), we'll see DCD drop too. ...and when we see DCD drop, we treat that as a hangup. In order to prevent this hangup from occurring at every sleep, we need to force DTR to remain high on Tegra UARTs. This patch uses the mcr_mask / mcr_force fields, which were originally added for the kludge ALPHA_KLUDGE_MCR. Using these fields does not prevent us from removing ALPHA_KLUDGE_MCR--we can just remove the "if" tests I have added and always init mcr_mask / mcr_force from the serial8250_config. NOTE: If we have people that are using UARTA on a Tegra and need to control DTR, we'll need to either add a separate port type for UARTA or we'll need to add some tegra-specific code to detect whether the DTR needs to be left high. Signed-off-by: Doug Anderson <dianders@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/tty/serial/8250.c14
-rw-r--r--drivers/tty/serial/8250.h2
2 files changed, 16 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index eeadf1b8e093..2b0a4b63c5f7 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -308,6 +308,8 @@ static const struct serial8250_config uart_config[] = {
308 .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | 308 .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
309 UART_FCR_T_TRIG_01, 309 UART_FCR_T_TRIG_01,
310 .flags = UART_CAP_FIFO | UART_CAP_RTOIE, 310 .flags = UART_CAP_FIFO | UART_CAP_RTOIE,
311 .mcr_mask = ~UART_MCR_DTR,
312 .mcr_force = UART_MCR_DTR,
311 }, 313 },
312 [PORT_XR17D15X] = { 314 [PORT_XR17D15X] = {
313 .name = "XR17D15X", 315 .name = "XR17D15X",
@@ -1229,6 +1231,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
1229 up->port.fifosize = uart_config[up->port.type].fifo_size; 1231 up->port.fifosize = uart_config[up->port.type].fifo_size;
1230 up->capabilities = uart_config[up->port.type].flags; 1232 up->capabilities = uart_config[up->port.type].flags;
1231 up->tx_loadsz = uart_config[up->port.type].tx_loadsz; 1233 up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
1234 if (!ALPHA_KLUDGE_MCR) {
1235 up->mcr_mask = uart_config[up->port.type].mcr_mask;
1236 up->mcr_force = uart_config[up->port.type].mcr_force;
1237 }
1232 1238
1233 if (up->port.type == PORT_UNKNOWN) 1239 if (up->port.type == PORT_UNKNOWN)
1234 goto out; 1240 goto out;
@@ -1987,6 +1993,10 @@ static int serial8250_startup(struct uart_port *port)
1987 up->port.fifosize = uart_config[up->port.type].fifo_size; 1993 up->port.fifosize = uart_config[up->port.type].fifo_size;
1988 up->tx_loadsz = uart_config[up->port.type].tx_loadsz; 1994 up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
1989 up->capabilities = uart_config[up->port.type].flags; 1995 up->capabilities = uart_config[up->port.type].flags;
1996 if (!ALPHA_KLUDGE_MCR) {
1997 up->mcr_mask = uart_config[up->port.type].mcr_mask;
1998 up->mcr_force = uart_config[up->port.type].mcr_force;
1999 }
1990 up->mcr = 0; 2000 up->mcr = 0;
1991 2001
1992 if (up->port.iotype != up->cur_iotype) 2002 if (up->port.iotype != up->cur_iotype)
@@ -2793,6 +2803,10 @@ serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
2793 up->port.fifosize = uart_config[type].fifo_size; 2803 up->port.fifosize = uart_config[type].fifo_size;
2794 up->capabilities = uart_config[type].flags; 2804 up->capabilities = uart_config[type].flags;
2795 up->tx_loadsz = uart_config[type].tx_loadsz; 2805 up->tx_loadsz = uart_config[type].tx_loadsz;
2806 if (!ALPHA_KLUDGE_MCR) {
2807 up->mcr_mask = uart_config[type].mcr_mask;
2808 up->mcr_force = uart_config[type].mcr_force;
2809 }
2796} 2810}
2797 2811
2798static void __init 2812static void __init
diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h
index 6edf4a6a22d4..1f7510051707 100644
--- a/drivers/tty/serial/8250.h
+++ b/drivers/tty/serial/8250.h
@@ -35,6 +35,8 @@ struct serial8250_config {
35 unsigned short tx_loadsz; 35 unsigned short tx_loadsz;
36 unsigned char fcr; 36 unsigned char fcr;
37 unsigned int flags; 37 unsigned int flags;
38 unsigned char mcr_mask;
39 unsigned char mcr_force;
38}; 40};
39 41
40#define UART_CAP_FIFO (1 << 8) /* UART has FIFO */ 42#define UART_CAP_FIFO (1 << 8) /* UART has FIFO */