tty: 8250: Add 64byte UART support for FSL platforms
[firefly-linux-kernel-4.4.55.git] / drivers / tty / serial / 8250 / 8250_core.c
index 1d42dba6121d029eb9e900df9488b0d3a30f54dd..689169c11f0fc4153ad2a5e45d840a1712440faf 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/nmi.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
 #ifdef CONFIG_SPARC
 #include <linux/sunserialcore.h>
 #endif
@@ -327,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 */
@@ -539,6 +552,55 @@ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
 }
 EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
 
+void serial8250_rpm_get(struct uart_8250_port *p)
+{
+       if (!(p->capabilities & UART_CAP_RPM))
+               return;
+       pm_runtime_get_sync(p->port.dev);
+}
+EXPORT_SYMBOL_GPL(serial8250_rpm_get);
+
+void serial8250_rpm_put(struct uart_8250_port *p)
+{
+       if (!(p->capabilities & UART_CAP_RPM))
+               return;
+       pm_runtime_mark_last_busy(p->port.dev);
+       pm_runtime_put_autosuspend(p->port.dev);
+}
+EXPORT_SYMBOL_GPL(serial8250_rpm_put);
+
+/*
+ * These two wrappers ensure that enable_runtime_pm_tx() can be called more than
+ * once and disable_runtime_pm_tx() will still disable RPM because the fifo is
+ * empty and the HW can idle again.
+ */
+static void serial8250_rpm_get_tx(struct uart_8250_port *p)
+{
+       unsigned char rpm_active;
+
+       if (!(p->capabilities & UART_CAP_RPM))
+               return;
+
+       rpm_active = xchg(&p->rpm_tx_active, 1);
+       if (rpm_active)
+               return;
+       pm_runtime_get_sync(p->port.dev);
+}
+
+static void serial8250_rpm_put_tx(struct uart_8250_port *p)
+{
+       unsigned char rpm_active;
+
+       if (!(p->capabilities & UART_CAP_RPM))
+               return;
+
+       rpm_active = xchg(&p->rpm_tx_active, 0);
+       if (!rpm_active)
+               return;
+       pm_runtime_mark_last_busy(p->port.dev);
+       pm_runtime_put_autosuspend(p->port.dev);
+}
+
 /*
  * IER sleep support.  UARTs which have EFRs need the "extended
  * capability" bit enabled.  Note that on XR16C850s, we need to
@@ -546,6 +608,7 @@ EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
  */
 static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
 {
+       unsigned char lcr = 0, efr = 0;
        /*
         * Exar UARTs have a SLEEP register that enables or disables
         * each UART to enter sleep mode separately.  On the XR17V35x the
@@ -553,14 +616,17 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
         * offset but the UART channel may only write to the corresponding
         * bit.
         */
+       serial8250_rpm_get(p);
        if ((p->port.type == PORT_XR17V35X) ||
           (p->port.type == PORT_XR17D15X)) {
                serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0);
-               return;
+               goto out;
        }
 
        if (p->capabilities & UART_CAP_SLEEP) {
                if (p->capabilities & UART_CAP_EFR) {
+                       lcr = serial_in(p, UART_LCR);
+                       efr = serial_in(p, UART_EFR);
                        serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
                        serial_out(p, UART_EFR, UART_EFR_ECB);
                        serial_out(p, UART_LCR, 0);
@@ -568,10 +634,12 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
                serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
                if (p->capabilities & UART_CAP_EFR) {
                        serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
-                       serial_out(p, UART_EFR, 0);
-                       serial_out(p, UART_LCR, 0);
+                       serial_out(p, UART_EFR, efr);
+                       serial_out(p, UART_LCR, lcr);
                }
        }
+out:
+       serial8250_rpm_put(p);
 }
 
 #ifdef CONFIG_SERIAL_8250_RSA
@@ -899,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;
@@ -1272,6 +1350,7 @@ static inline void __stop_tx(struct uart_8250_port *p)
        if (p->ier & UART_IER_THRI) {
                p->ier &= ~UART_IER_THRI;
                serial_out(p, UART_IER, p->ier);
+               serial8250_rpm_put_tx(p);
        }
 }
 
