Пример #1
0
static bool receive_chars(struct uart_port *port)
{
	struct tty_port *tport = NULL;
	int limit = 10000;
	unsigned char ch;
	char flag;
	u8 status;

	/* FIXME what is this trying to achieve? */
	if (port->state != NULL)		/* Unopened serial console */
		tport = &port->state->port;

	while (limit-- > 0) {
		status = READ_SC_PORT(port, SR);
		if (!(status & SR_RXRDY))
			break;
		ch = READ_SC_PORT(port, RHR);

		flag = TTY_NORMAL;
		port->icount.rx++;

		if (unlikely(status & (SR_BREAK | SR_FRAME |
				       SR_PARITY | SR_OVERRUN))) {
			if (status & SR_BREAK) {
				status &= ~(SR_PARITY | SR_FRAME);
				port->icount.brk++;
				if (uart_handle_break(port))
					continue;
			} else if (status & SR_PARITY)
				port->icount.parity++;
			else if (status & SR_FRAME)
				port->icount.frame++;
			if (status & SR_OVERRUN)
				port->icount.overrun++;

			status &= port->read_status_mask;
			if (status & SR_BREAK)
				flag = TTY_BREAK;
			else if (status & SR_PARITY)
				flag = TTY_PARITY;
			else if (status & SR_FRAME)
				flag = TTY_FRAME;
		}

		if (uart_handle_sysrq_char(port, ch))
			continue;

		if (status & port->ignore_status_mask)
			continue;

		tty_insert_flip_char(tport, ch, flag);
	}
	return !!tport;
}
Пример #2
0
static struct tty_struct *receive_chars(struct uart_port *port)
{
    struct tty_struct *tty = NULL;
    int limit = 10000;
    unsigned char ch;
    char flag;
    u8 status;

    if (port->state != NULL)
        tty = port->state->port.tty;

    while (limit-- > 0) {
        status = READ_SC_PORT(port, SR);
        if (!(status & SR_RXRDY))
            break;
        ch = READ_SC_PORT(port, RHR);

        flag = TTY_NORMAL;
        port->icount.rx++;

        if (unlikely(status & (SR_BREAK | SR_FRAME |
                               SR_PARITY | SR_OVERRUN))) {
            if (status & SR_BREAK) {
                status &= ~(SR_PARITY | SR_FRAME);
                port->icount.brk++;
                if (uart_handle_break(port))
                    continue;
            } else if (status & SR_PARITY)
                port->icount.parity++;
            else if (status & SR_FRAME)
                port->icount.frame++;
            if (status & SR_OVERRUN)
                port->icount.overrun++;

            status &= port->read_status_mask;
            if (status & SR_BREAK)
                flag = TTY_BREAK;
            else if (status & SR_PARITY)
                flag = TTY_PARITY;
            else if (status & SR_FRAME)
                flag = TTY_FRAME;
        }

        if (uart_handle_sysrq_char(port, ch))
            continue;

        if (status & port->ignore_status_mask)
            continue;

        tty_insert_flip_char(tty, ch, flag);
    }
    return tty;
}
Пример #3
0
/* 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++;
	}
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
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);
}
Пример #7
0
/* port->lock is not held.  */
static unsigned int sc26xx_tx_empty(struct uart_port *port)
{
	return (READ_SC_PORT(port, SR) & SR_TXRDY) ? TIOCSER_TEMT : 0;
}