]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/serial/8250.c
I2C: Add high-speed support to omap-i2c
[linux-2.6-omap-h63xx.git] / drivers / serial / 8250.c
index c9832d963f1efaf715f78a54cbd7d14c8d3ad64c..301e728cc0e0730d4196cd5695847b50f120da45 100644 (file)
@@ -894,7 +894,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
                        quot = serial_dl_read(up);
                        quot <<= 3;
 
-                       status1 = serial_in(up, 0x04); /* EXCR1 */
+                       status1 = serial_in(up, 0x04); /* EXCR2 */
                        status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
                        status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
                        serial_outp(up, 0x04, status1);
@@ -994,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;
@@ -1151,7 +1150,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
 
  out:
        spin_unlock_irqrestore(&up->port.lock, flags);
-//     restore_flags(flags);
        DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
 }
 
@@ -1503,7 +1501,11 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 
        DEBUG_INTR("end.\n");
 
+#ifdef CONFIG_ARCH_OMAP15XX
+       return IRQ_HANDLED;     /* FIXME: iir status not ready on 1510 */
+#else
        return IRQ_RETVAL(handled);
+#endif
 }
 
 /*
@@ -2154,6 +2156,19 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
                        /* emulated UARTs (Lucent Venus 167x) need two steps */
                        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
                }
+
+               /* Note that we need to set ECB to access write water mark
+                * bits. First allow FCR tx fifo write, then set fcr with
+                * possible TX fifo settings. */
+               if (uart_config[up->port.type].flags & UART_CAP_EFR) {
+                       serial_outp(up, UART_LCR, 0xbf);        /* Access EFR */
+                       serial_outp(up, UART_EFR, UART_EFR_ECB);
+                       serial_outp(up, UART_LCR, 0x0);         /* Access FCR */
+                       serial_outp(up, UART_FCR, fcr);
+                       serial_outp(up, UART_LCR, 0xbf);        /* Access EFR */
+                       serial_outp(up, UART_EFR, 0);
+                       serial_outp(up, UART_LCR, cval);        /* Access FCR */
+        } else
                serial_outp(up, UART_FCR, fcr);         /* set fcr */
        }
        serial8250_set_mctrl(&up->port, up->port.mctrl);
@@ -2180,6 +2195,11 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
        unsigned int size = 8 << up->port.regshift;
        int ret = 0;
 
+#ifdef CONFIG_ARCH_OMAP
+       if (is_omap_port((unsigned int)up->port.membase))
+               size = 0x16 << up->port.regshift;
+#endif
+
        switch (up->port.iotype) {
        case UPIO_AU:
                size = 0x100000;
@@ -2619,7 +2639,22 @@ void serial8250_suspend_port(int line)
  */
 void serial8250_resume_port(int line)
 {
-       uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
+       struct uart_8250_port *up = &serial8250_ports[line];
+
+       if (up->capabilities & UART_NATSEMI) {
+               unsigned char tmp;
+
+               /* Ensure it's still in high speed mode */
+               serial_outp(up, UART_LCR, 0xE0);
+
+               tmp = serial_in(up, 0x04); /* EXCR2 */
+               tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
+               tmp |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
+               serial_outp(up, 0x04, tmp);
+
+               serial_outp(up, UART_LCR, 0);
+       }
+       uart_resume_port(&serial8250_reg, &up->port);
 }
 
 /*
@@ -2696,7 +2731,7 @@ static int serial8250_resume(struct platform_device *dev)
                struct uart_8250_port *up = &serial8250_ports[i];
 
                if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
-                       uart_resume_port(&serial8250_reg, &up->port);
+                       serial8250_resume_port(i);
        }
 
        return 0;