@@ -1279,6 +1358,7 @@ static void serial8250_stop_tx(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
 
+       serial8250_rpm_get(up);
        __stop_tx(up);
 
        /*
@@ -1288,13 +1368,15 @@ static void serial8250_stop_tx(struct uart_port *port)
                up->acr |= UART_ACR_TXDIS;
                serial_icr_write(up, UART_ACR, up->acr);
        }
+       serial8250_rpm_put(up);
 }
 
 static void serial8250_start_tx(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
 
-       if (up->dma && !serial8250_tx_dma(up)) {
+       serial8250_rpm_get_tx(up);
+       if (up->dma && !up->dma->tx_dma(up)) {
                return;
        } else if (!(up->ier & UART_IER_THRI)) {
                up->ier |= UART_IER_THRI;
@@ -1318,13 +1400,40 @@ static void serial8250_start_tx(struct uart_port *port)
        }
 }
 
+static void serial8250_throttle(struct uart_port *port)
+{
+       port->throttle(port);
+}
+
+static void serial8250_unthrottle(struct uart_port *port)
+{
+       port->unthrottle(port);
+}
+
 static void serial8250_stop_rx(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
 
-       up->ier &= ~UART_IER_RLSI;
+       serial8250_rpm_get(up);
+
+       up->ier &= ~(UART_IER_RLSI | UART_IER_RDI);
        up->port.read_status_mask &= ~UART_LSR_DR;
        serial_port_out(port, UART_IER, up->ier);
+
+       serial8250_rpm_put(up);
+}
+
+static void serial8250_disable_ms(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       /* no MSR capabilities */
+       if (up->bugs & UART_BUG_NOMSR)
+               return;
+
+       up->ier &= ~UART_IER_MSI;
+       serial_port_out(port, UART_IER, up->ier);
 }
 
 static void serial8250_enable_ms(struct uart_port *port)
@@ -1336,7 +1445,10 @@ static void serial8250_enable_ms(struct uart_port *port)
                return;
 
        up->ier |= UART_IER_MSI;
+
+       serial8250_rpm_get(up);
        serial_port_out(port, UART_IER, up->ier);
+       serial8250_rpm_put(up);
 }
 
 /*
@@ -1410,7 +1522,7 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
 
 ignore_char:
                lsr = serial_in(up, UART_LSR);
-       } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
+       } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0));
        spin_unlock(&port->lock);
        tty_flip_buffer_push(&port->state->port);
        spin_lock(&port->lock);
@@ -1458,11 +1570,17 @@ void serial8250_tx_chars(struct uart_8250_port *up)
 
        DEBUG_INTR("THRE...");
 
-       if (uart_circ_empty(xmit))
+       /*
+        * With RPM enabled, we have to wait until the FIFO is empty before the
+        * HW can go idle. So we get here once again with empty FIFO and disable
+        * the interrupt and RPM in __stop_tx()
+        */
+       if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM))
                __stop_tx(up);
 }
 EXPORT_SYMBOL_GPL(serial8250_tx_chars);
 
