diff options
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 230 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_dma.c | 6 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_dw.c | 11 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_early.c | 13 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_omap.c | 88 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_pnp.c | 8 | ||||
-rw-r--r-- | drivers/tty/serial/8250/Kconfig | 19 |
8 files changed, 291 insertions, 88 deletions
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 11c66856ba2f..e3b9570a1eff 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -329,6 +329,17 @@ static const struct serial8250_config uart_config[] = { .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, +/* tx_loadsz is set to 63-bytes instead of 64-bytes to implement +workaround of errata A-008006 which states that tx_loadsz should be +configured less than Maximum supported fifo bytes */ + [PORT_16550A_FSL64] = { + .name = "16550A_FSL64", + .fifo_size = 64, + .tx_loadsz = 63, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | + UART_FCR7_64BYTE, + .flags = UART_CAP_FIFO, + }, }; /* Uart divisor latch read */ @@ -956,7 +967,17 @@ static void autoconfig_16550a(struct uart_8250_port *up) up->port.type = PORT_16650; up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; } else { - DEBUG_AUTOCONF("Motorola 8xxx DUART "); + serial_out(up, UART_LCR, 0); + serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR7_64BYTE); + status1 = serial_in(up, UART_IIR) >> 5; + serial_out(up, UART_FCR, 0); + serial_out(up, UART_LCR, 0); + + if (status1 == 7) + up->port.type = PORT_16550A_FSL64; + else + DEBUG_AUTOCONF("Motorola 8xxx DUART "); } serial_out(up, UART_EFR, 0); return; @@ -1355,9 +1376,11 @@ static void serial8250_start_tx(struct uart_port *port) struct uart_8250_port *up = up_to_u8250p(port); serial8250_rpm_get_tx(up); - if (up->dma && !up->dma->tx_dma(up)) { + + if (up->dma && !up->dma->tx_dma(up)) return; - } else if (!(up->ier & UART_IER_THRI)) { + + if (!(up->ier & UART_IER_THRI)) { up->ier |= UART_IER_THRI; serial_port_out(port, UART_IER, up->ier); @@ -1365,7 +1388,7 @@ static void serial8250_start_tx(struct uart_port *port) unsigned char lsr; lsr = serial_in(up, UART_LSR); up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; - if (lsr & UART_LSR_TEMT) + if (lsr & UART_LSR_THRE) serial8250_tx_chars(up); } } @@ -1924,7 +1947,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) return ret; } -static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) +void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct uart_8250_port *up = up_to_u8250p(port); unsigned char mcr = 0; @@ -1944,6 +1967,14 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) serial_port_out(port, UART_MCR, mcr); } +EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); + +static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + if (port->set_mctrl) + return port->set_mctrl(port, mctrl); + return serial8250_do_set_mctrl(port, mctrl); +} static void serial8250_break_ctl(struct uart_port *port, int break_state) { @@ -2382,13 +2413,34 @@ static void serial8250_shutdown(struct uart_port *port) serial8250_do_shutdown(port); } -static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) +/* + * XR17V35x UARTs have an extra fractional divisor register (DLD) + * Calculate divisor with extra 4-bit fractional portion + */ +static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up, + unsigned int baud, + unsigned int *frac) +{ + struct uart_port *port = &up->port; + unsigned int quot_16; + + quot_16 = DIV_ROUND_CLOSEST(port->uartclk, baud); + *frac = quot_16 & 0x0f; + + return quot_16 >> 4; +} + +static unsigned int serial8250_get_divisor(struct uart_8250_port *up, + unsigned int baud, + unsigned int *frac) { + struct uart_port *port = &up->port; unsigned int quot; /* * Handle magic divisors for baud rates above baud_base on * SMSC SuperIO chips. + * */ if ((port->flags & UPF_MAGIC_MULTIPLIER) && baud == (port->uartclk/4)) @@ -2396,22 +2448,26 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int else if ((port->flags & UPF_MAGIC_MULTIPLIER) && baud == (port->uartclk/8)) quot = 0x8002; + else if (up->port.type == PORT_XR17V35X) + quot = xr17v35x_get_divisor(up, baud, frac); else quot = uart_get_divisor(port, baud); + /* + * Oxford Semi 952 rev B workaround + */ + if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) + quot++; + return quot; } -void -serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) +static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, + tcflag_t c_cflag) { - struct uart_8250_port *up = up_to_u8250p(port); unsigned char cval; - unsigned long flags; - unsigned int baud, quot; - switch (termios->c_cflag & CSIZE) { + switch (c_cflag & CSIZE) { case CS5: cval = UART_LCR_WLEN5; break; @@ -2427,33 +2483,80 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, break; } - if (termios->c_cflag & CSTOPB) + if (c_cflag & CSTOPB) cval |= UART_LCR_STOP; - if (termios->c_cflag & PARENB) { + if (c_cflag & PARENB) { cval |= UART_LCR_PARITY; if (up->bugs & UART_BUG_PARITY) up->fifo_bug = true; } - if (!(termios->c_cflag & PARODD)) + if (!(c_cflag & PARODD)) cval |= UART_LCR_EPAR; #ifdef CMSPAR - if (termios->c_cflag & CMSPAR) + if (c_cflag & CMSPAR) cval |= UART_LCR_SPAR; #endif + return cval; +} + +static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, + unsigned int quot, unsigned int quot_frac) +{ + struct uart_8250_port *up = up_to_u8250p(port); + + /* Workaround to enable 115200 baud on OMAP1510 internal ports */ + if (is_omap1510_8250(up)) { + if (baud == 115200) { + quot = 1; + serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); + } else + serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); + } + + /* + * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, + * otherwise just set DLAB + */ + if (up->capabilities & UART_NATSEMI) + serial_port_out(port, UART_LCR, 0xe0); + else + serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); + + serial_dl_write(up, quot); + + /* XR17V35x UARTs have an extra fractional divisor register (DLD) */ + if (up->port.type == PORT_XR17V35X) + serial_port_out(port, 0x2, quot_frac); +} + +void +serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + struct ktermios *old) +{ + struct uart_8250_port *up = up_to_u8250p(port); + unsigned char cval; + unsigned long flags; + unsigned int baud, quot, frac = 0; + + cval = serial8250_compute_lcr(up, termios->c_cflag); + /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / 0xffff, port->uartclk / 16); - quot = serial8250_get_divisor(port, baud); + quot = serial8250_get_divisor(up, baud, &frac); /* - * Oxford Semi 952 rev B workaround + * Ok, we're now changing the port state. Do it with + * interrupts disabled. */ - if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) - quot++; + serial8250_rpm_get(up); + spin_lock_irqsave(&port->lock, flags); + + up->lcr = cval; /* Save computed LCR */ if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ @@ -2478,13 +2581,6 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, } /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. - */ - serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); - - /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); @@ -2548,43 +2644,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, serial_port_out(port, UART_EFR, efr); } - /* Workaround to enable 115200 baud on OMAP1510 internal ports */ - if (is_omap1510_8250(up)) { - if (baud == 115200) { - quot = 1; - serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); - } else - serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); - } - - /* - * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, - * otherwise just set DLAB - */ - if (up->capabilities & UART_NATSEMI) - serial_port_out(port, UART_LCR, 0xe0); - else - serial_port_out(port, UART_LCR, cval | UART_LCR_DLAB); - - serial_dl_write(up, quot); - - /* - * XR17V35x UARTs have an extra fractional divisor register (DLD) - * - * We need to recalculate all of the registers, because DLM and DLL - * are already rounded to a whole integer. - * - * When recalculating we use a 32x clock instead of a 16x clock to - * allow 1-bit for rounding in the fractional part. - */ - if (up->port.type == PORT_XR17V35X) { - unsigned int baud_x32 = (port->uartclk * 2) / baud; - u16 quot = baud_x32 / 32; - u8 quot_frac = DIV_ROUND_CLOSEST(baud_x32 % 32, 2); - - serial_dl_write(up, quot); - serial_port_out(port, 0x2, quot_frac & 0xf); - } + serial8250_set_divisor(port, baud, quot, frac); /* * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR @@ -2593,8 +2653,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if (port->type == PORT_16750) serial_port_out(port, UART_FCR, up->fcr); - serial_port_out(port, UART_LCR, cval); /* reset DLAB */ - up->lcr = cval; /* Save LCR */ + serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */ if (port->type != PORT_16750) { /* emulated UARTs (Lucent Venus 167x) need two steps */ if (up->fcr & UART_FCR_ENABLE_FIFO) @@ -3208,6 +3267,27 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) else serial_port_out(port, UART_IER, 0); + /* check scratch reg to see if port powered off during system sleep */ + if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { + struct ktermios termios; + unsigned int baud, quot, frac = 0; + + termios.c_cflag = port->cons->cflag; + if (port->state->port.tty && termios.c_cflag == 0) + termios.c_cflag = port->state->port.tty->termios.c_cflag; + + baud = uart_get_baud_rate(port, &termios, NULL, + port->uartclk / 16 / 0xffff, + port->uartclk / 16); + quot = serial8250_get_divisor(up, baud, &frac); + + serial8250_set_divisor(port, baud, quot, frac); + serial_port_out(port, UART_LCR, up->lcr); + serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); + + up->canary = 0; + } + uart_console_write(port, s, count, serial8250_console_putchar); /* @@ -3358,7 +3438,17 @@ int __init early_serial_setup(struct uart_port *port) */ void serial8250_suspend_port(int line) { - uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port); + struct uart_8250_port *up = &serial8250_ports[line]; + struct uart_port *port = &up->port; + + if (!console_suspend_enabled && uart_console(port) && + port->type != PORT_8250) { + unsigned char canary = 0xa5; + serial_out(up, UART_SCR, canary); + up->canary = canary; + } + + uart_suspend_port(&serial8250_reg, port); } /** @@ -3372,6 +3462,8 @@ void serial8250_resume_port(int line) struct uart_8250_port *up = &serial8250_ports[line]; struct uart_port *port = &up->port; + up->canary = 0; + if (up->capabilities & UART_NATSEMI) { /* Ensure it's still in high speed mode */ serial_port_out(port, UART_LCR, 0xE0); @@ -3605,6 +3697,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) /* Possibly override set_termios call */ if (up->port.set_termios) uart->port.set_termios = up->port.set_termios; + if (up->port.set_mctrl) + uart->port.set_mctrl = up->port.set_mctrl; if (up->port.startup) uart->port.startup = up->port.startup; if (up->port.shutdown) diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index fcd7ac6af2fc..21d01a491405 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -59,7 +59,6 @@ static void __dma_rx_complete(void *param) dma->rx_running = 0; dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); - dmaengine_terminate_all(dma->rxchan); count = dma->rx_size - state.residue; @@ -81,6 +80,10 @@ int serial8250_tx_dma(struct uart_8250_port *p) return 0; dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); + if (dma->tx_size < p->port.fifosize) { + ret = -EINVAL; + goto err; + } desc = dmaengine_prep_slave_single(dma->txchan, dma->tx_addr + xmit->tail, @@ -131,6 +134,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) if (dma->rx_running) { dmaengine_pause(dma->rxchan); __dma_rx_complete(p); + dmaengine_terminate_all(dma->rxchan); } return -ETIMEDOUT; default: diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 555de07db593..e60116235836 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -351,10 +351,20 @@ static int dw8250_probe_of(struct uart_port *p, static int dw8250_probe_acpi(struct uart_8250_port *up, struct dw8250_data *data) { + const struct acpi_device_id *id; struct uart_port *p = &up->port; dw8250_setup_port(up); + id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); + if (!id) + return -ENODEV; + + if (!p->uartclk) + if (device_property_read_u32(p->dev, "clock-frequency", + &p->uartclk)) + return -EINVAL; + p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; @@ -577,6 +587,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = { { "INT3435", 0 }, { "80860F0A", 0 }, { "8086228A", 0 }, + { "APMC0D08", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 4858b8a99d3b..c31a22b4f845 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -93,15 +93,18 @@ static void __init early_serial8250_write(struct console *console, struct uart_port *port = &early_device->port; unsigned int ier; - /* Save the IER and disable interrupts */ + /* Save the IER and disable interrupts preserving the UUE bit */ ier = serial8250_early_in(port, UART_IER); - serial8250_early_out(port, UART_IER, 0); + if (ier) + serial8250_early_out(port, UART_IER, ier & UART_IER_UUE); uart_console_write(port, s, count, serial_putc); /* Wait for transmitter to become empty and restore the IER */ wait_for_xmitr(port); - serial8250_early_out(port, UART_IER, ier); + + if (ier) + serial8250_early_out(port, UART_IER, ier); } static unsigned int __init probe_baud(struct uart_port *port) @@ -124,9 +127,11 @@ static void __init init_port(struct earlycon_device *device) struct uart_port *port = &device->port; unsigned int divisor; unsigned char c; + unsigned int ier; serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */ - serial8250_early_out(port, UART_IER, 0); /* no interrupt */ + ier = serial8250_early_in(port, UART_IER); + serial8250_early_out(port, UART_IER, ier & UART_IER_UUE); /* no interrupt */ serial8250_early_out(port, UART_FCR, 0); /* no fifo */ serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */ diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 96b69bfd773f..fe6d2e51da09 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -106,6 +106,28 @@ static u32 uart_read(struct uart_8250_port *up, u32 reg) return readl(up->port.membase + (reg << up->port.regshift)); } +static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + struct uart_8250_port *up = up_to_u8250p(port); + struct omap8250_priv *priv = up->port.private_data; + u8 lcr; + + serial8250_do_set_mctrl(port, mctrl); + + /* + * Turn off autoRTS if RTS is lowered and restore autoRTS setting + * if RTS is raised + */ + lcr = serial_in(up, UART_LCR); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) + priv->efr |= UART_EFR_RTS; + else + priv->efr &= ~UART_EFR_RTS; + serial_out(up, UART_EFR, priv->efr); + serial_out(up, UART_LCR, lcr); +} + /* * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460) * The access to uart register after MDR1 Access @@ -397,12 +419,12 @@ static void omap_8250_set_termios(struct uart_port *port, priv->efr = 0; up->mcr &= ~(UART_MCR_RTS | UART_MCR_XONANY); - if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { - /* Enable AUTORTS and AUTOCTS */ - priv->efr |= UART_EFR_CTS | UART_EFR_RTS; + up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); - /* Ensure MCR RTS is asserted */ - up->mcr |= UART_MCR_RTS; + if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { + /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ + up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; + priv->efr |= UART_EFR_CTS; } else if (up->port.flags & UPF_SOFT_FLOW) { /* * IXON Flag: @@ -417,8 +439,10 @@ static void omap_8250_set_termios(struct uart_port *port, * Enable XON/XOFF flow control on output. * Transmit XON1, XOFF1 */ - if (termios->c_iflag & IXOFF) + if (termios->c_iflag & IXOFF) { + up->port.status |= UPSTAT_AUTOXOFF; priv->efr |= OMAP_UART_SW_TX; + } /* * IXANY Flag: @@ -450,18 +474,18 @@ static void omap_8250_set_termios(struct uart_port *port, static void omap_8250_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { - struct uart_8250_port *up = - container_of(port, struct uart_8250_port, port); - struct omap8250_priv *priv = up->port.private_data; + struct uart_8250_port *up = up_to_u8250p(port); + u8 efr; pm_runtime_get_sync(port->dev); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(up, UART_EFR, priv->efr | UART_EFR_ECB); + efr = serial_in(up, UART_EFR); + serial_out(up, UART_EFR, efr | UART_EFR_ECB); serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(up, UART_EFR, priv->efr); + serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, 0); pm_runtime_mark_last_busy(port->dev); @@ -1007,6 +1031,7 @@ static int omap8250_probe(struct platform_device *pdev) up.capabilities |= UART_CAP_RPM; #endif up.port.set_termios = omap_8250_set_termios; + up.port.set_mctrl = omap8250_set_mctrl; up.port.pm = omap_8250_pm; up.port.startup = omap_8250_startup; up.port.shutdown = omap_8250_shutdown; @@ -1248,6 +1273,46 @@ static int omap8250_runtime_resume(struct device *dev) } #endif +#ifdef CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP +static int __init omap8250_console_fixup(void) +{ + char *omap_str; + char *options; + u8 idx; + + if (strstr(boot_command_line, "console=ttyS")) + /* user set a ttyS based name for the console */ + return 0; + + omap_str = strstr(boot_command_line, "console=ttyO"); + if (!omap_str) + /* user did not set ttyO based console, so we don't care */ + return 0; + + omap_str += 12; + if ('0' <= *omap_str && *omap_str <= '9') + idx = *omap_str - '0'; + else + return 0; + + omap_str++; + if (omap_str[0] == ',') { + omap_str++; + options = omap_str; + } else { + options = NULL; + } + + add_preferred_console("ttyS", idx, options); + pr_err("WARNING: Your 'console=ttyO%d' has been replaced by 'ttyS%d'\n", + idx, idx); + pr_err("This ensures that you still see kernel messages. Please\n"); + pr_err("update your kernel commandline.\n"); + return 0; +} +console_initcall(omap8250_console_fixup); +#endif + static const struct dev_pm_ops omap8250_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) SET_RUNTIME_PM_OPS(omap8250_runtime_suspend, @@ -1269,7 +1334,6 @@ static struct platform_driver omap8250_platform_driver = { .name = "omap8250", .pm = &omap8250_dev_pm_ops, .of_match_table = omap8250_dt_ids, - .owner = THIS_MODULE, }, .probe = omap8250_probe, .remove = omap8250_remove, diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index d1f8dc6aabcb..daf2c82984e9 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -221,13 +221,13 @@ pci_hp_diva_setup(struct serial_private *priv, */ static int pci_inteli960ni_init(struct pci_dev *dev) { - unsigned long oldval; + u32 oldval; if (!(dev->subsystem_device & 0x1000)) return -ENODEV; /* is firmware started? */ - pci_read_config_dword(dev, 0x44, (void *)&oldval); + pci_read_config_dword(dev, 0x44, &oldval); if (oldval == 0x00001000L) { /* RESET value */ dev_dbg(&dev->dev, "Local i960 firmware missing\n"); return -ENODEV; diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index 682a2fbe5c06..50a09cd76d50 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c @@ -426,7 +426,7 @@ static int serial_pnp_guess_board(struct pnp_dev *dev) static int serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { - struct uart_8250_port uart; + struct uart_8250_port uart, *port; int ret, line, flags = dev_id->driver_data; if (flags & UNKNOWN_DEV) { @@ -471,6 +471,10 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) if (line < 0 || (flags & CIR_PORT)) return -ENODEV; + port = serial8250_get_port(line); + if (uart_console(&port->port)) + dev->capabilities |= PNP_CONSOLE; + pnp_set_drvdata(dev, (void *)((long)line + 1)); return 0; } @@ -478,6 +482,8 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) static void serial_pnp_remove(struct pnp_dev *dev) { long line = (long)pnp_get_drvdata(dev); + + dev->capabilities &= ~PNP_CONSOLE; if (line) serial8250_unregister_port(line - 1); } diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 0fcbcd29502f..6f7f2d753def 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -308,6 +308,25 @@ config SERIAL_8250_OMAP This driver uses ttyS instead of ttyO. +config SERIAL_8250_OMAP_TTYO_FIXUP + bool "Replace ttyO with ttyS" + depends on SERIAL_8250_OMAP=y && SERIAL_8250_CONSOLE + default y + help + This option replaces the "console=ttyO" argument with the matching + ttyS argument if the user did not specified it on the command line. + This ensures that the user can see the kernel output during boot + which he wouldn't see otherwise. The getty has still to be configured + for ttyS instead of ttyO regardless of this option. + This option is intended for people who "automatically" enable this + driver without knowing that this driver requires a different console= + argument. If you read this, please keep this option disabled and + instead update your kernel command line. If you prepare a kernel for a + distribution or other kind of larger user base then you probably want + to keep this option enabled. Otherwise people might complain about a + not booting kernel because the serial console remains silent in case + they forgot to update the command line. + config SERIAL_8250_FINTEK tristate "Support for Fintek F81216A LPC to 4 UART" depends on SERIAL_8250 && PNP |