Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[powerpc.git] / drivers / serial / 8250.c
index 2964ca9..48e259a 100644 (file)
@@ -251,9 +251,16 @@ static const struct serial8250_config uart_config[] = {
                .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
                .flags          = UART_CAP_FIFO | UART_CAP_UUE,
        },
+       [PORT_RM9000] = {
+               .name           = "RM9000",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO,
+       },
 };
 
-#ifdef CONFIG_SERIAL_8250_AU1X00
+#if defined (CONFIG_SERIAL_8250_AU1X00)
 
 /* Au1x00 UART hardware has a weird register layout */
 static const u8 au_io_in_map[] = {
@@ -289,6 +296,44 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
        return au_io_out_map[offset];
 }
 
+#elif defined (CONFIG_SERIAL_8250_RM9K)
+
+static const u8
+       regmap_in[8] = {
+               [UART_RX]       = 0x00,
+               [UART_IER]      = 0x0c,
+               [UART_IIR]      = 0x14,
+               [UART_LCR]      = 0x1c,
+               [UART_MCR]      = 0x20,
+               [UART_LSR]      = 0x24,
+               [UART_MSR]      = 0x28,
+               [UART_SCR]      = 0x2c
+       },
+       regmap_out[8] = {
+               [UART_TX]       = 0x04,
+               [UART_IER]      = 0x0c,
+               [UART_FCR]      = 0x18,
+               [UART_LCR]      = 0x1c,
+               [UART_MCR]      = 0x20,
+               [UART_LSR]      = 0x24,
+               [UART_MSR]      = 0x28,
+               [UART_SCR]      = 0x2c
+       };
+
+static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
+{
+       if (up->port.iotype != UPIO_RM9000)
+               return offset;
+       return regmap_in[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
+{
+       if (up->port.iotype != UPIO_RM9000)
+               return offset;
+       return regmap_out[offset];
+}
+
 #else
 
 /* sane hardware needs no mapping */
@@ -308,8 +353,10 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
                return inb(up->port.iobase + 1);
 
        case UPIO_MEM:
+       case UPIO_DWAPB:
                return readb(up->port.membase + offset);
 
+       case UPIO_RM9000:
        case UPIO_MEM32:
                return readl(up->port.membase + offset);
 
@@ -333,6 +380,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
 static void
 serial_out(struct uart_8250_port *up, int offset, int value)
 {
+       /* Save the offset before it's remapped */
+       int save_offset = offset;
        offset = map_8250_out_reg(up, offset) << up->port.regshift;
 
        switch (up->port.iotype) {
@@ -345,6 +394,7 @@ serial_out(struct uart_8250_port *up, int offset, int value)
                writeb(value, up->port.membase + offset);
                break;
 
+       case UPIO_RM9000:
        case UPIO_MEM32:
                writel(value, up->port.membase + offset);
                break;
@@ -359,11 +409,41 @@ serial_out(struct uart_8250_port *up, int offset, int value)
                        writeb(value, up->port.membase + offset);
                break;
 
+       case UPIO_DWAPB:
+               /* Save the LCR value so it can be re-written when a
+                * Busy Detect interrupt occurs. */
+               if (save_offset == UART_LCR)
+                       up->lcr = value;
+               writeb(value, up->port.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 = serial_in(up, UART_IER);
+               break;
+
        default:
                outb(value, up->port.iobase + offset);
        }
 }
 
+static void
+serial_out_sync(struct uart_8250_port *up, int offset, int value)
+{
+       switch (up->port.iotype) {
+       case UPIO_MEM:
+       case UPIO_MEM32:
+#ifdef CONFIG_SERIAL_8250_AU1X00
+       case UPIO_AU:
+#endif
+       case UPIO_DWAPB:
+               serial_out(up, offset, value);
+               serial_in(up, UART_LCR);        /* safe, no side-effects */
+               break;
+       default:
+               serial_out(up, offset, value);
+       }
+}
+
 /*
  * We used to support using pause I/O for certain machines.  We
  * haven't supported this for a while, but just in case it's badly
@@ -386,7 +466,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value)
        serial_outp(up, UART_DLM, value >> 8 & 0xff);
 }
 
-#ifdef CONFIG_SERIAL_8250_AU1X00
+#if defined (CONFIG_SERIAL_8250_AU1X00)
 /* Au1x00 haven't got a standard divisor latch */
 static int serial_dl_read(struct uart_8250_port *up)
 {
@@ -403,6 +483,24 @@ static void serial_dl_write(struct uart_8250_port *up, int value)
        else
                _serial_dl_write(up, value);
 }
+#elif defined (CONFIG_SERIAL_8250_RM9K)
+static int serial_dl_read(struct uart_8250_port *up)
+{
+       return  (up->port.iotype == UPIO_RM9000) ?
+               (((__raw_readl(up->port.membase + 0x10) << 8) |
+               (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
+               _serial_dl_read(up);
+}
+
+static void serial_dl_write(struct uart_8250_port *up, int value)
+{
+       if (up->port.iotype == UPIO_RM9000) {
+               __raw_writel(value, up->port.membase + 0x08);
+               __raw_writel(value >> 8, up->port.membase + 0x10);
+       } else {
+               _serial_dl_write(up, value);
+       }
+}
 #else
 #define serial_dl_read(up) _serial_dl_read(up)
 #define serial_dl_write(up, value) _serial_dl_write(up, value)
@@ -604,7 +702,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
  * its clones.  (We treat the broken original StarTech 16650 V1 as a
  * 16550, and why not?  Startech doesn't seem to even acknowledge its
  * existence.)
- * 
+ *
  * What evil have men's minds wrought...
  */
 static void autoconfig_has_efr(struct uart_8250_port *up)
@@ -657,7 +755,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
                        up->bugs |= UART_BUG_QUOT;
                return;
        }
-       
+
        /*
         * We check for a XR16C850 by setting DLL and DLM to 0, and then
         * reading back DLL and DLM.  The chip type depends on the DLM
@@ -800,7 +898,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
                        status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
                        status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
                        serial_outp(up, 0x04, status1);
-                       
+
                        serial_dl_write(up, quot);
 
                        serial_outp(up, UART_LCR, 0);
@@ -896,7 +994,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
         * be frobbing the chips IRQ enable register to see if it exists.
         */
        spin_lock_irqsave(&up->port.lock, flags);
-//     save_flags(flags); cli();
 
        up->capabilities = 0;
        up->bugs = 0;
@@ -905,7 +1002,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
                /*
                 * Do a simple existence test first; if we fail this,
                 * there's no point trying anything else.
-                * 
+                *
                 * 0x80 is used as a nonsense port to prevent against
                 * false positives due to ISA bus float.  The
                 * assumption is that 0x80 is a non-existent port;
@@ -944,7 +1041,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
        save_mcr = serial_in(up, UART_MCR);
        save_lcr = serial_in(up, UART_LCR);
 
-       /* 
+       /*
         * Check to see if a UART is really there.  Certain broken
         * internal modems based on the Rockwell chipset fail this
         * test, because they apparently don't implement the loopback
@@ -1045,15 +1142,14 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
 #endif
        serial_outp(up, UART_MCR, save_mcr);
        serial8250_clear_fifos(up);
-       (void)serial_in(up, UART_RX);
+       serial_in(up, UART_RX);
        if (up->capabilities & UART_CAP_UUE)
                serial_outp(up, UART_IER, UART_IER_UUE);
        else
                serial_outp(up, UART_IER, 0);
 
- out:  
+ out:
        spin_unlock_irqrestore(&up->port.lock, flags);
-//     restore_flags(flags);
        DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
 }
 
@@ -1077,7 +1173,7 @@ static void autoconfig_irq(struct uart_8250_port *up)
        save_mcr = serial_inp(up, UART_MCR);
        save_ier = serial_inp(up, UART_IER);
        serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
-       
+
        irqs = probe_irq_on();
        serial_outp(up, UART_MCR, 0);
        udelay (10);
@@ -1142,8 +1238,11 @@ static void serial8250_start_tx(struct uart_port *port)
                if (up->bugs & UART_BUG_TXEN) {
                        unsigned char lsr, iir;
                        lsr = serial_in(up, UART_LSR);
-                       iir = serial_in(up, UART_IIR);
-                       if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)
+                       iir = serial_in(up, UART_IIR) & 0x0f;
+                       if ((up->port.type == PORT_RM9000) ?
+                               (lsr & UART_LSR_THRE &&
+                               (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
+                               (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
                                transmit_chars(up);
                }
        }
@@ -1179,7 +1278,7 @@ static void serial8250_enable_ms(struct uart_port *port)
 }
 
 static void
-receive_chars(struct uart_8250_port *up, int *status)
+receive_chars(struct uart_8250_port *up, unsigned int *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch, lsr = *status;
@@ -1293,7 +1392,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
 {
        unsigned int status = serial_in(up, UART_MSR);
 
-       if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) {
+       if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+           up->port.info != NULL) {
                if (status & UART_MSR_TERI)
                        up->port.icount.rng++;
                if (status & UART_MSR_DDSR)
@@ -1316,8 +1416,9 @@ static inline void
 serial8250_handle_port(struct uart_8250_port *up)
 {
        unsigned int status;
+       unsigned long flags;
 
-       spin_lock(&up->port.lock);
+       spin_lock_irqsave(&up->port.lock, flags);
 
        status = serial_inp(up, UART_LSR);
 
@@ -1329,7 +1430,7 @@ serial8250_handle_port(struct uart_8250_port *up)
        if (status & UART_LSR_THRE)
                transmit_chars(up);
 
-       spin_unlock(&up->port.lock);
+       spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
 /*
@@ -1369,6 +1470,19 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 
                        handled = 1;
 
+                       end = NULL;
+               } else if (up->port.iotype == UPIO_DWAPB &&
+                         (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
+                        * UART was busy. The interrupt must be cleared by reading
+                        * the UART status register (USR) and the LCR re-written. */
+                       unsigned int status;
+                       status = *(volatile u32 *)up->port.private_data;
+                       serial_out(up, UART_LCR, up->lcr);
+
+                       handled = 1;
+
                        end = NULL;
                } else if (end == NULL)
                        end = l;
@@ -1451,6 +1565,12 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
        serial_do_unlink(i, up);
 }
 
+/* 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
@@ -1460,16 +1580,51 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
 static void serial8250_timeout(unsigned long data)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)data;
-       unsigned int timeout;
        unsigned int iir;
 
        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));
+}
+
+static void serial8250_backup_timeout(unsigned long data)
+{
+       struct uart_8250_port *up = (struct uart_8250_port *)data;
+       unsigned int iir, ier = 0;
+
+       /*
+        * Must disable interrupts or else we risk racing with the interrupt
+        * based handler.
+        */
+       if (is_real_interrupt(up->port.irq)) {
+               ier = serial_in(up, UART_IER);
+               serial_out(up, UART_IER, 0);
+       }
+
+       iir = serial_in(up, UART_IIR);
+
+       /*
+        * This should be a safe test for anyone who doesn't trust the
+        * IIR bits on their UART, but it's specifically designed for
+        * the "Diva" UART used on the management processor on many HP
+        * ia64 and parisc boxes.
+        */
+       if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
+           (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
+           (serial_in(up, UART_LSR) & UART_LSR_THRE)) {
+               iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
+               iir |= UART_IIR_THRI;
+       }
+
+       if (!(iir & UART_IIR_NO_INT))
+               serial8250_handle_port(up);
+
+       if (is_real_interrupt(up->port.irq))
+               serial_out(up, UART_IER, ier);
 
-       timeout = up->port.timeout;
-       timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
-       mod_timer(&up->timer, jiffies + timeout);
+       /* Standard timer interval plus 0.2s to keep the port running */
+       mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout) + HZ/5);
 }
 
 static unsigned int serial8250_tx_empty(struct uart_port *port)
