Merge branch 'master' into for_paulus
[linux-drm-fsl-dcu.git] / drivers / serial / 8250.c
index 0ae9ced00ed4db899c591528a848f68a51c144a8..2964ca9df5a010f9cebb264e4115d5a588e5c234 100644 (file)
@@ -320,8 +320,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
 
        case UPIO_TSI:
                if (offset == UART_IIR) {
-                       tmp = readl((u32 *)(up->port.membase + UART_RX));
-                       return (cpu_to_le32(tmp) >> 8) & 0xff;
+                       tmp = readl(up->port.membase + (UART_IIR & ~3));
+                       return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
                } else
                        return readb(up->port.membase + offset);
 
@@ -920,12 +920,16 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
 #ifdef __i386__
                outb(0xff, 0x080);
 #endif
-               scratch2 = serial_inp(up, UART_IER);
+               /*
+                * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
+                * 16C754B) allow only to modify them if an EFR bit is set.
+                */
+               scratch2 = serial_inp(up, UART_IER) & 0x0f;
                serial_outp(up, UART_IER, 0x0F);
 #ifdef __i386__
                outb(0, 0x080);
 #endif
-               scratch3 = serial_inp(up, UART_IER);
+               scratch3 = serial_inp(up, UART_IER) & 0x0f;
                serial_outp(up, UART_IER, scratch);
                if (scratch2 != 0 || scratch3 != 0x0F) {
                        /*
@@ -1175,7 +1179,7 @@ static void serial8250_enable_ms(struct uart_port *port)
 }
 
 static void
-receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
+receive_chars(struct uart_8250_port *up, int *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch, lsr = *status;
@@ -1233,7 +1237,7 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
                        else if (lsr & UART_LSR_FE)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto ignore_char;
 
                uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
@@ -1309,7 +1313,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
  * This handles the interrupt from one port.
  */
 static inline void
-serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
+serial8250_handle_port(struct uart_8250_port *up)
 {
        unsigned int status;
 
@@ -1320,7 +1324,7 @@ serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
        DEBUG_INTR("status = %x...", status);
 
        if (status & UART_LSR_DR)
-               receive_chars(up, &status, regs);
+               receive_chars(up, &status);
        check_modem_status(up);
        if (status & UART_LSR_THRE)
                transmit_chars(up);
@@ -1342,7 +1346,7 @@ serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
  * This means we need to loop through all ports. checking that they
  * don't have an interrupt pending.
  */
-static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 {
        struct irq_info *i = dev_id;
        struct list_head *l, *end = NULL;
@@ -1361,7 +1365,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r
 
                iir = serial_in(up, UART_IIR);
                if (!(iir & UART_IIR_NO_INT)) {
-                       serial8250_handle_port(up, regs);
+                       serial8250_handle_port(up);
 
                        handled = 1;
 
@@ -1461,7 +1465,7 @@ static void serial8250_timeout(unsigned long data)
 
        iir = serial_in(up, UART_IIR);
        if (!(iir & UART_IIR_NO_INT))
-               serial8250_handle_port(up, NULL);
+               serial8250_handle_port(up);
 
        timeout = up->port.timeout;
        timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
@@ -1763,8 +1767,8 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int
 }
 
 static void
-serial8250_set_termios(struct uart_port *port, struct termios *termios,
-                      struct termios *old)
+serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
+                      struct ktermios *old)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)port;
        unsigned char cval, fcr = 0;
@@ -1896,6 +1900,17 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
                serial_outp(up, UART_EFR, efr);
        }
 
+#ifdef CONFIG_ARCH_OMAP15XX
+       /* Workaround to enable 115200 baud on OMAP1510 internal ports */
+       if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
+               if (baud == 115200) {
+                       quot = 1;
+                       serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
+               } else
+                       serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
+       }
+#endif
+
        if (up->capabilities & UART_NATSEMI) {
                /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
                serial_outp(up, UART_LCR, 0xe0);
@@ -1949,6 +1964,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
        case UPIO_AU:
                size = 0x100000;
                /* fall thru */
+       case UPIO_TSI:
+       case UPIO_MEM32:
        case UPIO_MEM:
                if (!up->port.mapbase)
                        break;
@@ -1984,6 +2001,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
        case UPIO_AU:
                size = 0x100000;
                /* fall thru */
+       case UPIO_TSI:
+       case UPIO_MEM32:
        case UPIO_MEM:
                if (!up->port.mapbase)
                        break;
@@ -2007,17 +2026,15 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up)
 {
        unsigned long start = UART_RSA_BASE << up->port.regshift;
        unsigned int size = 8 << up->port.regshift;
-       int ret = 0;
+       int ret = -EINVAL;
 
        switch (up->port.iotype) {
-       case UPIO_MEM:
-               ret = -EINVAL;
-               break;
-
        case UPIO_HUB6:
        case UPIO_PORT:
                start += up->port.iobase;
-               if (!request_region(start, size, "serial-rsa"))
+               if (request_region(start, size, "serial-rsa"))
+                       ret = 0;
+               else
                        ret = -EBUSY;
                break;
        }
@@ -2031,9 +2048,6 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
        unsigned int size = 8 << up->port.regshift;
 
        switch (up->port.iotype) {
-       case UPIO_MEM:
-               break;
-
        case UPIO_HUB6:
        case UPIO_PORT:
                release_region(up->port.iobase + offset, size);
@@ -2222,9 +2236,10 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
        /* Wait up to 1s for flow control if necessary */
        if (up->port.flags & UPF_CONS_FLOW) {
                tmout = 1000000;
-               while (--tmout &&
-                      ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+               while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
                        udelay(1);
+                       touch_nmi_watchdog();
+               }
        }
 }
 
@@ -2285,7 +2300,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
        local_irq_restore(flags);
 }
 
-static int serial8250_console_setup(struct console *co, char *options)
+static int __init serial8250_console_setup(struct console *co, char *options)
 {
        struct uart_port *port;
        int baud = 9600;
@@ -2397,7 +2412,6 @@ int __init early_serial_setup(struct uart_port *port)
 /**
  *     serial8250_suspend_port - suspend one serial port
  *     @line:  serial line number
- *      @level: the level of port suspension, as per uart_suspend_port
  *
  *     Suspend one serial port.
  */
@@ -2409,7 +2423,6 @@ void serial8250_suspend_port(int line)
 /**
  *     serial8250_resume_port - resume one serial port
  *     @line:  serial line number
- *      @level: the level of port resumption, as per uart_resume_port
  *
  *     Resume one serial port.
  */