Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[linux-flexiantxendom0-3.2.10.git] / drivers / serial / 8250.c
index 131c95f..4d8e14b 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 {
@@ -1606,8 +1601,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 +1717,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 +1731,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,7 +1776,7 @@ 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)
@@ -1867,15 +1856,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) {
@@ -2069,7 +2060,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 +2070,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)
@@ -2440,16 +2431,24 @@ 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;
 
        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)
@@ -2674,6 +2673,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 +2728,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);
+
        }
 }
 
@@ -3010,6 +3022,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 +3189,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)