Merge 3.8-rc5 into tty-next
[cascardo/linux.git] / drivers / tty / serial / 8250 / 8250.c
index f932043..24939ca 100644 (file)
@@ -239,13 +239,6 @@ static const struct serial8250_config uart_config[] = {
                .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
                .flags          = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
        },
-       [PORT_RM9000] = {
-               .name           = "RM9000",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO,
-       },
        [PORT_OCTEON] = {
                .name           = "OCTEON",
                .fifo_size      = 64,
@@ -370,56 +363,6 @@ static void au_serial_dl_write(struct uart_8250_port *up, int value)
 
 #endif
 
-#ifdef CONFIG_SERIAL_8250_RM9K
-
-static const u8
-       regmap_in[8] = {
-               [UART_RX]       = 0x00,
-               [UART_IER]      = 0x0c,
-               [UART_IIR]      = 0x14,
-               [UART_LCR]      = 0x1c,
-               [UART_MCR]      = 0x20,
-               [UART_LSR]      = 0x24,
-               [UART_MSR]      = 0x28,
-               [UART_SCR]      = 0x2c
-       },
-       regmap_out[8] = {
-               [UART_TX]       = 0x04,
-               [UART_IER]      = 0x0c,
-               [UART_FCR]      = 0x18,
-               [UART_LCR]      = 0x1c,
-               [UART_MCR]      = 0x20,
-               [UART_LSR]      = 0x24,
-               [UART_MSR]      = 0x28,
-               [UART_SCR]      = 0x2c
-       };
-
-static unsigned int rm9k_serial_in(struct uart_port *p, int offset)
-{
-       offset = regmap_in[offset] << p->regshift;
-       return readl(p->membase + offset);
-}
-
-static void rm9k_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = regmap_out[offset] << p->regshift;
-       writel(value, p->membase + offset);
-}
-
-static int rm9k_serial_dl_read(struct uart_8250_port *up)
-{
-       return ((__raw_readl(up->port.membase + 0x10) << 8) |
-               (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff;
-}
-
-static void rm9k_serial_dl_write(struct uart_8250_port *up, int value)
-{
-       __raw_writel(value, up->port.membase + 0x08);
-       __raw_writel(value >> 8, up->port.membase + 0x10);
-}
-
-#endif
-
 static unsigned int hub6_serial_in(struct uart_port *p, int offset)
 {
        offset = offset << p->regshift;
@@ -497,15 +440,6 @@ static void set_io_from_upio(struct uart_port *p)
                p->serial_out = mem32_serial_out;
                break;
 
-#ifdef CONFIG_SERIAL_8250_RM9K
-       case UPIO_RM9000:
-               p->serial_in = rm9k_serial_in;
-               p->serial_out = rm9k_serial_out;
-               up->dl_read = rm9k_serial_dl_read;
-               up->dl_write = rm9k_serial_dl_write;
-               break;
-#endif
-
 #ifdef CONFIG_MIPS_ALCHEMY
        case UPIO_AU:
                p->serial_in = au_serial_in;
@@ -1341,7 +1275,9 @@ static void serial8250_start_tx(struct uart_port *port)
        struct uart_8250_port *up =
                container_of(port, struct uart_8250_port, port);
 
-       if (!(up->ier & UART_IER_THRI)) {
+       if (up->dma && !serial8250_tx_dma(up)) {
+               return;
+       } else if (!(up->ier & UART_IER_THRI)) {
                up->ier |= UART_IER_THRI;
                serial_port_out(port, UART_IER, up->ier);
 
@@ -1349,9 +1285,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 ((port->type == PORT_RM9000) ?
-                               (lsr & UART_LSR_THRE) :
-                               (lsr & UART_LSR_TEMT))
+                       if (lsr & UART_LSR_TEMT)
                                serial8250_tx_chars(up);
                }
        }
@@ -1397,7 +1331,6 @@ unsigned char
 serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
 {
        struct uart_port *port = &up->port;
-       struct tty_struct *tty = port->state->port.tty;
        unsigned char ch;
        int max_count = 256;
        char flag;
@@ -1462,7 +1395,7 @@ ignore_char:
                lsr = serial_in(up, UART_LSR);
        } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
        spin_unlock(&port->lock);
-       tty_flip_buffer_push(tty);
+       tty_flip_buffer_push(&port->state->port);
        spin_lock(&port->lock);
        return lsr;
 }
@@ -1547,6 +1480,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
        unsigned long flags;
        struct uart_8250_port *up =
                container_of(port, struct uart_8250_port, port);
+       int dma_err = 0;
 
        if (iir & UART_IIR_NO_INT)
                return 0;
@@ -1557,8 +1491,13 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 
        DEBUG_INTR("status = %x...", status);
 
-       if (status & (UART_LSR_DR | UART_LSR_BI))
-               status = serial8250_rx_chars(up, status);
+       if (status & (UART_LSR_DR | UART_LSR_BI)) {
+               if (up->dma)
+                       dma_err = serial8250_rx_dma(up, iir);
+
+               if (!up->dma || dma_err)
+                       status = serial8250_rx_chars(up, status);
+       }
        serial8250_modem_status(up);
        if (status & UART_LSR_THRE)
                serial8250_tx_chars(up);
@@ -1991,9 +1930,12 @@ static int serial8250_startup(struct uart_port *port)
        if (port->type == PORT_8250_CIR)
                return -ENODEV;
 
-       port->fifosize = uart_config[up->port.type].fifo_size;
-       up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
-       up->capabilities = uart_config[up->port.type].flags;
+       if (!port->fifosize)
+               port->fifosize = uart_config[port->type].fifo_size;
+       if (!up->tx_loadsz)
+               up->tx_loadsz = uart_config[port->type].tx_loadsz;
+       if (!up->capabilities)
+               up->capabilities = uart_config[port->type].flags;
        up->mcr = 0;
 
        if (port->iotype != up->cur_iotype)
@@ -2197,6 +2139,18 @@ dont_test_tx_en:
        up->lsr_saved_flags = 0;
        up->msr_saved_flags = 0;
 
+       /*
+        * Request DMA channels for both RX and TX.
+        */
+       if (up->dma) {
+               retval = serial8250_request_dma(up);
+               if (retval) {
+                       pr_warn_ratelimited("ttyS%d - failed to request DMA\n",
+                                           serial_index(port));
+                       up->dma = NULL;
+               }
+       }
+
        /*
         * Finally, enable interrupts.  Note: Modem status interrupts
         * are set via set_termios(), which will be occurring imminently
@@ -2230,6 +2184,9 @@ static void serial8250_shutdown(struct uart_port *port)
        up->ier = 0;
        serial_port_out(port, UART_IER, 0);
 
+       if (up->dma)
+               serial8250_release_dma(up);
+
        spin_lock_irqsave(&port->lock, flags);
        if (port->flags & UPF_FOURPORT) {
                /* reset interrupts on the AST Fourport board */
@@ -2826,9 +2783,12 @@ 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;
+       if (!up->port.fifosize)
+               up->port.fifosize = uart_config[type].fifo_size;
+       if (!up->tx_loadsz)
+               up->tx_loadsz = uart_config[type].tx_loadsz;
+       if (!up->capabilities)
+               up->capabilities = uart_config[type].flags;
 }
 
 static void __init
@@ -3262,6 +3222,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                uart->bugs              = up->bugs;
                uart->port.mapbase      = up->port.mapbase;
                uart->port.private_data = up->port.private_data;
+               uart->port.fifosize     = up->port.fifosize;
+               uart->tx_loadsz         = up->tx_loadsz;
+               uart->capabilities      = up->capabilities;
+
                if (up->port.dev)
                        uart->port.dev = up->port.dev;
 
@@ -3287,6 +3251,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                        uart->dl_read = up->dl_read;
                if (up->dl_write)
                        uart->dl_write = up->dl_write;
+               if (up->dma)
+                       uart->dma = up->dma;
 
                if (serial8250_isa_config != NULL)
                        serial8250_isa_config(0, &uart->port,