Commit 3cd30bf0 authored by Russell King's avatar Russell King

[SERIAL] Introduce per-port capabilities.

This allows us to maintain quirks or capabilities on a per-port basis,
so we can handle buggy clones more effectively.
parent cca9cd91
...@@ -122,6 +122,7 @@ struct uart_8250_port { ...@@ -122,6 +122,7 @@ struct uart_8250_port {
struct uart_port port; struct uart_port port;
struct timer_list timer; /* "no irq" timer */ struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */ struct list_head list; /* ports on this IRQ */
unsigned int capabilities; /* port capabilities */
unsigned short rev; unsigned short rev;
unsigned char acr; unsigned char acr;
unsigned char ier; unsigned char ier;
...@@ -683,6 +684,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) ...@@ -683,6 +684,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
serial_outp(up, UART_LCR, save_lcr); serial_outp(up, UART_LCR, save_lcr);
up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size; up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
up->capabilities = uart_config[up->port.type].flags;
if (up->port.type == PORT_UNKNOWN) if (up->port.type == PORT_UNKNOWN)
goto out; goto out;
...@@ -1190,6 +1192,8 @@ static int serial8250_startup(struct uart_port *port) ...@@ -1190,6 +1192,8 @@ static int serial8250_startup(struct uart_port *port)
unsigned long flags; unsigned long flags;
int retval; int retval;
up->capabilities = uart_config[up->port.type].flags;
if (up->port.type == PORT_16C950) { if (up->port.type == PORT_16C950) {
/* Wake up and initialize UART */ /* Wake up and initialize UART */
up->acr = 0; up->acr = 0;
...@@ -1215,7 +1219,7 @@ static int serial8250_startup(struct uart_port *port) ...@@ -1215,7 +1219,7 @@ static int serial8250_startup(struct uart_port *port)
* Clear the FIFO buffers and disable them. * Clear the FIFO buffers and disable them.
* (they will be reeanbled in set_termios()) * (they will be reeanbled in set_termios())
*/ */
if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) { if (up->capabilities & UART_CLEAR_FIFO) {
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
...@@ -1428,7 +1432,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, ...@@ -1428,7 +1432,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
up->rev == 0x5201) up->rev == 0x5201)
quot ++; quot ++;
if (uart_config[up->port.type].flags & UART_USE_FIFO) { if (up->capabilities & UART_USE_FIFO) {
if (baud < 2400) if (baud < 2400)
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
#ifdef CONFIG_SERIAL_8250_RSA #ifdef CONFIG_SERIAL_8250_RSA
...@@ -1489,13 +1493,13 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, ...@@ -1489,13 +1493,13 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
serial_out(up, UART_IER, up->ier); serial_out(up, UART_IER, up->ier);
if (uart_config[up->port.type].flags & UART_STARTECH) { if (up->capabilities & UART_STARTECH) {
serial_outp(up, UART_LCR, 0xBF); serial_outp(up, UART_LCR, 0xBF);
serial_outp(up, UART_EFR, serial_outp(up, UART_EFR,
termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0); termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0);
} }
if (uart_config[up->port.type].flags & UART_NATSEMI) { if (up->capabilities & UART_NATSEMI) {
/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */ /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
serial_outp(up, UART_LCR, 0xe0); serial_outp(up, UART_LCR, 0xe0);
} else { } else {
...@@ -1524,7 +1528,7 @@ serial8250_pm(struct uart_port *port, unsigned int state, ...@@ -1524,7 +1528,7 @@ serial8250_pm(struct uart_port *port, unsigned int state,
struct uart_8250_port *up = (struct uart_8250_port *)port; struct uart_8250_port *up = (struct uart_8250_port *)port;
if (state) { if (state) {
/* sleep */ /* sleep */
if (uart_config[up->port.type].flags & UART_STARTECH) { if (up->capabilities & UART_STARTECH) {
/* Arrange to enter sleep mode */ /* Arrange to enter sleep mode */
serial_outp(up, UART_LCR, 0xBF); serial_outp(up, UART_LCR, 0xBF);
serial_outp(up, UART_EFR, UART_EFR_ECB); serial_outp(up, UART_EFR, UART_EFR_ECB);
...@@ -1543,7 +1547,7 @@ serial8250_pm(struct uart_port *port, unsigned int state, ...@@ -1543,7 +1547,7 @@ serial8250_pm(struct uart_port *port, unsigned int state,
up->pm(port, state, oldstate); up->pm(port, state, oldstate);
} else { } else {
/* wake */ /* wake */
if (uart_config[up->port.type].flags & UART_STARTECH) { if (up->capabilities & UART_STARTECH) {
/* Wake up UART */ /* Wake up UART */
serial_outp(up, UART_LCR, 0xBF); serial_outp(up, UART_LCR, 0xBF);
serial_outp(up, UART_EFR, UART_EFR_ECB); serial_outp(up, UART_EFR, UART_EFR_ECB);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment