]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/tty/serial/8250.c
Merge branch 'master' into tk71
[mv-sheeva.git] / drivers / tty / serial / 8250.c
similarity index 94%
rename from drivers/serial/8250.c
rename to drivers/tty/serial/8250.c
index 24110f6f61e0efae9beddc0d509ba28968e73224..3975df6f7fdba6f4bff57f9c7fa05a8ae1bbeadf 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/tty.h>
+#include <linux/ratelimit.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_reg.h>
 #include <linux/serial_core.h>
@@ -154,12 +155,6 @@ struct uart_8250_port {
        unsigned char           lsr_saved_flags;
 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
        unsigned char           msr_saved_flags;
-
-       /*
-        * We provide a per-port pm hook.
-        */
-       void                    (*pm)(struct uart_port *port,
-                                     unsigned int state, unsigned int old);
 };
 
 struct irq_info {
@@ -241,7 +236,8 @@ static const struct serial8250_config uart_config[] = {
                .fifo_size      = 128,
                .tx_loadsz      = 128,
                .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+               /* UART_CAP_EFR breaks billionon CF bluetooth card. */
+               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
        },
        [PORT_16654] = {
                .name           = "ST16654",
@@ -459,21 +455,40 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value)
                writeb(value, p->membase + offset);
 }
 
+/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
+static inline void dwapb_save_out_value(struct uart_port *p, int offset,
+                                       int value)
+{
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
+
+       if (offset == UART_LCR)
+               up->lcr = value;
+}
+
+/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
+static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
+{
+       if (offset == UART_TX || offset == UART_IER)
+               p->serial_in(p, UART_IER);
+}
+
 static void dwapb_serial_out(struct uart_port *p, int offset, int value)
 {
        int save_offset = offset;
        offset = map_8250_out_reg(p, offset) << p->regshift;
-       /* Save the LCR value so it can be re-written when a
-        * Busy Detect interrupt occurs. */
-       if (save_offset == UART_LCR) {
-               struct uart_8250_port *up = (struct uart_8250_port *)p;
-               up->lcr = value;
-       }
+       dwapb_save_out_value(p, save_offset, value);
        writeb(value, p->membase + offset);
-       /* Read the IER to ensure any interrupt is cleared before
-        * returning from ISR. */
-       if (save_offset == UART_TX || save_offset == UART_IER)
-               value = p->serial_in(p, UART_IER);
+       dwapb_check_clear_ier(p, save_offset);
+}
+
+static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
+{
+       int save_offset = offset;
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       dwapb_save_out_value(p, save_offset, value);
+       writel(value, p->membase + offset);
+       dwapb_check_clear_ier(p, save_offset);
 }
 
 static unsigned int io_serial_in(struct uart_port *p, int offset)
