Skip to content

Commit

Permalink
tty/serial: Prevent drop of DCD on suspend for Tegra UARTs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Doug Anderson authored and Greg Kroah-Hartman committed Nov 15, 2011
1 parent eca9dfa commit 9636b75
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
14 changes: 14 additions & 0 deletions drivers/tty/serial/8250.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
UART_FCR_T_TRIG_01,
.flags = UART_CAP_FIFO | UART_CAP_RTOIE,
.mcr_mask = ~UART_MCR_DTR,
.mcr_force = UART_MCR_DTR,
},
[PORT_XR17D15X] = {
.name = "XR17D15X",
Expand Down Expand Up @@ -1229,6 +1231,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
up->port.fifosize = uart_config[up->port.type].fifo_size;
up->capabilities = uart_config[up->port.type].flags;
up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
if (!ALPHA_KLUDGE_MCR) {
up->mcr_mask = uart_config[up->port.type].mcr_mask;
up->mcr_force = uart_config[up->port.type].mcr_force;
}

if (up->port.type == PORT_UNKNOWN)
goto out;
Expand Down Expand Up @@ -1987,6 +1993,10 @@ static int serial8250_startup(struct uart_port *port)
up->port.fifosize = uart_config[up->port.type].fifo_size;
up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
up->capabilities = uart_config[up->port.type].flags;
if (!ALPHA_KLUDGE_MCR) {
up->mcr_mask = uart_config[up->port.type].mcr_mask;
up->mcr_force = uart_config[up->port.type].mcr_force;
}
up->mcr = 0;

if (up->port.iotype != up->cur_iotype)
Expand Down Expand Up @@ -2793,6 +2803,10 @@ serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
up->port.fifosize = uart_config[type].fifo_size;
up->capabilities = uart_config[type].flags;
up->tx_loadsz = uart_config[type].tx_loadsz;
if (!ALPHA_KLUDGE_MCR) {
up->mcr_mask = uart_config[type].mcr_mask;
up->mcr_force = uart_config[type].mcr_force;
}
}

static void __init
Expand Down
2 changes: 2 additions & 0 deletions drivers/tty/serial/8250.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ struct serial8250_config {
unsigned short tx_loadsz;
unsigned char fcr;
unsigned int flags;
unsigned char mcr_mask;
unsigned char mcr_force;
};

#define UART_CAP_FIFO (1 << 8) /* UART has FIFO */
Expand Down

0 comments on commit 9636b75

Please sign in to comment.