serial: 8250: Fix THRE flag usage for CAP_MINI
[sfrench/cifs-2.6.git] / drivers / tty / serial / 8250 / 8250_port.c
index 09a65a3ec7f7df0bb3f7355fd7758d797169f960..a5fe0e66c60725bf227ea8acf2e93fe2adda5c4c 100644 (file)
@@ -47,6 +47,7 @@
 /*
  * These are definitions for the Exar XR17V35X and XR17(C|D)15X
  */
+#define UART_EXAR_INT0         0x80
 #define UART_EXAR_SLEEP                0x8b    /* Sleep mode */
 #define UART_EXAR_DVID         0x8d    /* Device identification */
 
@@ -1337,7 +1338,7 @@ out_lock:
        /*
         * Check if the device is a Fintek F81216A
         */
-       if (port->type == PORT_16550A)
+       if (port->type == PORT_16550A && port->iotype == UPIO_PORT)
                fintek_8250_probe(up);
 
        if (up->capabilities != old_capabilities) {
@@ -1763,6 +1764,10 @@ void serial8250_tx_chars(struct uart_8250_port *up)
                if ((up->capabilities & UART_CAP_HFIFO) &&
                    (serial_in(up, UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY)
                        break;
+               /* The BCM2835 MINI UART THRE bit is really a not-full bit. */
+               if ((up->capabilities & UART_CAP_MINI) &&
+                   !(serial_in(up, UART_LSR) & UART_LSR_THRE))
+                       break;
        } while (--count > 0);
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@ -1869,17 +1874,13 @@ static int serial8250_default_handle_irq(struct uart_port *port)
 static int exar_handle_irq(struct uart_port *port)
 {
        unsigned int iir = serial_port_in(port, UART_IIR);
-       int ret;
+       int ret = 0;
 
-       ret = serial8250_handle_irq(port, iir);
+       if (((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) &&
+           serial_port_in(port, UART_EXAR_INT0) != 0)
+               ret = 1;
 
-       if ((port->type == PORT_XR17V35X) ||
-          (port->type == PORT_XR17D15X)) {
-               serial_port_in(port, 0x80);
-               serial_port_in(port, 0x81);
-               serial_port_in(port, 0x82);
-               serial_port_in(port, 0x83);
-       }
+       ret |= serial8250_handle_irq(port, iir);
 
        return ret;
 }
@@ -2177,6 +2178,8 @@ int serial8250_do_startup(struct uart_port *port)
        serial_port_in(port, UART_RX);
        serial_port_in(port, UART_IIR);
        serial_port_in(port, UART_MSR);
+       if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
+               serial_port_in(port, UART_EXAR_INT0);
 
        /*
         * At this point, there's no way the LSR could still be 0xff;
@@ -2229,7 +2232,7 @@ int serial8250_do_startup(struct uart_port *port)
                }
        }
 
-       if (port->irq) {
+       if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
                unsigned char iir1;
                /*
                 * Test for UARTs that do not reassert THRE when the
@@ -2335,6 +2338,8 @@ dont_test_tx_en:
        serial_port_in(port, UART_RX);
        serial_port_in(port, UART_IIR);
        serial_port_in(port, UART_MSR);
+       if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
+               serial_port_in(port, UART_EXAR_INT0);
        up->lsr_saved_flags = 0;
        up->msr_saved_flags = 0;
 
@@ -2584,6 +2589,12 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
        unsigned long flags;
        unsigned int baud, quot, frac = 0;
 
+       if (up->capabilities & UART_CAP_MINI) {
+               termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR);
+               if ((termios->c_cflag & CSIZE) == CS5 ||
+                   (termios->c_cflag & CSIZE) == CS6)
+                       termios->c_cflag = (termios->c_cflag & ~CSIZE) | CS7;
+       }
        cval = serial8250_compute_lcr(up, termios->c_cflag);
 
        baud = serial8250_get_baud_rate(port, termios, old);