]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/serial/8250.c
rndis_wlan: use ARRAY_SIZE instead of sizeof when adding 11g rates
[linux-2.6-omap-h63xx.git] / drivers / serial / 8250.c
index b8a4bd94f51d5501cbf813d38f75147a9e180ab9..a1ca9b7bf2d5862b7466fbdcee4f5099b882ac76 100644 (file)
@@ -305,7 +305,7 @@ 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)
+#elif defined(CONFIG_SERIAL_8250_RM9K)
 
 static const u8
        regmap_in[8] = {
@@ -475,7 +475,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value)
        serial_outp(up, UART_DLM, value >> 8 & 0xff);
 }
 
-#if defined (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)
 {
@@ -492,7 +492,7 @@ static void serial_dl_write(struct uart_8250_port *up, int value)
        else
                _serial_dl_write(up, value);
 }
-#elif defined (CONFIG_SERIAL_8250_RM9K)
+#elif defined(CONFIG_SERIAL_8250_RM9K)
 static int serial_dl_read(struct uart_8250_port *up)
 {
        return  (up->port.iotype == UPIO_RM9000) ?
@@ -1185,8 +1185,8 @@ static void autoconfig_irq(struct uart_8250_port *up)
 
        irqs = probe_irq_on();
        serial_outp(up, UART_MCR, 0);
-       udelay (10);
-       if (up->port.flags & UPF_FOURPORT)  {
+       udelay(10);
+       if (up->port.flags & UPF_FOURPORT) {
                serial_outp(up, UART_MCR,
                            UART_MCR_DTR | UART_MCR_RTS);
        } else {
@@ -1199,7 +1199,7 @@ static void autoconfig_irq(struct uart_8250_port *up)
        (void)serial_inp(up, UART_IIR);
        (void)serial_inp(up, UART_MSR);
        serial_outp(up, UART_TX, 0xFF);
-       udelay (20);
+       udelay(20);
        irq = probe_irq_off(irqs);
 
        serial_outp(up, UART_MCR, save_mcr);
@@ -1343,7 +1343,7 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
 
                uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
 
-       ignore_char:
+ignore_char:
                lsr = serial_inp(up, UART_LSR);
        } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
        spin_unlock(&up->port.lock);
@@ -1633,7 +1633,8 @@ static void serial8250_backup_timeout(unsigned long data)
                serial_out(up, UART_IER, ier);
 
        /* Standard timer interval plus 0.2s to keep the port running */
-       mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout) + HZ/5);
+       mod_timer(&up->timer,
+               jiffies + poll_timeout(up->port.timeout) + HZ / 5);
 }
 
 static unsigned int serial8250_tx_empty(struct uart_port *port)
@@ -1739,6 +1740,60 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
        }
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+/*
+ * Console polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+static int serial8250_get_poll_char(struct uart_port *port)
+{
+       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       unsigned char lsr = serial_inp(up, UART_LSR);
+
+       while (!(lsr & UART_LSR_DR))
+               lsr = serial_inp(up, UART_LSR);
+
+       return serial_inp(up, UART_RX);
+}
+
+
+static void serial8250_put_poll_char(struct uart_port *port,
+                        unsigned char c)
+{
+       unsigned int ier;
+       struct uart_8250_port *up = (struct uart_8250_port *)port;
+
+       /*
+        *      First save the IER then disable the interrupts
+        */
+       ier = serial_in(up, UART_IER);
+       if (up->capabilities & UART_CAP_UUE)
+               serial_out(up, UART_IER, UART_IER_UUE);
+       else
+               serial_out(up, UART_IER, 0);
+
+       wait_for_xmitr(up, BOTH_EMPTY);
+       /*
+        *      Send the character out.
+        *      If a LF, also do CR...
+        */
+       serial_out(up, UART_TX, c);
+       if (c == 10) {
+               wait_for_xmitr(up, BOTH_EMPTY);
+               serial_out(up, UART_TX, 13);
+       }
+
+       /*
+        *      Finally, wait for transmitter to become empty
+        *      and restore the IER
+        */
+       wait_for_xmitr(up, BOTH_EMPTY);
+       serial_out(up, UART_IER, ier);
+}
+
+#endif /* CONFIG_CONSOLE_POLL */
+
 static int serial8250_startup(struct uart_port *port)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1813,6 +1868,7 @@ static int serial8250_startup(struct uart_port *port)
        }
 
        if (is_real_interrupt(up->port.irq)) {
+               unsigned char iir1;
                /*
                 * Test for UARTs that do not reassert THRE when the
                 * transmitter is idle and the interrupt has already
@@ -1826,7 +1882,7 @@ static int serial8250_startup(struct uart_port *port)
                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);
+               iir1 = 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 */
@@ -1839,12 +1895,12 @@ static int serial8250_startup(struct uart_port *port)
                 * If the interrupt is not reasserted, setup a timer to
                 * kick the UART on a regular basis.
                 */
-               if (iir & UART_IIR_NO_INT) {
+               if (!(iir1 & UART_IIR_NO_INT) && (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);
+                               poll_timeout(up->port.timeout) + HZ / 5);
                }
        }
 
@@ -2173,6 +2229,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
        }
        serial8250_set_mctrl(&up->port, up->port.mctrl);
        spin_unlock_irqrestore(&up->port.lock, flags);
+       /* Don't rewrite B0 */
+       if (tty_termios_baud_rate(termios))
+               tty_termios_encode_baud_rate(termios, baud, baud);
 }
 
 static void
@@ -2212,7 +2271,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
                }
 
                if (up->port.flags & UPF_IOREMAP) {
-                       up->port.membase = ioremap(up->port.mapbase, size);
+                       up->port.membase = ioremap_nocache(up->port.mapbase,
+                                                                       size);
                        if (!up->port.membase) {
                                release_mem_region(up->port.mapbase, size);
                                ret = -ENOMEM;
@@ -2384,6 +2444,10 @@ static struct uart_ops serial8250_pops = {
        .request_port   = serial8250_request_port,
        .config_port    = serial8250_config_port,
        .verify_port    = serial8250_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char = serial8250_get_poll_char,
+       .poll_put_char = serial8250_put_poll_char,
+#endif
 };
 
 static struct uart_8250_port serial8250_ports[UART_NR];