diff options
Diffstat (limited to 'drivers/tty/serial/8250.c')
| -rw-r--r-- | drivers/tty/serial/8250.c | 44 | 
1 files changed, 40 insertions, 4 deletions
| diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 6611535f4440..b40f7b90c81d 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -1,6 +1,4 @@  /* - *  linux/drivers/char/8250.c - *   *  Driver for 8250/16550-type serial ports   *   *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. @@ -273,7 +271,7 @@ static const struct serial8250_config uart_config[] = {  		.fifo_size	= 32,  		.tx_loadsz	= 32,  		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, -		.flags		= UART_CAP_FIFO | UART_CAP_UUE, +		.flags		= UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,  	},  	[PORT_RM9000] = {  		.name		= "RM9000", @@ -303,6 +301,14 @@ static const struct serial8250_config uart_config[] = {  		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,  		.flags		= UART_CAP_FIFO | UART_CAP_AFE,  	}, +	[PORT_TEGRA] = { +		.name		= "Tegra", +		.fifo_size	= 32, +		.tx_loadsz	= 8, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | +				  UART_FCR_T_TRIG_01, +		.flags		= UART_CAP_FIFO | UART_CAP_RTOIE, +	},  };  #if defined(CONFIG_MIPS_ALCHEMY) @@ -1427,6 +1433,27 @@ static void serial8250_enable_ms(struct uart_port *port)  	serial_out(up, UART_IER, up->ier);  } +/* + * Clear the Tegra rx fifo after a break + * + * FIXME: This needs to become a port specific callback once we have a + * framework for this + */ +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)  { @@ -1462,6 +1489,13 @@ 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 @@ -2405,7 +2439,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,  			UART_ENABLE_MS(&up->port, termios->c_cflag))  		up->ier |= UART_IER_MSI;  	if (up->capabilities & UART_CAP_UUE) -		up->ier |= UART_IER_UUE | UART_IER_RTOIE; +		up->ier |= UART_IER_UUE; +	if (up->capabilities & UART_CAP_RTOIE) +		up->ier |= UART_IER_RTOIE;  	serial_out(up, UART_IER, up->ier); |