struct serial_port_device {
        struct device dev;
        struct uart_port *port;
+       unsigned int tx_enabled:1;
 };
 
 int serial_base_ctrl_init(void);
 int serial_base_port_init(void);
 void serial_base_port_exit(void);
 
+void serial_base_port_startup(struct uart_port *port);
+void serial_base_port_shutdown(struct uart_port *port);
+
 int serial_base_driver_register(struct device_driver *driver);
 void serial_base_driver_unregister(struct device_driver *driver);
 
 
                        bool init_hw)
 {
        struct tty_port *port = &state->port;
+       struct uart_port *uport;
        int retval;
 
        if (tty_port_initialized(port))
-               return 0;
+               goto out_base_port_startup;
 
        retval = uart_port_startup(tty, state, init_hw);
-       if (retval)
+       if (retval) {
                set_bit(TTY_IO_ERROR, &tty->flags);
+               return retval;
+       }
 
-       return retval;
+out_base_port_startup:
+       uport = uart_port_check(state);
+       if (!uport)
+               return -EIO;
+
+       serial_base_port_startup(uport);
+
+       return 0;
 }
 
 /*
        if (tty)
                set_bit(TTY_IO_ERROR, &tty->flags);
 
+       if (uport)
+               serial_base_port_shutdown(uport);
+
        if (tty_port_initialized(port)) {
                tty_port_set_initialized(port, false);
 
        uport->ops->stop_rx(uport);
        uart_port_unlock_irq(uport);
 
+       serial_base_port_shutdown(uport);
        uart_port_shutdown(port);
 
        /*
 
 
        /* Flush any pending TX for the port */
        uart_port_lock_irqsave(port, &flags);
+       if (!port_dev->tx_enabled)
+               goto unlock;
        if (__serial_port_busy(port))
                port->ops->start_tx(port);
+
+unlock:
        uart_port_unlock_irqrestore(port, flags);
 
 out:
                return 0;
 
        uart_port_lock_irqsave(port, &flags);
+       if (!port_dev->tx_enabled) {
+               uart_port_unlock_irqrestore(port, flags);
+               return 0;
+       }
+
        busy = __serial_port_busy(port);
        if (busy)
                port->ops->start_tx(port);
        return busy ? -EBUSY : 0;
 }
 
+static void serial_base_port_set_tx(struct uart_port *port,
+                                   struct serial_port_device *port_dev,
+                                   bool enabled)
+{
+       unsigned long flags;
+
+       uart_port_lock_irqsave(port, &flags);
+       port_dev->tx_enabled = enabled;
+       uart_port_unlock_irqrestore(port, flags);
+}
+
+void serial_base_port_startup(struct uart_port *port)
+{
+       struct serial_port_device *port_dev = port->port_dev;
+
+       serial_base_port_set_tx(port, port_dev, true);
+}
+
+void serial_base_port_shutdown(struct uart_port *port)
+{
+       struct serial_port_device *port_dev = port->port_dev;
+
+       serial_base_port_set_tx(port, port_dev, false);
+}
+
 static DEFINE_RUNTIME_DEV_PM_OPS(serial_port_pm,
                                 serial_port_runtime_suspend,
                                 serial_port_runtime_resume, NULL);