+/* Caller holds uart port lock */
 unsigned int serial8250_modem_status(struct uart_8250_port *up)
 {
        struct uart_port *port = &up->port;
@@ -1509,13 +1627,14 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 
        if (status & (UART_LSR_DR | UART_LSR_BI)) {
                if (up->dma)
-                       dma_err = serial8250_rx_dma(up, iir);
+                       dma_err = up->dma->rx_dma(up, iir);
 
                if (!up->dma || dma_err)
                        status = serial8250_rx_chars(up, status);
        }
        serial8250_modem_status(up);
-       if (!up->dma && (status & UART_LSR_THRE))
+       if ((!up->dma || (up->dma && up->dma->tx_err)) &&
+           (status & UART_LSR_THRE))
                serial8250_tx_chars(up);
 
        spin_unlock_irqrestore(&port->lock, flags);
@@ -1525,9 +1644,17 @@ EXPORT_SYMBOL_GPL(serial8250_handle_irq);
 
 static int serial8250_default_handle_irq(struct uart_port *port)
 {
-       unsigned int iir = serial_port_in(port, UART_IIR);
+       struct uart_8250_port *up = up_to_u8250p(port);
+       unsigned int iir;
+       int ret;
+
+       serial8250_rpm_get(up);
+
+       iir = serial_port_in(port, UART_IIR);
+       ret = serial8250_handle_irq(port, iir);
 
-       return serial8250_handle_irq(port, iir);
+       serial8250_rpm_put(up);
+       return ret;
 }
 
 /*
@@ -1784,11 +1911,15 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
        unsigned long flags;
        unsigned int lsr;
 
+       serial8250_rpm_get(up);
+
        spin_lock_irqsave(&port->lock, flags);
        lsr = serial_port_in(port, UART_LSR);
        up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
        spin_unlock_irqrestore(&port->lock, flags);
 
+       serial8250_rpm_put(up);
+
        return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
 }
 
@@ -1798,7 +1929,9 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
        unsigned int status;
        unsigned int ret;
 
+       serial8250_rpm_get(up);
        status = serial8250_modem_status(up);
+       serial8250_rpm_put(up);
 
        ret = 0;
        if (status & UART_MSR_DCD)
@@ -1812,7 +1945,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;
@@ -1832,12 +1965,21 @@ 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)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        unsigned long flags;
 
+       serial8250_rpm_get(up);
        spin_lock_irqsave(&port->lock, flags);
        if (break_state == -1)
                up->lcr |= UART_LCR_SBC;
@@ -1845,6 +1987,7 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
                up->lcr &= ~UART_LCR_SBC;
        serial_port_out(port, UART_LCR, up->lcr);
        spin_unlock_irqrestore(&port->lock, flags);
+       serial8250_rpm_put(up);
 }
 
 /*
@@ -1889,12 +2032,23 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 
 static int serial8250_get_poll_char(struct uart_port *port)
 {
-       unsigned char lsr = serial_port_in(port, UART_LSR);
+       struct uart_8250_port *up = up_to_u8250p(port);
+       unsigned char lsr;
+       int status;
+
+       serial8250_rpm_get(up);
+
+       lsr = serial_port_in(port, UART_LSR);
 
-       if (!(lsr & UART_LSR_DR))
-               return NO_POLL_CHAR;
+       if (!(lsr & UART_LSR_DR)) {
+               status = NO_POLL_CHAR;
+               goto out;
+       }
 
-       return serial_port_in(port, UART_RX);
+       status = serial_port_in(port, UART_RX);
+out:
+       serial8250_rpm_put(up);
+       return status;
 }
 
 
@@ -1904,6 +2058,7 @@ static void serial8250_put_poll_char(struct uart_port *port,
        unsigned int ier;
        struct uart_8250_port *up = up_to_u8250p(port);
 
+       serial8250_rpm_get(up);
        /*
         *      First save the IER then disable the interrupts
         */
@@ -1925,11 +2080,12 @@ static void serial8250_put_poll_char(struct uart_port *port,
         */
        wait_for_xmitr(up, BOTH_EMPTY);
        serial_port_out(port, UART_IER, ier);
+       serial8250_rpm_put(up);
 }
 
 #endif /* CONFIG_CONSOLE_POLL */
 
-static int serial8250_startup(struct uart_port *port)
+int serial8250_do_startup(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        unsigned long flags;
@@ -1950,6 +2106,7 @@ static int serial8250_startup(struct uart_port *port)
        if (port->iotype != up->cur_iotype)
                set_io_from_upio(port);
 
+       serial8250_rpm_get(up);
        if (port->type == PORT_16C950) {
                /* Wake up and initialize UART */
                up->acr = 0;
@@ -1970,7 +2127,6 @@ static int serial8250_startup(struct uart_port *port)
         */
        enable_rsa(up);
 #endif
-
        /*
         * Clear the FIFO buffers and disable them.
         * (they will be reenabled in set_termios())
@@ -1980,8 +2136,8 @@ static int serial8250_startup(struct uart_port *port)
        /*
         * Clear the interrupt registers.
         */
-       serial_port_in(port, UART_LSR);
-       serial_port_in(port, UART_RX);
+       if (serial_port_in(port, UART_LSR) & UART_LSR_DR)
+               serial_port_in(port, UART_RX);
        serial_port_in(port, UART_IIR);
        serial_port_in(port, UART_MSR);
 
@@ -1994,7 +2150,8 @@ static int serial8250_startup(struct uart_port *port)
            (serial_port_in(port, UART_LSR) == 0xff)) {
                printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
                                   serial_index(port));
-               return -ENODEV;
+               retval = -ENODEV;
+               goto out;
        }
 
        /*
@@ -2079,7 +2236,7 @@ static int serial8250_startup(struct uart_port *port)
        } else {
                retval = serial_link_irq_chain(up);
                if (retval)
-                       return retval;
+                       goto out;
        }
 
        /*
@@ -2141,8 +2298,8 @@ dont_test_tx_en:
         * saved flags to avoid getting false values from polling
         * routines or the previous session.
         */
-       serial_port_in(port, UART_LSR);
-       serial_port_in(port, UART_RX);
+       if (serial_port_in(port, UART_LSR) & UART_LSR_DR)
+               serial_port_in(port, UART_RX);
        serial_port_in(port, UART_IIR);
        serial_port_in(port, UART_MSR);
        up->lsr_saved_flags = 0;
@@ -2177,15 +2334,26 @@ dont_test_tx_en:
                outb_p(0x80, icp);
                inb_p(icp);
        }
