* This routine will shutdown a serial port; interrupts are disabled, and
  * DTR is dropped if the hangup on close termio flag is on.  Calls to
  * uart_shutdown are serialised by the per-port semaphore.
+ *
+ * uport == NULL if uart_port has already been removed
  */
 static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
 {
                /*
                 * Turn off DTR and RTS early.
                 */
-               if (uart_console(uport) && tty)
+               if (uport && uart_console(uport) && tty)
                        uport->cons->cflag = tty->termios.c_cflag;
 
                if (!tty || C_HUPCL(tty))
  * Calls to uart_close() are serialised via the tty_lock in
  *   drivers/tty/tty_io.c:tty_release()
  *   drivers/tty/tty_io.c:do_tty_hangup()
- * This runs from a workqueue and can sleep for a _short_ time only.
  */
 static void uart_close(struct tty_struct *tty, struct file *filp)
 {
                return;
        }
 
-       uport = state->uart_port;
        port = &state->port;
        pr_debug("uart_close(%d) called\n", tty->index);
 
-       if (!port->count || tty_port_close_start(port, tty, filp) == 0)
+       if (tty_port_close_start(port, tty, filp) == 0)
                return;
 
+       mutex_lock(&port->mutex);
+       uport = uart_port_check(state);
+
        /*
         * At this point, we stop accepting input.  To do this, we
         * disable the receive line status interrupts.
         */
-       if (tty_port_initialized(port)) {
+       if (tty_port_initialized(port) &&
+           !WARN(!uport, "detached port still initialized!\n")) {
                spin_lock_irq(&uport->lock);
                uport->ops->stop_rx(uport);
                spin_unlock_irq(&uport->lock);
                uart_wait_until_sent(tty, uport->timeout);
        }
 
-       mutex_lock(&port->mutex);
        uart_shutdown(tty, state);
        tty_port_tty_set(port, NULL);
 
                if (port->close_delay)
                        msleep_interruptible(jiffies_to_msecs(port->close_delay));
                spin_lock_irq(&port->lock);
-       } else if (!uart_console(uport)) {
+       } else if (uport && !uart_console(uport)) {
                spin_unlock_irq(&port->lock);
                uart_change_pm(state, UART_PM_STATE_OFF);
                spin_lock_irq(&port->lock);
 {
        struct uart_state *state = tty->driver_data;
        struct tty_port *port = &state->port;
+       struct uart_port *uport;
        unsigned long flags;
 
        pr_debug("uart_hangup(%d)\n", tty->index);
 
        mutex_lock(&port->mutex);
+       uport = uart_port_check(state);
+       WARN(!uport, "hangup of detached port!\n");
+
        if (tty_port_active(port)) {
                uart_flush_buffer(tty);
                uart_shutdown(tty, state);
                spin_unlock_irqrestore(&port->lock, flags);
                tty_port_set_active(port, 0);
                tty_port_tty_set(port, NULL);
-               if (!uart_console(state->uart_port))
+               if (uport && !uart_console(uport))
                        uart_change_pm(state, UART_PM_STATE_OFF);
                wake_up_interruptible(&port->open_wait);
                wake_up_interruptible(&port->delta_msr_wait);
        mutex_unlock(&port->mutex);
 }
 
+/* uport == NULL if uart_port has already been removed */
 static void uart_port_shutdown(struct tty_port *port)
 {
        struct uart_state *state = container_of(port, struct uart_state, port);
        /*
         * Free the IRQ and disable the port.
         */
-       uport->ops->shutdown(uport);
+       if (uport)
+               uport->ops->shutdown(uport);
 
        /*
         * Ensure that the IRQ handler isn't running on another CPU.
         */
-       synchronize_irq(uport->irq);
+       if (uport)
+               synchronize_irq(uport->irq);
 }
 
 static int uart_carrier_raised(struct tty_port *port)