summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2010-10-19 14:05:15 +0530
committerVarun Colbert <vcolbert@nvidia.com>2010-11-22 14:53:41 -0800
commitff4d0279c458b724d273efd88ee87ff7caf48991 (patch)
tree5f3bdaf3425bf75d3d83554b26bb5ca0f47232ac
parent6678b8e8e8a087955cf60f3dc84abd9b246c956f (diff)
[arm/tegra] serial: Support for break on console driver.
There is sysrq feature which works from console with sending break and then character. The console driver uses the 8250 driver. In tegra uart controller, after receiving break, it needs to clear the rx fifo by reading fifo till empty to receive the another break/character. Fixing this issue in 8250 driver. bug 697978 Change-Id: I4eb71a67bafc186ec9934fce164e28ad86fa0ace Reviewed-on: http://git-master/r/8736 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rwxr-xr-xarch/arm/mach-tegra/board-nvodm.c4
-rw-r--r--drivers/serial/8250.c34
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/serial_reg.h2
4 files changed, 41 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/board-nvodm.c b/arch/arm/mach-tegra/board-nvodm.c
index d601636c958f..ff4c5bd08c3c 100755
--- a/arch/arm/mach-tegra/board-nvodm.c
+++ b/arch/arm/mach-tegra/board-nvodm.c
@@ -94,7 +94,9 @@ extern const struct tegra_pingroup_config *tegra_pinmux_get(const char *dev_id,
static struct plat_serial8250_port debug_uart_platform[] = {
{
- .flags = UPF_BOOT_AUTOCONF,
+ /* Force the debug console UART port type to PORT_TEGRA.*/
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .type = PORT_TEGRA,
.iotype = UPIO_MEM,
.regshift = 2,
}, {
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 5ed1b828a7ca..1653c8e57e87 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -299,6 +299,14 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
+ [PORT_TEGRA] = {
+ .name = "Tegra",
+ .fifo_size = 32,
+ .tx_loadsz = 8,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_T_TRIG_01 |
+ UART_FCR_R_TRIG_01,
+ .flags = UART_CAP_FIFO,
+ },
};
#if defined (CONFIG_SERIAL_8250_AU1X00)
@@ -1381,6 +1389,23 @@ static void serial8250_enable_ms(struct uart_port *port)
up->ier |= UART_IER_MSI;
serial_out(up, UART_IER, up->ier);
}
+/* Clear the rx fifo */
+static void clear_rx_fifo(struct uart_8250_port *up)
+{
+ unsigned int status, tmout = 10000;
+ do {
+ status = serial_in(up, UART_LSR);
+ if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
+ status = serial_in(up, UART_RX);
+ else
+ break;
+ if (--tmout == 0)
+ break;
+ udelay(1);
+ } while (1);
+}
+
+
static void
receive_chars(struct uart_8250_port *up, unsigned int *status)
@@ -1417,6 +1442,12 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
lsr &= ~(UART_LSR_FE | UART_LSR_PE);
up->port.icount.brk++;
/*
+ * If tegra port then clear the rx fifo to
+ * accept another break/character.
+ */
+ if (up->port.type == PORT_TEGRA)
+ clear_rx_fifo(up);
+ /*
* We do the SysRQ and SAK checking
* here because otherwise the break
* may get masked by ignore_status_mask
@@ -2152,6 +2183,9 @@ dont_test_tx_en:
* anyway, so we don't enable them here.
*/
up->ier = UART_IER_RLSI | UART_IER_RDI;
+ /* Use the receive timeout interrupt for tegra port*/
+ if (up->port.type == PORT_TEGRA)
+ up->ier |= UART_IER_RTOIE;
serial_outp(up, UART_IER, up->ier);
if (up->port.flags & UPF_FOURPORT) {
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 743f48ac71dc..18d4b99ed61f 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -44,7 +44,8 @@
#define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */
#define PORT_OCTEON 17 /* Cavium OCTEON internal UART */
#define PORT_AR7 18 /* Texas Instruments AR7 internal UART */
-#define PORT_MAX_8250 18 /* max port ID */
+#define PORT_TEGRA 19 /* NVIDIA Tegra internal UART */
+#define PORT_MAX_8250 19 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index 850db2e80510..360e0d7d7113 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -57,6 +57,7 @@
* ST16C654: 8 16 56 60 8 16 32 56 PORT_16654
* TI16C750: 1 16 32 56 xx xx xx xx PORT_16750
* TI16C752: 8 16 56 60 8 16 32 56
+ * TEGRA: 1 4 8 14 16 8 4 1
*/
#define UART_FCR_R_TRIG_00 0x00
#define UART_FCR_R_TRIG_01 0x40
@@ -111,6 +112,7 @@
#define UART_MCR_DTR 0x01 /* DTR complement */
#define UART_LSR 5 /* In: Line Status Register */
+#define UART_LSR_FIFOE 0x80 /* Fifo error */
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_BI 0x10 /* Break interrupt indicator */