+       retval = 0;
+out:
+       serial8250_rpm_put(up);
+       return retval;
+}
+EXPORT_SYMBOL_GPL(serial8250_do_startup);
 
-       return 0;
+static int serial8250_startup(struct uart_port *port)
+{
+       if (port->startup)
+               return port->startup(port);
+       return serial8250_do_startup(port);
 }
 
-static void serial8250_shutdown(struct uart_port *port)
+void serial8250_do_shutdown(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        unsigned long flags;
 
+       serial8250_rpm_get(up);
        /*
         * Disable interrupts from this port
         */
@@ -2224,13 +2392,24 @@ static void serial8250_shutdown(struct uart_port *port)
         * Read data port to reset things, and then unlink from
         * the IRQ chain.
         */
-       serial_port_in(port, UART_RX);
+       if (serial_port_in(port, UART_LSR) & UART_LSR_DR)
+               serial_port_in(port, UART_RX);
+       serial8250_rpm_put(up);
 
        del_timer_sync(&up->timer);
        up->timer.function = serial8250_timeout;
        if (port->irq)
                serial_unlink_irq_chain(up);
 }
+EXPORT_SYMBOL_GPL(serial8250_do_shutdown);
+
+static void serial8250_shutdown(struct uart_port *port)
+{
+       if (port->shutdown)
+               port->shutdown(port);
+       else
+               serial8250_do_shutdown(port);
+}
 
 static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
 {
@@ -2319,11 +2498,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
         * the trigger, or the MCR RTS bit is cleared.  In the case where
         * the remote UART is not using CTS auto flow control, we must
         * have sufficient FIFO entries for the latency of the remote
-        * UART to respond.  IOW, at least 32 bytes of FIFO. Also enable
-        * AFE if hw flow control is supported
+        * UART to respond.  IOW, at least 32 bytes of FIFO.
         */
-       if ((up->capabilities & UART_CAP_AFE && (port->fifosize >= 32)) ||
-           (port->flags & UPF_HARD_FLOW)) {
+       if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) {
                up->mcr &= ~UART_MCR_AFE;
                if (termios->c_cflag & CRTSCTS)
                        up->mcr |= UART_MCR_AFE;
@@ -2333,6 +2510,7 @@ 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);
 
        /*
@@ -2454,6 +2632,8 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
        }
        serial8250_set_mctrl(port, port->mctrl);
        spin_unlock_irqrestore(&port->lock, flags);
+       serial8250_rpm_put(up);
+
        /* Don't rewrite B0 */
        if (tty_termios_baud_rate(termios))
                tty_termios_encode_baud_rate(termios, baud, baud);
@@ -2471,13 +2651,21 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
 }
 
 static void
-serial8250_set_ldisc(struct uart_port *port, int new)
+serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios)
 {
-       if (new == N_PPS) {
+       if (termios->c_line == N_PPS) {
                port->flags |= UPF_HARDPPS_CD;
+               spin_lock_irq(&port->lock);
                serial8250_enable_ms(port);
-       } else
+               spin_unlock_irq(&port->lock);
+       } else {
                port->flags &= ~UPF_HARDPPS_CD;
+               if (!UART_ENABLE_MS(port, termios->c_cflag)) {
+                       spin_lock_irq(&port->lock);
+                       serial8250_disable_ms(port);
+                       spin_unlock_irq(&port->lock);
+               }
+       }
 }
 
 
@@ -2502,8 +2690,11 @@ 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)
+       if (pt->port.iotype == UPIO_AU) {
+               if (pt->port.type == PORT_RT2880)
+                       return 0x100;
                return 0x1000;
+       }
        if (is_omap1_8250(pt))
                return 0x16 << pt->port.regshift;
 
