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); }
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); } }
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; }
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); }
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; }
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); }
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; }