]> Pileus Git - ~andy/linux/blobdiff - drivers/serial/serial_core.c
Merge head 'drm-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
[~andy/linux] / drivers / serial / serial_core.c
index f5ce58d0514d35a9e83ef21693bc5fe7feec648a..54699c3a00ab4e48c1b6c6b196b24ddd80626bc2 100644 (file)
@@ -182,6 +182,13 @@ static int uart_startup(struct uart_state *state, int init_hw)
                                uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
                }
 
+               if (info->flags & UIF_CTS_FLOW) {
+                       spin_lock_irq(&port->lock);
+                       if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
+                               info->tty->hw_stopped = 1;
+                       spin_unlock_irq(&port->lock);
+               }
+
                info->flags |= UIF_INITIALIZED;
 
                clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1134,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios
                spin_unlock_irqrestore(&state->port->lock, flags);
        }
 
+       /* Handle turning on CRTSCTS */
+       if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+               spin_lock_irqsave(&state->port->lock, flags);
+               if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
+                       tty->hw_stopped = 1;
+                       state->port->ops->stop_tx(state->port, 0);
+               }
+               spin_unlock_irqrestore(&state->port->lock, flags);
+       }
+
 #if 0
        /*
         * No need to wake up processes in open wait, since they
@@ -1791,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co,
        struct termios termios;
        int i;
 
+       /*
+        * Ensure that the serial console lock is initialised
+        * early.
+        */
+       spin_lock_init(&port->lock);
+
        memset(&termios, 0, sizeof(struct termios));
 
        termios.c_cflag = CREAD | HUPCL | CLOCAL;
@@ -2179,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
 
        state->port = port;
 
-       spin_lock_init(&port->lock);
        port->cons = drv->cons;
        port->info = state->info;
 
+       /*
+        * If this port is a console, then the spinlock is already
+        * initialised.
+        */
+       if (!uart_console(port))
+               spin_lock_init(&port->lock);
+
        uart_configure_port(drv, state, port);
 
        /*