@@ -2859,6 +3050,8 @@ static struct uart_ops serial8250_pops = {
        .get_mctrl      = serial8250_get_mctrl,
        .stop_tx        = serial8250_stop_tx,
        .start_tx       = serial8250_start_tx,
+       .throttle       = serial8250_throttle,
+       .unthrottle     = serial8250_unthrottle,
        .stop_rx        = serial8250_stop_rx,
        .enable_ms      = serial8250_enable_ms,
        .break_ctl      = serial8250_break_ctl,
@@ -2880,6 +3073,24 @@ static struct uart_ops serial8250_pops = {
 
 static struct uart_8250_port serial8250_ports[UART_NR];
 
+/**
+ * serial8250_get_port - retrieve struct uart_8250_port
+ * @line: serial line number
+ *
+ * This function retrieves struct uart_8250_port for the specific line.
+ * This struct *must* *not* be used to perform a 8250 or serial core operation
+ * which is not accessible otherwise. Its only purpose is to make the struct
+ * accessible to the runtime-pm callbacks for context suspend/restore.
+ * The lock assumption made here is none because runtime-pm suspend/resume
+ * callbacks should not be invoked if there is any operation performed on the
+ * port.
+ */
+struct uart_8250_port *serial8250_get_port(int line)
+{
+       return &serial8250_ports[line];
+}
+EXPORT_SYMBOL_GPL(serial8250_get_port);
+
 static void (*serial8250_isa_config)(int port, struct uart_port *up,
        unsigned short *capabilities);
 
@@ -3007,7 +3218,11 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
 
        touch_nmi_watchdog();
 
-       if (port->sysrq || oops_in_progress)
+       serial8250_rpm_get(up);
+
+       if (port->sysrq)
+               locked = 0;
+       else if (oops_in_progress)
                locked = spin_trylock_irqsave(&port->lock, flags);
        else
                spin_lock_irqsave(&port->lock, flags);
@@ -3043,9 +3258,10 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
 
        if (locked)
                spin_unlock_irqrestore(&port->lock, flags);
+       serial8250_rpm_put(up);
 }
 
-static int __init serial8250_console_setup(struct console *co, char *options)
+static int serial8250_console_setup(struct console *co, char *options)
 {
        struct uart_port *port;
        int baud = 9600;
@@ -3296,7 +3512,6 @@ static struct platform_driver serial8250_isa_driver = {
        .resume         = serial8250_resume,
        .driver         = {
                .name   = "serial8250",
-               .owner  = THIS_MODULE,
        },
 };
 
@@ -3324,6 +3539,11 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
                if (uart_match_port(&serial8250_ports[i].port, port))
                        return &serial8250_ports[i];
 
+       /* try line number first if still available */
+       i = port->line;
+       if (i < nr_uarts && serial8250_ports[i].port.type == PORT_UNKNOWN &&
+                       serial8250_ports[i].port.iobase == 0)
+               return &serial8250_ports[i];
        /*
         * We didn't find a matching entry, so look for the first
         * free entry.  We look for one which hasn't been previously
@@ -3388,6 +3608,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                uart->port.fifosize     = up->port.fifosize;
                uart->tx_loadsz         = up->tx_loadsz;
                uart->capabilities      = up->capabilities;
+               uart->port.throttle     = up->port.throttle;
+               uart->port.unthrottle   = up->port.unthrottle;
+               uart->port.rs485_config = up->port.rs485_config;
+               uart->port.rs485        = up->port.rs485;
 
                /* Take tx_loadsz from fifosize if it wasn't set separately */
                if (uart->port.fifosize && !uart->tx_loadsz)
@@ -3410,6 +3634,12 @@ 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)
+                       uart->port.shutdown = up->port.shutdown;
                if (up->port.pm)
                        uart->port.pm = up->port.pm;
                if (up->port.handle_break)
@@ -3418,8 +3648,13 @@ 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)
+               if (up->dma) {
                        uart->dma = up->dma;
+                       if (!uart->dma->tx_dma)
+                               uart->dma->tx_dma = serial8250_tx_dma;
+                       if (!uart->dma->rx_dma)
+                               uart->dma->rx_dma = serial8250_rx_dma;
+               }
 
                if (serial8250_isa_config != NULL)
                        serial8250_isa_config(0, &uart->port,
@@ -3587,7 +3822,7 @@ static void __used s8250_options(void)
 #ifdef CONFIG_SERIAL_8250_RSA
        __module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
                &param_array_ops, .arr = &__param_arr_probe_rsa,
-               0444, -1);
+               0444, -1, 0);
 #endif
 }
 #else