示例#1
0
文件: sc26xx.c 项目: maraz/linux-2.6
/* port->lock is not held.  */
static void sc26xx_shutdown(struct uart_port *port)
{
	/* disable interrupst */
	sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);

	/* stop tx/rx */
	WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX);
}
static void sc26xx_shutdown(struct uart_port *port)
{

    sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);


    WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX);
}
/* port->lock held by caller.  */
static void sc26xx_start_tx(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;

	while (!uart_circ_empty(xmit)) {
		if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) {
			sc26xx_enable_irq(port, IMR_TXRDY);
			break;
		}
		WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}
}
static void sc26xx_console_putchar(struct uart_port *port, char c)
{
	unsigned long flags;
	int limit = 1000000;

	spin_lock_irqsave(&port->lock, flags);

	while (limit-- > 0) {
		if (READ_SC_PORT(port, SR) & SR_TXRDY) {
			WRITE_SC_PORT(port, THR, c);
			break;
		}
		udelay(2);
	}

	spin_unlock_irqrestore(&port->lock, flags);
}
static void transmit_chars(struct uart_port *port)
{
	struct circ_buf *xmit;

	if (!port->state)
		return;

	xmit = &port->state->xmit;
	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		sc26xx_disable_irq(port, IMR_TXRDY);
		return;
	}
	while (!uart_circ_empty(xmit)) {
		if (!(READ_SC_PORT(port, SR) & SR_TXRDY))
			break;

		WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}
	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);
}
/* 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);
}