* [PATCH] tty/serial: Prevent drop of DCD on suspend for Tegra UARTs
@ 2011-10-12 0:05 Doug Anderson
2011-10-12 11:56 ` Alan Cox
2011-10-13 17:57 ` Stephen Warren
0 siblings, 2 replies; 3+ messages in thread
From: Doug Anderson @ 2011-10-12 0:05 UTC (permalink / raw)
To: Jiri Slaby, Stephen Warren, Olof Johansson
Cc: Greg Kroah-Hartman, Alan Cox, Allen Martin, Tom Warren,
linux-serial, linux-kernel, Doug Anderson
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>
---
drivers/tty/serial/8250.c | 14 ++++++++++++++
drivers/tty/serial/8250.h | 2 ++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index 7f50999..c8d26a3 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -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,
},
};
@@ -1282,6 +1284,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;
@@ -2034,6 +2040,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)
@@ -2841,6 +2851,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
diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h
index 6edf4a6..1f75100 100644
--- a/drivers/tty/serial/8250.h
+++ b/drivers/tty/serial/8250.h
@@ -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 */
--
1.7.3.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] tty/serial: Prevent drop of DCD on suspend for Tegra UARTs
2011-10-12 0:05 [PATCH] tty/serial: Prevent drop of DCD on suspend for Tegra UARTs Doug Anderson
@ 2011-10-12 11:56 ` Alan Cox
2011-10-13 17:57 ` Stephen Warren
1 sibling, 0 replies; 3+ messages in thread
From: Alan Cox @ 2011-10-12 11:56 UTC (permalink / raw)
To: Doug Anderson
Cc: Jiri Slaby, Stephen Warren, Olof Johansson, Greg Kroah-Hartman,
Alan Cox, Allen Martin, Tom Warren, linux-serial, linux-kernel
> 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.
I have two problems with this change
- It adds more special cases into the 8250.c core code
- It breaks the UARTA port (which is a regression so not acceptable for
upstream merging)
I think you should simply provide your platform with an appropriate
serial_in/serial_out method that does the needed masking. That way its
kept isolated from everyone else.
Alan
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [PATCH] tty/serial: Prevent drop of DCD on suspend for Tegra UARTs
2011-10-12 0:05 [PATCH] tty/serial: Prevent drop of DCD on suspend for Tegra UARTs Doug Anderson
2011-10-12 11:56 ` Alan Cox
@ 2011-10-13 17:57 ` Stephen Warren
1 sibling, 0 replies; 3+ messages in thread
From: Stephen Warren @ 2011-10-13 17:57 UTC (permalink / raw)
To: Doug Anderson, Jiri Slaby, Olof Johansson
Cc: Greg Kroah-Hartman, Alan Cox, Allen Martin, Tom Warren,
linux-serial, linux-kernel
Doug Anderson wrote at Tuesday, October 11, 2011 6:06 PM:
> 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.
I did some research on the HW, and here's how everything is hooked up
in Tegra20 and Tegra30. Later chips may have this fixed, or at least
configurable; I don't know the details yet.
All 5 UARTs support the modem signals in the HW block.
In UART A, you can mux the modem signals out using the pinmux. If the
pinmux /doesn't/ route the signals out, the DSR and DCD signals are tied
to an /active/ state.
In UART B, the DTR output is indeed wired back into the DSR and DCD
inputs, as you discovered.
In UARTs C, D, and E, the DSR and DCD signals are tied to an /inactive/
state.
So, I think this particular WAR is only needed on UART B.
--
nvpublic
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-10-13 17:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-12 0:05 [PATCH] tty/serial: Prevent drop of DCD on suspend for Tegra UARTs Doug Anderson
2011-10-12 11:56 ` Alan Cox
2011-10-13 17:57 ` Stephen Warren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®