diff options
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/8250_pci.c | 10 | ||||
-rw-r--r-- | drivers/tty/serial/altera_uart.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 29 | ||||
-rw-r--r-- | drivers/tty/serial/atmel_serial.c | 5 | ||||
-rw-r--r-- | drivers/tty/serial/clps711x.c | 14 | ||||
-rw-r--r-- | drivers/tty/serial/jsm/jsm_driver.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/pch_uart.c | 7 | ||||
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 15 |
8 files changed, 64 insertions, 21 deletions
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index ff48fdb..21098ed 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -1459,51 +1459,61 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8811, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8812, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8813, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8814, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x8027, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x8028, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x8029, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x800C, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x800D, .init = pci_eg20t_init, + .setup = pci_default_setup, }, { .vendor = 0x10DB, .device = 0x800D, .init = pci_eg20t_init, + .setup = pci_default_setup, }, /* * Cronyx Omega PCI (PLX-chip based) diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 50bc5a5..37db1d5 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -555,7 +555,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) port->mapbase = res_mem->start; - else if (platp->mapbase) + else if (platp) port->mapbase = platp->mapbase; else return -EINVAL; @@ -563,7 +563,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res_irq) port->irq = res_irq->start; - else if (platp->irq) + else if (platp) port->irq = platp->irq; /* Check platform data first so we can override device node data */ diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index f5f6831..21dc4b7 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1376,6 +1376,10 @@ static int pl011_startup(struct uart_port *port) uap->port.uartclk = clk_get_rate(uap->clk); + /* Clear pending error and receive interrupts */ + writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | + UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); + /* * Allocate the IRQ */ @@ -1410,10 +1414,6 @@ static int pl011_startup(struct uart_port *port) cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; writew(cr, uap->port.membase + UART011_CR); - /* Clear pending error interrupts */ - writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, - uap->port.membase + UART011_ICR); - /* * initialise the old status of the modem signals */ @@ -1428,6 +1428,9 @@ static int pl011_startup(struct uart_port *port) * as well. */ spin_lock_irq(&uap->port.lock); + /* Clear out any spuriously appearing RX interrupts */ + writew(UART011_RTIS | UART011_RXIS, + uap->port.membase + UART011_ICR); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; @@ -1733,9 +1736,19 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; + unsigned long flags; + int locked = 1; clk_enable(uap->clk); + local_irq_save(flags); + if (uap->port.sysrq) + locked = 0; + else if (oops_in_progress) + locked = spin_trylock(&uap->port.lock); + else + spin_lock(&uap->port.lock); + /* * First save the CR then disable the interrupts */ @@ -1755,6 +1768,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) } while (status & UART01x_FR_BUSY); writew(old_cr, uap->port.membase + UART011_CR); + if (locked) + spin_unlock(&uap->port.lock); + local_irq_restore(flags); + clk_disable(uap->clk); } @@ -1906,6 +1923,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.line = i; pl011_dma_probe(uap); + /* Ensure interrupts from this UART are masked and cleared */ + writew(0, uap->port.membase + UART011_IMSC); + writew(0xffff, uap->port.membase + UART011_ICR); + snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); amba_ports[i] = uap; diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index af9b781..b989495 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -199,8 +199,9 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); unsigned int mode; + unsigned long flags; - spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); /* Disable interrupts */ UART_PUT_IDR(port, atmel_port->tx_done_mask); @@ -231,7 +232,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) /* Enable interrupts */ UART_PUT_IER(port, atmel_port->tx_done_mask); - spin_unlock(&port->lock); + spin_unlock_irqrestore(&port->lock, flags); } diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index e6c3dbd..836fe273 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -154,10 +154,9 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) port->x_char = 0; return IRQ_HANDLED; } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - clps711xuart_stop_tx(port); - return IRQ_HANDLED; - } + + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) + goto disable_tx_irq; count = port->fifosize >> 1; do { @@ -171,8 +170,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (uart_circ_empty(xmit)) - clps711xuart_stop_tx(port); + if (uart_circ_empty(xmit)) { + disable_tx_irq: + disable_irq_nosync(TX_IRQ(port)); + tx_enabled(port) = 0; + } return IRQ_HANDLED; } diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 2aaafa9..6c12d94 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -269,6 +269,7 @@ static void jsm_io_resume(struct pci_dev *pdev) struct jsm_board *brd = pci_get_drvdata(pdev); pci_restore_state(pdev); + pci_save_state(pdev); jsm_uart_port_init(brd); } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 902588b..101eda9 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -602,7 +602,8 @@ static void pch_request_dma(struct uart_port *port) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(0xa, 0)); /* Get DMA's dev + dma_dev = pci_get_bus_and_slot(priv->pdev->bus->number, + PCI_DEVFN(0xa, 0)); /* Get DMA's dev information */ /* Set Tx DMA */ param = &priv->param_tx; @@ -1353,9 +1354,11 @@ static int pch_uart_verify_port(struct uart_port *port, __func__); return -EOPNOTSUPP; #endif - priv->use_dma = 1; priv->use_dma_flag = 1; dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); + if (!priv->use_dma) + pch_request_dma(port); + priv->use_dma = 1; } return 0; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index ebd8629..bead17e 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -953,17 +953,20 @@ static void sci_dma_tx_complete(void *arg) port->icount.tx += sg_dma_len(&s->sg_tx); async_tx_ack(s->desc_tx); - s->cookie_tx = -EINVAL; s->desc_tx = NULL; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (!uart_circ_empty(xmit)) { + s->cookie_tx = 0; schedule_work(&s->work_tx); - } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { - u16 ctrl = sci_in(port, SCSCR); - sci_out(port, SCSCR, ctrl & ~SCSCR_TIE); + } else { + s->cookie_tx = -EINVAL; + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { + u16 ctrl = sci_in(port, SCSCR); + sci_out(port, SCSCR, ctrl & ~SCSCR_TIE); + } } spin_unlock_irqrestore(&port->lock, flags); @@ -1225,8 +1228,10 @@ static void sci_start_tx(struct uart_port *port) } if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && - s->cookie_tx < 0) + s->cookie_tx < 0) { + s->cookie_tx = 0; schedule_work(&s->work_tx); + } #endif if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |