}
 }
 
-static int mxser_startup(struct tty_struct *tty)
+static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
 {
-       struct mxser_port *info = tty->driver_data;
+       struct mxser_port *info = container_of(port, struct mxser_port, port);
        unsigned long page;
        unsigned long flags;
 
 
        spin_lock_irqsave(&info->slock, flags);
 
-       if (info->port.flags & ASYNC_INITIALIZED) {
-               free_page(page);
-               spin_unlock_irqrestore(&info->slock, flags);
-               return 0;
-       }
-
        if (!info->ioaddr || !info->type) {
                set_bit(TTY_IO_ERROR, &tty->flags);
                free_page(page);
                spin_unlock_irqrestore(&info->slock, flags);
                return 0;
        }
-       if (info->port.xmit_buf)
-               free_page(page);
-       else
-               info->port.xmit_buf = (unsigned char *) page;
+       info->port.xmit_buf = (unsigned char *) page;
 
        /*
         * Clear the FIFO buffers and disable them
         * and set the speed of the serial port
         */
        mxser_change_speed(tty, NULL);
-       info->port.flags |= ASYNC_INITIALIZED;
        spin_unlock_irqrestore(&info->slock, flags);
 
        return 0;
 }
 
 /*
- * This routine will shutdown a serial port; interrupts maybe disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
+ * This routine will shutdown a serial port
  */
-static void mxser_shutdown(struct tty_struct *tty)
+static void mxser_shutdown_port(struct tty_port *port)
 {
-       struct mxser_port *info = tty->driver_data;
+       struct mxser_port *info = container_of(port, struct mxser_port, port);
        unsigned long flags;
 
-       if (!(info->port.flags & ASYNC_INITIALIZED))
-               return;
-
        spin_lock_irqsave(&info->slock, flags);
 
        /*
        wake_up_interruptible(&info->port.delta_msr_wait);
 
        /*
-        * Free the IRQ, if necessary
+        * Free the xmit buffer, if necessary
         */
        if (info->port.xmit_buf) {
                free_page((unsigned long) info->port.xmit_buf);
        info->IER = 0;
        outb(0x00, info->ioaddr + UART_IER);
 
-       if (tty->termios->c_cflag & HUPCL)
-               info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
-       outb(info->MCR, info->ioaddr + UART_MCR);
-
        /* clear Rx/Tx FIFO's */
        if (info->board->chip_flag)
                outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT |
        /* read data port to reset things */
        (void) inb(info->ioaddr + UART_RX);
 
-       set_bit(TTY_IO_ERROR, &tty->flags);
-
-       info->port.flags &= ~ASYNC_INITIALIZED;
 
        if (info->board->chip_flag)
                SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr);
 static int mxser_open(struct tty_struct *tty, struct file *filp)
 {
        struct mxser_port *info;
-       unsigned long flags;
-       int retval, line;
+       int line;
 
        line = tty->index;
        if (line == MXSER_PORTS)
        if (!info->ioaddr)
                return -ENODEV;
 
-       tty->driver_data = info;
-       tty_port_tty_set(&info->port, tty);
-       /*
-        * Start up serial port
-        */
-       spin_lock_irqsave(&info->port.lock, flags);
-       info->port.count++;
-       spin_unlock_irqrestore(&info->port.lock, flags);
-       retval = mxser_startup(tty);
-       if (retval)
-               return retval;
-
-       retval = tty_port_block_til_ready(&info->port, tty, filp);
-       if (retval)
-               return retval;
-
-       return 0;
+       return tty_port_open(&info->port, tty, filp);
 }
 
 static void mxser_flush_buffer(struct tty_struct *tty)
 }
 
 
-static void mxser_close_port(struct tty_struct *tty, struct tty_port *port)
+static void mxser_close_port(struct tty_port *port)
 {
        struct mxser_port *info = container_of(port, struct mxser_port, port);
        unsigned long timeout;
-       /*
-        * Save the termios structure, since this port may have
-        * separate termios for callout and dialin.
-        *
-        * FIXME: Can this go ?
-        */
-       if (port->flags & ASYNC_NORMAL_ACTIVE)
-               info->normal_termios = *tty->termios;
        /*
         * At this point we stop accepting input.  To do this, we
         * disable the receive line status interrupts, and tell the
        if (info->board->chip_flag)
                info->IER &= ~MOXA_MUST_RECV_ISR;
 
-       if (port->flags & ASYNC_INITIALIZED) {
-               outb(info->IER, info->ioaddr + UART_IER);
-               /*
-                * Before we drop DTR, make sure the UART transmitter
-                * has completely drained; this is especially
-                * important if there is a transmit FIFO!
-                */
-               timeout = jiffies + HZ;
-               while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
-                       schedule_timeout_interruptible(5);
-                       if (time_after(jiffies, timeout))
-                               break;
-               }
+       outb(info->IER, info->ioaddr + UART_IER);
+       /*
+        * Before we drop DTR, make sure the UART transmitter
+        * has completely drained; this is especially
+        * important if there is a transmit FIFO!
+        */
+       timeout = jiffies + HZ;
+       while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
+               schedule_timeout_interruptible(5);
+               if (time_after(jiffies, timeout))
+                       break;
        }
-       mxser_shutdown(tty);
-
 }
 
 /*
                return;
        if (tty_port_close_start(port, tty, filp) == 0)
                return;
-       mxser_close_port(tty, port);
+       mutex_lock(&port->mutex);
+       mxser_close_port(port);
        mxser_flush_buffer(tty);
+       mxser_shutdown_port(port);
+       clear_bit(ASYNCB_INITIALIZED, &port->flags);
+       mutex_unlock(&port->mutex);
        /* Right now the tty_port set is done outside of the close_end helper
           as we don't yet have everyone using refcounts */     
        tty_port_close_end(port, tty);
                        mxser_change_speed(tty, NULL);
                        spin_unlock_irqrestore(&info->slock, sl_flags);
                }
-       } else
-               retval = mxser_startup(tty);
-
+       } else {
+               mutex_lock(&info->port.mutex);
+               retval = mxser_activate(&info->port, tty);
+               if (retval == 0)
+                       set_bit(ASYNCB_INITIALIZED, &info->port.flags);
+               mutex_unlock(&info->port.mutex);
+       }
        return retval;
 }
 
        struct mxser_port *info = tty->driver_data;
 
        mxser_flush_buffer(tty);
-       mxser_shutdown(tty);
        tty_port_hangup(&info->port);
 }
 
 struct tty_port_operations mxser_port_ops = {
        .carrier_raised = mxser_carrier_raised,
        .dtr_rts = mxser_dtr_rts,
+       .activate = mxser_activate,
+       .shutdown = mxser_shutdown_port,
 };
 
 /*