static void sc26xx_disable_irq(struct uart_port *port, int mask)
{
	struct uart_sc26xx_port *up;
	int line = port->line;

	port -= line;
	up = container_of(port, struct uart_sc26xx_port, port[0]);

	up->imr &= ~(mask << (line * 4));
	WRITE_SC(port, IMR, up->imr);
}
/* port->lock held by caller.  */
static void sc26xx_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	struct uart_sc26xx_port *up;
	int line = port->line;

	port -= line;
	up = container_of(port, struct uart_sc26xx_port, port[0]);

	if (up->dtr_mask[line]) {
		if (mctrl & TIOCM_DTR)
			WRITE_SC(port, OPR_SET, up->dtr_mask[line]);
		else
			WRITE_SC(port, OPR_CLR, up->dtr_mask[line]);
	}
	if (up->rts_mask[line]) {
		if (mctrl & TIOCM_RTS)
			WRITE_SC(port, OPR_SET, up->rts_mask[line]);
		else
			WRITE_SC(port, OPR_CLR, up->rts_mask[line]);
	}
}
/* port->lock is not held.  */
static int sc26xx_startup(struct uart_port *port)
{
	sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);
	WRITE_SC(port, OPCR, 0);

	/* reset tx and rx */
	WRITE_SC_PORT(port, CR, CR_RES_RX);
	WRITE_SC_PORT(port, CR, CR_RES_TX);

	/* start rx/tx */
	WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX);

	/* enable irqs */
	sc26xx_enable_irq(port, IMR_RXRDY);
	return 0;
}
static int sc26xx_startup(struct uart_port *port)
{
    sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);
    WRITE_SC(port, OPCR, 0);


    WRITE_SC_PORT(port, CR, CR_RES_RX);
    WRITE_SC_PORT(port, CR, CR_RES_TX);


    WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX);


    sc26xx_enable_irq(port, IMR_RXRDY);
    return 0;
}
/* port->lock is not held.  */
static void sc26xx_set_termios(struct uart_port *port, struct ktermios *termios,
			      struct ktermios *old)
{
	unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
	unsigned int quot = uart_get_divisor(port, baud);
	unsigned int iflag, cflag;
	unsigned long flags;
	u8 mr1, mr2, csr;

	spin_lock_irqsave(&port->lock, flags);

	while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc)
		udelay(2);

	WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX);

	iflag = termios->c_iflag;
	cflag = termios->c_cflag;

	port->read_status_mask = SR_OVERRUN;
	if (iflag & INPCK)
		port->read_status_mask |= SR_PARITY | SR_FRAME;
	if (iflag & (BRKINT | PARMRK))
		port->read_status_mask |= SR_BREAK;

	port->ignore_status_mask = 0;
	if (iflag & IGNBRK)
		port->ignore_status_mask |= SR_BREAK;
	if ((cflag & CREAD) == 0)
		port->ignore_status_mask |= SR_BREAK | SR_FRAME |
					    SR_PARITY | SR_OVERRUN;

	switch (cflag & CSIZE) {
	case CS5:
		mr1 = 0x00;
		break;
	case CS6:
		mr1 = 0x01;
		break;
	case CS7:
		mr1 = 0x02;
		break;
	default:
	case CS8:
		mr1 = 0x03;
		break;
	}
	mr2 = 0x07;
	if (cflag & CSTOPB)
		mr2 = 0x0f;
	if (cflag & PARENB) {
		if (cflag & PARODD)
			mr1 |= (1 << 2);
	} else
		mr1 |= (2 << 3);

	switch (baud) {
	case 50:
		csr = 0x00;
		break;
	case 110:
		csr = 0x11;
		break;
	case 134:
		csr = 0x22;
		break;
	case 200:
		csr = 0x33;
		break;
	case 300:
		csr = 0x44;
		break;
	case 600:
		csr = 0x55;
		break;
	case 1200:
		csr = 0x66;
		break;
	case 2400:
		csr = 0x88;
		break;
	case 4800:
		csr = 0x99;
		break;
	default:
	case 9600:
		csr = 0xbb;
		break;
	case 19200:
		csr = 0xcc;
		break;
	}

	WRITE_SC_PORT(port, CR, CR_RES_MR);
	WRITE_SC_PORT(port, MRx, mr1);
	WRITE_SC_PORT(port, MRx, mr2);

	WRITE_SC(port, ACR, 0x80);
	WRITE_SC_PORT(port, CSR, csr);

	/* reset tx and rx */
	WRITE_SC_PORT(port, CR, CR_RES_RX);
	WRITE_SC_PORT(port, CR, CR_RES_TX);

	WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX);
	while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc)
		udelay(2);

	/* XXX */
	uart_update_timeout(port, cflag,
			    (port->uartclk / (16 * quot)));

	spin_unlock_irqrestore(&port->lock, flags);
}