Merge git://git.infradead.org/mtd-2.6
[pandora-kernel.git] / drivers / serial / 8250.c
index ce948b6..342e12f 100644 (file)
@@ -1293,7 +1293,18 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
        char flag;
 
        do {
-               ch = serial_inp(up, UART_RX);
+               if (likely(lsr & UART_LSR_DR))
+                       ch = serial_inp(up, UART_RX);
+               else
+                       /*
+                        * Intel 82571 has a Serial Over Lan device that will
+                        * set UART_LSR_BI without setting UART_LSR_DR when
+                        * it receives a break. To avoid reading from the
+                        * receive buffer without UART_LSR_DR bit set, we
+                        * just force the read character to be 0
+                        */
+                       ch = 0;
+
                flag = TTY_NORMAL;
                up->port.icount.rx++;
 
@@ -1342,7 +1353,7 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
 
 ignore_char:
                lsr = serial_inp(up, UART_LSR);
-       } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
+       } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
        spin_unlock(&up->port.lock);
        tty_flip_buffer_push(tty);
        spin_lock(&up->port.lock);
@@ -1425,7 +1436,7 @@ serial8250_handle_port(struct uart_8250_port *up)
 
        DEBUG_INTR("status = %x...", status);
 
-       if (status & UART_LSR_DR)
+       if (status & (UART_LSR_DR | UART_LSR_BI))
                receive_chars(up, &status);
        check_modem_status(up);
        if (status & UART_LSR_THRE)
@@ -1875,6 +1886,8 @@ static int serial8250_startup(struct uart_port *port)
                 * allow register changes to become visible.
                 */
                spin_lock_irqsave(&up->port.lock, flags);
+               if (up->port.flags & UPF_SHARE_IRQ)
+                       disable_irq_nosync(up->port.irq);
 
                wait_for_xmitr(up, UART_LSR_THRE);
                serial_out_sync(up, UART_IER, UART_IER_THRI);
@@ -1886,6 +1899,8 @@ static int serial8250_startup(struct uart_port *port)
                iir = serial_in(up, UART_IIR);
                serial_out(up, UART_IER, 0);
 
+               if (up->port.flags & UPF_SHARE_IRQ)
+                       enable_irq(up->port.irq);
                spin_unlock_irqrestore(&up->port.lock, flags);
 
                /*