@@ -490,7 +505,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
 
 static void set_io_from_upio(struct uart_port *p)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)p;
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
        switch (p->iotype) {
        case UPIO_HUB6:
                p->serial_in = hub6_serial_in;
@@ -523,6 +539,11 @@ static void set_io_from_upio(struct uart_port *p)
                p->serial_out = dwapb_serial_out;
                break;
 
+       case UPIO_DWAPB32:
+               p->serial_in = mem32_serial_in;
+               p->serial_out = dwapb32_serial_out;
+               break;
+
        default:
                p->serial_in = io_serial_in;
                p->serial_out = io_serial_out;
@@ -541,6 +562,7 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
        case UPIO_MEM32:
        case UPIO_AU:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                p->serial_out(p, offset, value);
                p->serial_in(p, UART_LCR);      /* safe, no side-effects */
                break;
@@ -658,13 +680,13 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
 {
        if (p->capabilities & UART_CAP_SLEEP) {
                if (p->capabilities & UART_CAP_EFR) {
-                       serial_outp(p, UART_LCR, 0xBF);
+                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
                        serial_outp(p, UART_EFR, UART_EFR_ECB);
                        serial_outp(p, UART_LCR, 0);
                }
                serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
                if (p->capabilities & UART_CAP_EFR) {
-                       serial_outp(p, UART_LCR, 0xBF);
+                       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
                        serial_outp(p, UART_EFR, 0);
                        serial_outp(p, UART_LCR, 0);
                }
@@ -757,7 +779,7 @@ static int size_fifo(struct uart_8250_port *up)
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
                    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
        serial_outp(up, UART_MCR, UART_MCR_LOOP);
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        old_dl = serial_dl_read(up);
        serial_dl_write(up, 0x0001);
        serial_outp(up, UART_LCR, 0x03);
@@ -769,7 +791,7 @@ static int size_fifo(struct uart_8250_port *up)
                serial_inp(up, UART_RX);
        serial_outp(up, UART_FCR, old_fcr);
        serial_outp(up, UART_MCR, old_mcr);
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_dl_write(up, old_dl);
        serial_outp(up, UART_LCR, old_lcr);
 
@@ -787,7 +809,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
        unsigned int id;
 
        old_lcr = serial_inp(p, UART_LCR);
-       serial_outp(p, UART_LCR, UART_LCR_DLAB);
+       serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A);
 
        old_dll = serial_inp(p, UART_DLL);
        old_dlm = serial_inp(p, UART_DLM);
@@ -841,7 +863,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
         * recommended for new designs).
         */
        up->acr = 0;
-       serial_out(up, UART_LCR, 0xBF);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_out(up, UART_EFR, UART_EFR_ECB);
        serial_out(up, UART_LCR, 0x00);
        id1 = serial_icr_read(up, UART_ID1);
@@ -924,7 +946,7 @@ static int broken_efr(struct uart_8250_port *up)
        /*
         * Exar ST16C2550 "A2" devices incorrectly detect as
         * having an EFR, and report an ID of 0x0201.  See
-        * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf
+        * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html 
         */
        if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
                return 1;
@@ -950,7 +972,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
         * Check for presence of the EFR when DLAB is set.
         * Only ST16C650V1 UARTs pass this test.
         */
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        if (serial_in(up, UART_EFR) == 0) {
                serial_outp(up, UART_EFR, 0xA8);
                if (serial_in(up, UART_EFR) != 0) {
@@ -968,7 +990,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
         * Maybe it requires 0xbf to be written to the LCR.
         * (other ST16C650V2 UARTs, TI16C752A, etc)
         */
-       serial_outp(up, UART_LCR, 0xBF);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
        if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
                DEBUG_AUTOCONF("EFRv2 ");
                autoconfig_has_efr(up);
@@ -1029,7 +1051,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
        status1 = serial_in(up, UART_IIR) >> 5;
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       serial_outp(up, UART_LCR, UART_LCR_DLAB);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
        status2 = serial_in(up, UART_IIR) >> 5;
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
@@ -1188,7 +1210,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
         * We also initialise the EFR (if any) to zero for later.  The
         * EFR occupies the same register location as the FCR and IIR.
         */
-       serial_outp(up, UART_LCR, 0xBF);
+       serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_outp(up, UART_EFR, 0);
        serial_outp(up, UART_LCR, 0);
 
@@ -1324,7 +1346,8 @@ static inline void __stop_tx(struct uart_8250_port *p)
 
 static void serial8250_stop_tx(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        __stop_tx(up);
 
@@ -1341,7 +1364,8 @@ static void transmit_chars(struct uart_8250_port *up);
 
 static void serial8250_start_tx(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        if (!(up->ier & UART_IER_THRI)) {
                up->ier |= UART_IER_THRI;
@@ -1369,7 +1393,8 @@ static void serial8250_start_tx(struct uart_port *port)
 
 static void serial8250_stop_rx(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        up->ier &= ~UART_IER_RLSI;
        up->port.read_status_mask &= ~UART_LSR_DR;
@@ -1378,7 +1403,8 @@ static void serial8250_stop_rx(struct uart_port *port)
 
 static void serial8250_enable_ms(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        /* no MSR capabilities */
        if (up->bugs & UART_BUG_NOMSR)
@@ -1586,7 +1612,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
                        handled = 1;
 
                        end = NULL;
-               } else if (up->port.iotype == UPIO_DWAPB &&
+               } else if ((up->port.iotype == UPIO_DWAPB ||
+                           up->port.iotype == UPIO_DWAPB32) &&
                          (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
                        /* The DesignWare APB UART has an Busy Detect (0x07)
                         * interrupt meaning an LCR write attempt occured while the
@@ -1606,8 +1633,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 
                if (l == i->head && pass_counter++ > PASS_LIMIT) {
                        /* If we hit this, we're dead. */
-                       printk(KERN_ERR "serial8250: too much work for "
-                               "irq%d\n", irq);
+                       printk_ratelimited(KERN_ERR
+                               "serial8250: too much work for irq%d\n", irq);
                        break;
                }
        } while (l != end);
@@ -1722,12 +1749,6 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
        mutex_unlock(&hash_mutex);
 }
 
-/* Base timer interval for polling */
-static inline int poll_timeout(int timeout)
-{
-       return timeout > 6 ? (timeout / 2 - 2) : 1;
-}
-
 /*
  * This function is used to handle ports that do not have an
  * interrupt.  This doesn't work very well for 16450's, but gives
@@ -1742,7 +1763,7 @@ static void serial8250_timeout(unsigned long data)
        iir = serial_in(up, UART_IIR);
        if (!(iir & UART_IIR_NO_INT))
                serial8250_handle_port(up);
-       mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
+       mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
 }
 
 static void serial8250_backup_timeout(unsigned long data)
@@ -1787,12 +1808,13 @@ static void serial8250_backup_timeout(unsigned long data)
 
        /* Standard timer interval plus 0.2s to keep the port running */
        mod_timer(&up->timer,
-               jiffies + poll_timeout(up->port.timeout) + HZ / 5);
+               jiffies + uart_poll_timeout(&up->port) + HZ / 5);
 }
 
 static unsigned int serial8250_tx_empty(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
        unsigned int lsr;
 
@@ -1806,7 +1828,8 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
 
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned int status;
        unsigned int ret;
 
@@ -1826,7 +1849,8 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
 
 static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char mcr = 0;
 
        if (mctrl & TIOCM_RTS)
@@ -1847,7 +1871,8 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
 static void serial8250_break_ctl(struct uart_port *port, int break_state)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
 
        spin_lock_irqsave(&up->port.lock, flags);
@@ -1867,15 +1892,17 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
        unsigned int status, tmout = 10000;
 
        /* Wait up to 10ms for the character(s) to be sent. */
-       do {
+       for (;;) {
                status = serial_in(up, UART_LSR);
 
                up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
 
+               if ((status & bits) == bits)
+                       break;
                if (--tmout == 0)
                        break;
                udelay(1);
-       } while ((status & bits) != bits);
+       }
 
        /* Wait up to 1s for flow control if necessary */
        if (up->port.flags & UPF_CONS_FLOW) {
@@ -1899,7 +1926,8 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 
 static int serial8250_get_poll_char(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char lsr = serial_inp(up, UART_LSR);
 
        if (!(lsr & UART_LSR_DR))
@@ -1913,7 +1941,8 @@ static void serial8250_put_poll_char(struct uart_port *port,
                         unsigned char c)
 {
        unsigned int ier;
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        /*
         *      First save the IER then disable the interrupts
@@ -1947,11 +1976,14 @@ static void serial8250_put_poll_char(struct uart_port *port,
 
 static int serial8250_startup(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
        unsigned char lsr, iir;
        int retval;
 
+       up->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;
        up->mcr = 0;
 
@@ -1961,7 +1993,7 @@ static int serial8250_startup(struct uart_port *port)
        if (up->port.type == PORT_16C950) {
                /* Wake up and initialize UART */
                up->acr = 0;
-               serial_outp(up, UART_LCR, 0xBF);
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
                serial_outp(up, UART_EFR, UART_EFR_ECB);
                serial_outp(up, UART_IER, 0);
                serial_outp(up, UART_LCR, 0);
@@ -2011,7 +2043,7 @@ static int serial8250_startup(struct uart_port *port)
        if (up->port.type == PORT_16850) {
                unsigned char fctr;
 
-               serial_outp(up, UART_LCR, 0xbf);
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
 
                fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
                serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
@@ -2069,7 +2101,7 @@ static int serial8250_startup(struct uart_port *port)
                up->timer.function = serial8250_backup_timeout;
                up->timer.data = (unsigned long)up;
                mod_timer(&up->timer, jiffies +
-                         poll_timeout(up->port.timeout) + HZ / 5);
+                       uart_poll_timeout(port) + HZ / 5);
        }
 
        /*
@@ -2079,7 +2111,7 @@ static int serial8250_startup(struct uart_port *port)
         */
        if (!is_real_interrupt(up->port.irq)) {
                up->timer.data = (unsigned long)up;
-               mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
+               mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
        } else {
                retval = serial_link_irq_chain(up);
                if (retval)
@@ -2175,7 +2207,8 @@ dont_test_tx_en:
 
 static void serial8250_shutdown(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
 
        /*
@@ -2244,7 +2277,8 @@ void
 serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                          struct ktermios *old)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
@@ -2372,7 +2406,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                if (termios->c_cflag & CRTSCTS)
                        efr |= UART_EFR_CTS;
 
-               serial_outp(up, UART_LCR, 0xBF);
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
                serial_outp(up, UART_EFR, efr);
        }
 
@@ -2440,16 +2474,25 @@ serial8250_set_ldisc(struct uart_port *port, int new)
                port->flags &= ~UPF_HARDPPS_CD;
 }
 
-static void
-serial8250_pm(struct uart_port *port, unsigned int state,
-             unsigned int oldstate)
+
+void serial8250_do_pm(struct uart_port *port, unsigned int state,
+                     unsigned int oldstate)
 {
-       struct uart_8250_port *p = (struct uart_8250_port *)port;
+       struct uart_8250_port *p =
+               container_of(port, struct uart_8250_port, port);
 
        serial8250_set_sleep(p, state != 0);
+}
+EXPORT_SYMBOL(serial8250_do_pm);
 
-       if (p->pm)
-               p->pm(port, state, oldstate);
+static void
+serial8250_pm(struct uart_port *port, unsigned int state,
+             unsigned int oldstate)
+{
+       if (port->pm)
+               port->pm(port, state, oldstate);
+       else
+               serial8250_do_pm(port, state, oldstate);
 }
 
 static unsigned int serial8250_port_size(struct uart_8250_port *pt)
@@ -2477,6 +2520,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
        case UPIO_MEM32:
        case UPIO_MEM:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                if (!up->port.mapbase)
                        break;
 
@@ -2514,6 +2558,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
        case UPIO_MEM32:
        case UPIO_MEM:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                if (!up->port.mapbase)
                        break;
 
@@ -2567,7 +2612,8 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
 
 static void serial8250_release_port(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        serial8250_release_std_resource(up);
        if (up->port.type == PORT_RSA)
@@ -2576,7 +2622,8 @@ static void serial8250_release_port(struct uart_port *port)
 
 static int serial8250_request_port(struct uart_port *port)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        int ret = 0;
 
        ret = serial8250_request_std_resource(up);
@@ -2591,7 +2638,8 @@ static int serial8250_request_port(struct uart_port *port)
 
 static void serial8250_config_port(struct uart_port *port, int flags)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        int probeflags = PROBE_ANY;
        int ret;
 
@@ -2674,6 +2722,16 @@ static struct uart_ops serial8250_pops = {
 
 static struct uart_8250_port serial8250_ports[UART_NR];
 
+static void (*serial8250_isa_config)(int port, struct uart_port *up,
+       unsigned short *capabilities);
+
+void serial8250_set_isa_configurator(
+       void (*v)(int port, struct uart_port *up, unsigned short *capabilities))
+{
+       serial8250_isa_config = v;
+}
+EXPORT_SYMBOL(serial8250_set_isa_configurator);
+
 static void __init serial8250_isa_init_ports(void)
 {
        struct uart_8250_port *up;
@@ -2719,6 +2777,9 @@ static void __init serial8250_isa_init_ports(void)
                up->port.regshift = old_serial_port[i].iomem_reg_shift;
                set_io_from_upio(&up->port);
                up->port.irqflags |= irqflag;
+               if (serial8250_isa_config != NULL)
+                       serial8250_isa_config(i, &up->port, &up->capabilities);
+
        }
 }
 
@@ -2759,7 +2820,8 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
 
 static void serial8250_console_putchar(struct uart_port *port, int ch)
 {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
 
        wait_for_xmitr(up, UART_LSR_THRE);
        serial_out(up, UART_TX, ch);
@@ -2860,7 +2922,7 @@ static struct console serial8250_console = {
        .device         = uart_console_device,
        .setup          = serial8250_console_setup,
        .early_setup    = serial8250_console_early_setup,
-       .flags          = CON_PRINTBUFFER,
+       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
        .index          = -1,
        .data           = &serial8250_reg,
 };
@@ -3010,6 +3072,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
                port.serial_in          = p->serial_in;
                port.serial_out         = p->serial_out;
                port.set_termios        = p->set_termios;
+               port.pm                 = p->pm;
                port.dev                = &dev->dev;
                port.irqflags           |= irqflag;
                ret = serial8250_register_port(&port);
@@ -3176,6 +3239,12 @@ int serial8250_register_port(struct uart_port *port)
                /*  Possibly override set_termios call */
                if (port->set_termios)
                        uart->port.set_termios = port->set_termios;
+               if (port->pm)
+                       uart->port.pm = port->pm;
+
+               if (serial8250_isa_config != NULL)
+                       serial8250_isa_config(0, &uart->port,
+                                       &uart->capabilities);
 
                ret = uart_add_one_port(&serial8250_reg, &uart->port);
                if (ret == 0)