diff options
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r-- | drivers/serial/8250.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index c3e37c8e7e2..c3db16b7afa 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -83,6 +83,9 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ #define PASS_LIMIT 256 +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + + /* * We default to IRQ0 for the "no irq" hack. Some * machine types want others as well - they're free @@ -1214,12 +1217,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) } #endif -#ifdef CONFIG_SERIAL_8250_AU1X00 - /* if access method is AU, it is a 16550 with a quirk */ - if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) - up->bugs |= UART_BUG_NOMSR; -#endif - serial_outp(up, UART_LCR, save_lcr); if (up->capabilities != uart_config[up->port.type].flags) { @@ -1792,7 +1789,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; spin_unlock_irqrestore(&up->port.lock, flags); - return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; + return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; } static unsigned int serial8250_get_mctrl(struct uart_port *port) @@ -1850,8 +1847,6 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&up->port.lock, flags); } -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - /* * Wait for transmitter & holding register to empty */ @@ -2413,6 +2408,21 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, } static void +serial8250_set_ldisc(struct uart_port *port) +{ + int line = port->line; + + if (line >= port->state->port.tty->driver->num) + return; + + if (port->state->port.tty->ldisc->ops->num == N_PPS) { + port->flags |= UPF_HARDPPS_CD; + serial8250_enable_ms(port); + } else + port->flags &= ~UPF_HARDPPS_CD; +} + +static void serial8250_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { @@ -2427,7 +2437,7 @@ serial8250_pm(struct uart_port *port, unsigned int state, static unsigned int serial8250_port_size(struct uart_8250_port *pt) { if (pt->port.iotype == UPIO_AU) - return 0x100000; + return 0x1000; #ifdef CONFIG_ARCH_OMAP if (is_omap_port(pt)) return 0x16 << pt->port.regshift; @@ -2584,6 +2594,13 @@ static void serial8250_config_port(struct uart_port *port, int flags) if (flags & UART_CONFIG_TYPE) autoconfig(up, probeflags); + +#ifdef CONFIG_SERIAL_8250_AU1X00 + /* if access method is AU, it is a 16550 with a quirk */ + if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) + up->bugs |= UART_BUG_NOMSR; +#endif + if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) autoconfig_irq(up); @@ -2626,6 +2643,7 @@ static struct uart_ops serial8250_pops = { .startup = serial8250_startup, .shutdown = serial8250_shutdown, .set_termios = serial8250_set_termios, + .set_ldisc = serial8250_set_ldisc, .pm = serial8250_pm, .type = serial8250_type, .release_port = serial8250_release_port, @@ -2688,6 +2706,15 @@ static void __init serial8250_isa_init_ports(void) } } +static void +serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) +{ + up->port.type = type; + up->port.fifosize = uart_config[type].fifo_size; + up->capabilities = uart_config[type].flags; + up->tx_loadsz = uart_config[type].tx_loadsz; +} + static void __init serial8250_register_ports(struct uart_driver *drv, struct device *dev) { @@ -2704,6 +2731,10 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) struct uart_8250_port *up = &serial8250_ports[i]; up->port.dev = dev; + + if (up->port.flags & UPF_FIXED_TYPE) + serial8250_init_fixed_type_port(up, up->port.type); + uart_add_one_port(drv, &up->port); } } @@ -3116,12 +3147,8 @@ int serial8250_register_port(struct uart_port *port) if (port->dev) uart->port.dev = port->dev; - if (port->flags & UPF_FIXED_TYPE) { - uart->port.type = port->type; - uart->port.fifosize = uart_config[port->type].fifo_size; - uart->capabilities = uart_config[port->type].flags; - uart->tx_loadsz = uart_config[port->type].tx_loadsz; - } + if (port->flags & UPF_FIXED_TYPE) + serial8250_init_fixed_type_port(uart, port->type); set_io_from_upio(&uart->port); /* Possibly override default I/O functions. */ |