Пример #1
0
static void efm32_uart_tx_chars(struct efm32_uart_port *efm_port)
{
	struct uart_port *port = &efm_port->port;
	struct circ_buf *xmit = &port->state->xmit;

	while (efm32_uart_read32(efm_port, UARTn_STATUS) &
			UARTn_STATUS_TXBL) {
		if (port->x_char) {
			port->icount.tx++;
			efm32_uart_write32(efm_port, port->x_char,
					UARTn_TXDATA);
			port->x_char = 0;
			continue;
		}
		if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) {
			port->icount.tx++;
			efm32_uart_write32(efm_port, xmit->buf[xmit->tail],
					UARTn_TXDATA);
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		} else
			break;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (!port->x_char && uart_circ_empty(xmit) &&
			efm32_uart_read32(efm_port, UARTn_STATUS) &
				UARTn_STATUS_TXC)
		efm32_uart_stop_tx(port);
}
Пример #2
0
static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port,
		struct tty_struct *tty)
{
	struct uart_port *port = &efm_port->port;

	while (efm32_uart_read32(efm_port, UARTn_STATUS) &
			UARTn_STATUS_RXDATAV) {
		u32 rxdata = efm32_uart_read32(efm_port, UARTn_RXDATAX);
		int flag = 0;

		/*
		 * This is a reserved bit and I only saw it read as 0. But to be
		 * sure not to be confused too much by new devices adhere to the
		 * warning in the reference manual that reserverd bits might
		 * read as 1 in the future.
		 */
		rxdata &= ~SW_UARTn_RXDATAX_BERR;

		port->icount.rx++;

		if ((rxdata & UARTn_RXDATAX_FERR) &&
				!(rxdata & UARTn_RXDATAX_RXDATA__MASK)) {
			rxdata |= SW_UARTn_RXDATAX_BERR;
			port->icount.brk++;
			if (uart_handle_break(port))
				continue;
		} else if (rxdata & UARTn_RXDATAX_PERR)
			port->icount.parity++;
		else if (rxdata & UARTn_RXDATAX_FERR)
			port->icount.frame++;

		rxdata &= port->read_status_mask;

		if (rxdata & SW_UARTn_RXDATAX_BERR)
			flag = TTY_BREAK;
		else if (rxdata & UARTn_RXDATAX_PERR)
			flag = TTY_PARITY;
		else if (rxdata & UARTn_RXDATAX_FERR)
			flag = TTY_FRAME;
		else if (uart_handle_sysrq_char(port,
					rxdata & UARTn_RXDATAX_RXDATA__MASK))
			continue;

		if (tty && (rxdata & port->ignore_status_mask) == 0)
			tty_insert_flip_char(tty,
					rxdata & UARTn_RXDATAX_RXDATA__MASK, flag);
	}
}
Пример #3
0
static irqreturn_t efm32_uart_rxirq(int irq, void *data)
{
	struct efm32_uart_port *efm_port = data;
	u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF);
	int handled = IRQ_NONE;
	struct uart_port *port = &efm_port->port;
	struct tty_port *tport = &port->state->port;

	spin_lock(&port->lock);

	if (irqflag & UARTn_IF_RXDATAV) {
		efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC);
		efm32_uart_rx_chars(efm_port);

		handled = IRQ_HANDLED;
	}

	if (irqflag & UARTn_IF_RXOF) {
		efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC);
		port->icount.overrun++;
		tty_insert_flip_char(tport, 0, TTY_OVERRUN);

		handled = IRQ_HANDLED;
	}

	spin_unlock(&port->lock);

	tty_flip_buffer_push(tport);

	return handled;
}
Пример #4
0
static void efm32_uart_stop_tx(struct uart_port *port)
{
	struct efm32_uart_port *efm_port = to_efm_port(port);
	u32 ien = efm32_uart_read32(efm_port,  UARTn_IEN);

	efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD);
	ien &= ~(UARTn_IF_TXC | UARTn_IF_TXBL);
	efm32_uart_write32(efm_port, ien, UARTn_IEN);
}
Пример #5
0
static unsigned int efm32_uart_tx_empty(struct uart_port *port)
{
	struct efm32_uart_port *efm_port = to_efm_port(port);
	u32 status = efm32_uart_read32(efm_port, UARTn_STATUS);

	if (status & UARTn_STATUS_TXC)
		return TIOCSER_TEMT;
	else
		return 0;
}
Пример #6
0
static void efm32_uart_start_tx(struct uart_port *port)
{
	struct efm32_uart_port *efm_port = to_efm_port(port);
	u32 ien;

	efm32_uart_write32(efm_port,
			UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IFC);
	ien = efm32_uart_read32(efm_port, UARTn_IEN);
	efm32_uart_write32(efm_port,
			ien | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IEN);
	efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD);

	efm32_uart_tx_chars(efm_port);
}
Пример #7
0
static irqreturn_t efm32_uart_txirq(int irq, void *data)
{
	struct efm32_uart_port *efm_port = data;
	u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF);

	/* TXBL doesn't need to be cleared */
	if (irqflag & UARTn_IF_TXC)
		efm32_uart_write32(efm_port, UARTn_IF_TXC, UARTn_IFC);

	if (irqflag & (UARTn_IF_TXC | UARTn_IF_TXBL)) {
		efm32_uart_tx_chars(efm_port);
		return IRQ_HANDLED;
	} else
		return IRQ_NONE;
}