indicate that the signal is permanently active.  If RI is
        not available, the signal should not be indicated as active.
 
-       Locking: none.
-       Interrupts: caller dependent.
+       Locking: port->lock taken.
+       Interrupts: locally disabled.
        This call must not sleep
 
   stop_tx(port,tty_stop)
 
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)port;
-       unsigned long flags;
        unsigned char status;
        unsigned int ret;
 
-       spin_lock_irqsave(&up->port.lock, flags);
        status = serial_in(up, UART_MSR);
-       spin_unlock_irqrestore(&up->port.lock, flags);
 
        ret = 0;
        if (status & UART_MSR_DCD)
 
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)port;
-       unsigned long flags;
        unsigned char status;
        unsigned int ret;
 
-       spin_lock_irqsave(&up->port.lock, flags);
        status = serial_in(up, UART_MSR);
-       spin_unlock_irqrestore(&up->port.lock, flags);
 
        ret = 0;
        if (status & UART_MSR_DCD)
 
 static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
 {
        struct zilog_channel *channel;
-       unsigned long flags;
        unsigned char status;
 
-       spin_lock_irqsave(&port->lock, flags);
-
        channel = ZILOG_CHANNEL_FROM_PORT(port);
        status = readb(&channel->control);
        ZSDELAY();
 
-       spin_unlock_irqrestore(&port->lock, flags);
-
        return status;
 }
 
 /* The port lock is not held.  */
 static unsigned int ip22zilog_tx_empty(struct uart_port *port)
 {
+       unsigned long flags;
        unsigned char status;
        unsigned int ret;
 
+       spin_lock_irqsave(&port->lock, flags);
+
        status = ip22zilog_read_channel_status(port);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
        if (status & Tx_BUF_EMP)
                ret = TIOCSER_TEMT;
        else
        return ret;
 }
 
-/* The port lock is not held.  */
+/* The port lock is held and interrupts are disabled.  */
 static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
 {
        unsigned char status;
 
 {
        struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
        u32 mflags, status;
-       ulong iflags;
 
-       spin_lock_irqsave(&pi->port.lock, iflags);
        status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
                readl(pi->mpsc_base + MPSC_CHR_10);
-       spin_unlock_irqrestore(&pi->port.lock, iflags);
 
        mflags = 0;
        if (status & 0x1)
 
 /* 
  * Get Modem Control bits (only the input ones, the core will
  * or that with a cached value of the control ones)
- * The port lock is not held.
+ * The port lock is held and interrupts are disabled.
  */
 static unsigned int pmz_get_mctrl(struct uart_port *port)
 {
        if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
                return 0;
 
-       status = pmz_peek_status(to_pmz(port));
+       status = read_zsreg(uap, R0);
 
        ret = 0;
        if (status & DCD)
 
 static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
 {
        struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-       unsigned long flags;
        unsigned char status;
        unsigned int ret;
 
 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-       spin_lock_irqsave(&up->port.lock, flags);
        status = serial_in(up, UART_MSR);
-       spin_unlock_irqrestore(&up->port.lock, flags);
 
        ret = 0;
        if (status & UART_MSR_DCD)
 
        if ((!file || !tty_hung_up_p(file)) &&
            !(tty->flags & (1 << TTY_IO_ERROR))) {
                result = port->mctrl;
+
+               spin_lock_irq(&port->lock);
                result |= port->ops->get_mctrl(port);
+               spin_unlock_irq(&port->lock);
        }
        up(&state->sem);
 
        DECLARE_WAITQUEUE(wait, current);
        struct uart_info *info = state->info;
        struct uart_port *port = state->port;
+       unsigned int mctrl;
 
        info->blocked_open++;
        state->count--;
                 * and wait for the carrier to indicate that the
                 * modem is ready for us.
                 */
-               if (port->ops->get_mctrl(port) & TIOCM_CAR)
+               spin_lock_irq(&port->lock);
+               mctrl = port->ops->get_mctrl(port);
+               spin_unlock_irq(&port->lock);
+               if (mctrl & TIOCM_CAR)
                        break;
 
                up(&state->sem);
 
        if(capable(CAP_SYS_ADMIN))
        {
+               spin_lock_irq(&port->lock);
                status = port->ops->get_mctrl(port);
+               spin_unlock_irq(&port->lock);
 
                ret += sprintf(buf + ret, " tx:%d rx:%d",
                                port->icount.tx, port->icount.rx);
 
 static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
 {
        struct uart_txx9_port *up = (struct uart_txx9_port *)port;
-       unsigned long flags;
        unsigned int ret;
 
-       spin_lock_irqsave(&up->port.lock, flags);
        ret =  ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
                | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
-       spin_unlock_irqrestore(&up->port.lock, flags);
 
        return ret;
 }
 
                sunsab_tx_idle(up);
 }
 
-/* port->lock is not held.  */
+/* port->lock is held by caller and interrupts are disabled.  */
 static unsigned int sunsab_get_mctrl(struct uart_port *port)
 {
        struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
-       unsigned long flags;
        unsigned char val;
        unsigned int result;
 
        result = 0;
 
-       spin_lock_irqsave(&up->port.lock, flags);
-
        val = readb(&up->regs->r.pvr);
        result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
 
        val = readb(&up->regs->r.star);
        result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
 
-       spin_unlock_irqrestore(&up->port.lock, flags);
-
        return result;
 }
 
 
 static unsigned int sunsu_get_mctrl(struct uart_port *port)
 {
        struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
-       unsigned long flags;
        unsigned char status;
        unsigned int ret;
 
-       spin_lock_irqsave(&up->port.lock, flags);
        status = serial_in(up, UART_MSR);
-       spin_unlock_irqrestore(&up->port.lock, flags);
 
        ret = 0;
        if (status & UART_MSR_DCD)
 
 static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
 {
        struct zilog_channel __iomem *channel;
-       unsigned long flags;
        unsigned char status;
 
-       spin_lock_irqsave(&port->lock, flags);
-
        channel = ZILOG_CHANNEL_FROM_PORT(port);
        status = sbus_readb(&channel->control);
        ZSDELAY();
 
-       spin_unlock_irqrestore(&port->lock, flags);
-
        return status;
 }
 
 /* The port lock is not held.  */
 static unsigned int sunzilog_tx_empty(struct uart_port *port)
 {
+       unsigned long flags;
        unsigned char status;
        unsigned int ret;
 
+       spin_lock_irqsave(&port->lock, flags);
+
        status = sunzilog_read_channel_status(port);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
        if (status & Tx_BUF_EMP)
                ret = TIOCSER_TEMT;
        else
        return ret;
 }
 
-/* The port lock is not held.  */
+/* The port lock is held and interrupts are disabled.  */
 static unsigned int sunzilog_get_mctrl(struct uart_port *port)
 {
        unsigned char status;