@@ -1540,6 +1695,37 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
        spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+/*
+ *     Wait for transmitter & holding register to empty
+ */
+static inline 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 {
+               status = serial_in(up, UART_LSR);
+
+               if (status & UART_LSR_BI)
+                       up->lsr_break_flag = UART_LSR_BI;
+
+               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) {
+               tmout = 1000000;
+               while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
+                       udelay(1);
+                       touch_nmi_watchdog();
+               }
+       }
+}
+
 static int serial8250_startup(struct uart_port *port)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1613,18 +1799,50 @@ static int serial8250_startup(struct uart_port *port)
                serial_outp(up, UART_LCR, 0);
        }
 
+       if (is_real_interrupt(up->port.irq)) {
+               /*
+                * Test for UARTs that do not reassert THRE when the
+                * transmitter is idle and the interrupt has already
+                * been cleared.  Real 16550s should always reassert
+                * this interrupt whenever the transmitter is idle and
+                * the interrupt is enabled.  Delays are necessary to
+                * allow register changes to become visible.
+                */
+               spin_lock_irqsave(&up->port.lock, flags);
+
+               wait_for_xmitr(up, UART_LSR_THRE);
+               serial_out_sync(up, UART_IER, UART_IER_THRI);
+               udelay(1); /* allow THRE to set */
+               serial_in(up, UART_IIR);
+               serial_out(up, UART_IER, 0);
+               serial_out_sync(up, UART_IER, UART_IER_THRI);
+               udelay(1); /* allow a working UART time to re-assert THRE */
+               iir = serial_in(up, UART_IIR);
+               serial_out(up, UART_IER, 0);
+
+               spin_unlock_irqrestore(&up->port.lock, flags);
+
+               /*
+                * If the interrupt is not reasserted, setup a timer to
+                * kick the UART on a regular basis.
+                */
+               if (iir & UART_IIR_NO_INT) {
+                       pr_debug("ttyS%d - using backup timer\n", port->line);
+                       up->timer.function = serial8250_backup_timeout;
+                       up->timer.data = (unsigned long)up;
+                       mod_timer(&up->timer, jiffies +
+                                 poll_timeout(up->port.timeout) + HZ/5);
+               }
+       }
+
        /*
         * If the "interrupt" for this port doesn't correspond with any
         * hardware interrupt, we use a timer-based system.  The original
         * driver used to do this with IRQ0.
         */
        if (!is_real_interrupt(up->port.irq)) {
-               unsigned int timeout = up->port.timeout;
-
-               timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
-
                up->timer.data = (unsigned long)up;
-               mod_timer(&up->timer, jiffies + timeout);
+               mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
        } else {
                retval = serial_link_irq_chain(up);
                if (retval)
@@ -1740,9 +1958,9 @@ static void serial8250_shutdown(struct uart_port *port)
         */
        (void) serial_in(up, UART_RX);
 
-       if (!is_real_interrupt(up->port.irq))
-               del_timer_sync(&up->timer);
-       else
+       del_timer_sync(&up->timer);
+       up->timer.function = serial8250_timeout;
+       if (is_real_interrupt(up->port.irq))
                serial_unlink_irq_chain(up);
 }
 
@@ -1805,7 +2023,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
        /*
         * Ask the core to calculate the divisor for us.
         */
-       baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+       baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
        quot = serial8250_get_divisor(port, baud);
 
        /*
@@ -1967,6 +2185,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
        case UPIO_TSI:
        case UPIO_MEM32:
        case UPIO_MEM:
+       case UPIO_DWAPB:
                if (!up->port.mapbase)
                        break;
 
@@ -2004,6 +2223,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
        case UPIO_TSI:
        case UPIO_MEM32:
        case UPIO_MEM:
+       case UPIO_DWAPB:
                if (!up->port.mapbase)
                        break;
 
@@ -2212,37 +2432,6 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
 
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-/*
- *     Wait for transmitter & holding register to empty
- */
-static inline 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 {
-               status = serial_in(up, UART_LSR);
-
-               if (status & UART_LSR_BI)
-                       up->lsr_break_flag = UART_LSR_BI;
-
-               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) {
-               tmout = 1000000;
-               while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
-                       udelay(1);
-                       touch_nmi_watchdog();
-               }
-       }
-}
-
 static void serial8250_console_putchar(struct uart_port *port, int ch)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)port;