/* We've been assigned a range on the "Low-density serial ports" major */ #define SERIAL_IMX_MAJOR 207 #define MINOR_START 16 #define DEV_NAME "ttymxc"
/* * This determines how often we check the modem status signals * for any change. They generally aren't connected to an IRQ * so we have to poll them. We also check immediately before * filling the TX fifo incase CTS has been dropped.
*/ #define MCTRL_TIMEOUT (250*HZ/1000)
#define DRIVER_NAME "IMX-uart"
#define UART_NR 8
/* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */ enum imx_uart_type {
IMX1_UART,
IMX21_UART,
};
staticconststruct of_device_id imx_uart_dt_ids[] = { /* * For reasons unknown to me, some UART devices (e.g. imx6ul's) are * compatible to fsl,imx6q-uart, but not fsl,imx21-uart, while the * original imx6q's UART is compatible to fsl,imx21-uart. This driver * doesn't make any distinction between these two variants.
*/
{ .compatible = "fsl,imx6q-uart", .data = &imx_uart_imx21_devdata, },
{ .compatible = "fsl,imx1-uart", .data = &imx_uart_imx1_devdata, },
{ .compatible = "fsl,imx21-uart", .data = &imx_uart_imx21_devdata, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_uart_dt_ids);
/* called with port.lock taken and irqs off */ staticvoid imx_uart_soft_reset(struct imx_port *sport)
{ int i = 10;
u32 ucr2, ubir, ubmr, uts;
/* * According to the Reference Manual description of the UART SRST bit: * * "Reset the transmit and receive state machines, * all FIFOs and register USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD * and UTS[6-3]". * * We don't need to restore the old values from USR1, USR2, URXD and * UTXD. UBRC is read only, so only save/restore the other three * registers.
*/
ubir = imx_uart_readl(sport, UBIR);
ubmr = imx_uart_readl(sport, UBMR);
uts = imx_uart_readl(sport, IMX21_UTS);
/* called with port.lock taken and irqs off */ staticvoid imx_uart_disable_loopback_rs485(struct imx_port *sport)
{ unsignedint uts;
/* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */
uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
uts &= ~UTS_LOOP;
imx_uart_writel(sport, uts, imx_uart_uts_reg(sport));
}
/* called with port.lock taken and irqs off */ staticvoid imx_uart_start_rx(struct uart_port *port)
{ struct imx_port *sport = to_imx_port(port); unsignedint ucr1, ucr2;
/* Write UCR2 first as it includes RXEN */
imx_uart_writel(sport, ucr2, UCR2);
imx_uart_writel(sport, ucr1, UCR1);
imx_uart_disable_loopback_rs485(sport);
}
/* called with port.lock taken and irqs off */ staticvoid imx_uart_stop_tx(struct uart_port *port)
{ struct imx_port *sport = to_imx_port(port);
u32 ucr1, ucr4, usr2;
if (sport->tx_state == OFF) return;
/* * We are maybe in the SMP context, so if the DMA TX thread is running * on other cpu, we have to wait for it to finish.
*/ if (sport->dma_is_txing) return;
/* called with port.lock taken and irqs off */ staticvoid imx_uart_stop_rx(struct uart_port *port)
{ /* * Stop RX and enable loopback in order to make sure RS485 bus * is not blocked. Se comment in imx_uart_probe().
*/
imx_uart_stop_rx_with_loopback_ctrl(port, true);
}
/* called with port.lock taken and irqs off */ staticvoid imx_uart_enable_ms(struct uart_port *port)
{ struct imx_port *sport = to_imx_port(port);
/* called with port.lock taken and irqs off */ staticinlinevoid imx_uart_transmit_buffer(struct imx_port *sport)
{ struct tty_port *tport = &sport->port.state->port; unsignedchar c;
if (sport->port.x_char) { /* Send next char */
imx_uart_writel(sport, sport->port.x_char, URTX0);
sport->port.icount.tx++;
sport->port.x_char = 0; return;
}
if (kfifo_is_empty(&tport->xmit_fifo) ||
uart_tx_stopped(&sport->port)) {
imx_uart_stop_tx(&sport->port); return;
}
if (sport->dma_is_enabled) {
u32 ucr1; /* * We've just sent a X-char Ensure the TX DMA is enabled * and the TX IRQ is disabled.
**/
ucr1 = imx_uart_readl(sport, UCR1);
ucr1 &= ~UCR1_TRDYEN; if (sport->dma_is_txing) {
ucr1 |= UCR1_TXDMAEN;
imx_uart_writel(sport, ucr1, UCR1);
} else {
imx_uart_writel(sport, ucr1, UCR1);
imx_uart_dma_tx(sport);
}
/* fire it */
sport->dma_is_txing = 1;
dmaengine_submit(desc);
dma_async_issue_pending(chan); return;
}
/* called with port.lock taken and irqs off */ staticvoid imx_uart_start_tx(struct uart_port *port)
{ struct imx_port *sport = to_imx_port(port); struct tty_port *tport = &sport->port.state->port;
u32 ucr1;
if (!sport->port.x_char && kfifo_is_empty(&tport->xmit_fifo)) return;
/* * We cannot simply do nothing here if sport->tx_state == SEND already * because UCR1_TXMPTYEN might already have been cleared in * imx_uart_stop_tx(), but tx_state is still SEND.
*/
if (port->rs485.flags & SER_RS485_ENABLED) { if (sport->tx_state == OFF) {
u32 ucr2 = imx_uart_readl(sport, UCR2); if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
imx_uart_rts_active(sport, &ucr2); else
imx_uart_rts_inactive(sport, &ucr2);
imx_uart_writel(sport, ucr2, UCR2);
/* * Since we are about to transmit we can not stop RX * with loopback enabled because that will make our * transmitted data being just looped to RX.
*/ if (!(port->rs485.flags & SER_RS485_RX_DURING_TX) &&
!port->rs485_rx_during_tx_gpio)
imx_uart_stop_rx_with_loopback_ctrl(port, false);
sport->tx_state = WAIT_AFTER_RTS;
if (port->rs485.delay_rts_before_send > 0) {
start_hrtimer_ms(&sport->trigger_start_tx,
port->rs485.delay_rts_before_send); return;
}
/* continue without any delay */
}
if (sport->tx_state == WAIT_AFTER_SEND
|| sport->tx_state == WAIT_AFTER_RTS) {
hrtimer_try_to_cancel(&sport->trigger_stop_tx);
/* * Enable transmitter and shifter empty irq only if DMA * is off. In the DMA case this is done in the * tx-callback.
*/ if (!sport->dma_is_enabled) {
u32 ucr4 = imx_uart_readl(sport, UCR4);
ucr4 |= UCR4_TCEN;
imx_uart_writel(sport, ucr4, UCR4);
}
if (sport->dma_is_enabled) { if (sport->port.x_char) { /* We have X-char to send, so enable TX IRQ and
* disable TX DMA to let TX interrupt to send X-char */
ucr1 = imx_uart_readl(sport, UCR1);
ucr1 &= ~UCR1_TXDMAEN;
ucr1 |= UCR1_TRDYEN;
imx_uart_writel(sport, ucr1, UCR1); return;
}
if (!kfifo_is_empty(&tport->xmit_fifo) &&
!uart_tx_stopped(port))
imx_uart_dma_tx(sport); return;
}
}
imx_uart_writel(sport, USR1_RTSD, USR1);
usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS; /* * Update sport->old_status here, so any follow-up calls to * imx_uart_mctrl_check() will be able to recognize that RTS * state changed since last imx_uart_mctrl_check() call. * * In case RTS has been detected as asserted here and later on * deasserted by the time imx_uart_mctrl_check() was called, * imx_uart_mctrl_check() can detect the RTS state change and * trigger uart_handle_cts_change() to unblock the port for * further TX transfers.
*/ if (usr1 & USR1_RTSS)
sport->old_status |= TIOCM_CTS; else
sport->old_status &= ~TIOCM_CTS;
uart_handle_cts_change(&sport->port, usr1);
wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
/* Check if hardware Rx flood is in progress, and issue soft reset to stop it. * This is to be called from Rx ISRs only when some bytes were actually * received. * * A way to reproduce the flood (checked on iMX6SX) is: open iMX UART at 9600 * 8N1, and from external source send 0xf0 char at 115200 8N1. In about 90% of * cases this starts a flood of "receiving" of 0xff characters by the iMX6 UART * that is terminated by any activity on RxD line, or could be stopped by * issuing soft reset to the UART (just stop/start of RX does not help). Note * that what we do here is sending isolated start bit about 2.4 times shorter * than it is to be on UART configured baud rate. * * Called with port.lock taken and irqs off.
*/ staticvoid imx_uart_check_flood(struct imx_port *sport, u32 usr2)
{ /* To detect hardware 0xff flood we monitor RxD line between RX * interrupts to isolate "receiving" of char(s) with no activity * on RxD line, that'd never happen on actual data transfers. * * We use USR2_WAKE bit to check for activity on RxD line, but we have a * race here if we clear USR2_WAKE when receiving of a char is in * progress, so we might get RX interrupt later with USR2_WAKE bit * cleared. Note though that as we don't try to clear USR2_WAKE when we * detected no activity, this race may hide actual activity only once. * * Yet another case where receive interrupt may occur without RxD * activity is expiration of aging timer, so we consider this as well. * * We use 'idle_counter' to ensure that we got at least so many RX * interrupts without any detected activity on RxD line. 2 cases * described plus 1 to be on the safe side gives us a margin of 3, * below. In practice I was not able to produce a false positive to * induce soft reset at regular data transfers even using 1 as the * margin, so 3 is actually very strong. * * We count interrupts, not chars in 'idle-counter' for simplicity.
*/
/* * We have a modem side uart, so the meanings of RTS and CTS are inverted.
*/ /* called with port.lock taken and irqs off */ staticunsignedint imx_uart_get_hwmctrl(struct imx_port *sport)
{ unsignedint tmp = TIOCM_DSR; unsigned usr1 = imx_uart_readl(sport, USR1); unsigned usr2 = imx_uart_readl(sport, USR2);
if (usr1 & USR1_RTSS)
tmp |= TIOCM_CTS;
/* in DCE mode DCDIN is always 0 */ if (!(usr2 & USR2_DCDIN))
tmp |= TIOCM_CAR;
if (sport->dte_mode) if (!(imx_uart_readl(sport, USR2) & USR2_RIIN))
tmp |= TIOCM_RI;
return tmp;
}
/* * Handle any change of modem status signal since we were last called. * * Called with port.lock taken and irqs off.
*/ staticvoid imx_uart_mctrl_check(struct imx_port *sport)
{ unsignedint status, changed;
status = imx_uart_get_hwmctrl(sport);
changed = status ^ sport->old_status;
if (changed == 0) return;
sport->old_status = status;
if (changed & TIOCM_RI && status & TIOCM_RI)
sport->port.icount.rng++; if (changed & TIOCM_DSR)
sport->port.icount.dsr++; if (changed & TIOCM_CAR)
uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); if (changed & TIOCM_CTS)
uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
/* * Even if a condition is true that can trigger an irq only handle it if * the respective irq source is enabled. This prevents some undesired * actions, for example if a character that sits in the RX FIFO and that * should be fetched via DMA is tried to be fetched using PIO. Or the * receiver is currently off and so reading from URXD0 results in an * exception. So just mask the (raw) status bits for disabled irqs.
*/ if ((ucr1 & UCR1_RRDYEN) == 0)
usr1 &= ~USR1_RRDY; if ((ucr2 & UCR2_ATEN) == 0)
usr1 &= ~USR1_AGTIM; if ((ucr1 & UCR1_TRDYEN) == 0)
usr1 &= ~USR1_TRDY; if ((ucr4 & UCR4_TCEN) == 0)
usr2 &= ~USR2_TXDC; if ((ucr3 & UCR3_DTRDEN) == 0)
usr1 &= ~USR1_DTRD; if ((ucr1 & UCR1_RTSDEN) == 0)
usr1 &= ~USR1_RTSD; if ((ucr3 & UCR3_AWAKEN) == 0)
usr1 &= ~USR1_AWAKE; if ((ucr4 & UCR4_OREN) == 0)
usr2 &= ~USR2_ORE;
if (usr1 & (USR1_RRDY | USR1_AGTIM)) {
imx_uart_writel(sport, USR1_AGTIM, USR1);
__imx_uart_rxint(irq, dev_id);
ret = IRQ_HANDLED;
}
if ((usr1 & USR1_TRDY) || (usr2 & USR2_TXDC)) {
imx_uart_transmit_buffer(sport);
ret = IRQ_HANDLED;
}
if (usr1 & USR1_DTRD) {
imx_uart_writel(sport, USR1_DTRD, USR1);
imx_uart_mctrl_check(sport);
ret = IRQ_HANDLED;
}
if (usr1 & USR1_RTSD) {
__imx_uart_rtsint(irq, dev_id);
ret = IRQ_HANDLED;
}
if (usr1 & USR1_AWAKE) {
imx_uart_writel(sport, USR1_AWAKE, USR1);
ret = IRQ_HANDLED;
}
if (usr2 & USR2_ORE) {
sport->port.icount.overrun++;
imx_uart_writel(sport, USR2_ORE, USR2);
ret = IRQ_HANDLED;
}
uart_port_unlock(&sport->port);
return ret;
}
/* * Return TIOCSER_TEMT when transmitter is not busy.
*/ staticunsignedint imx_uart_tx_empty(struct uart_port *port)
{ struct imx_port *sport = to_imx_port(port); unsignedint ret;
ret = (imx_uart_readl(sport, USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0;
/* If the TX DMA is working, return 0. */ if (sport->dma_is_txing)
ret = 0;
return ret;
}
/* called with port.lock taken and irqs off */ staticunsignedint imx_uart_get_mctrl(struct uart_port *port)
{ struct imx_port *sport = to_imx_port(port); unsignedint ret = imx_uart_get_hwmctrl(sport);
mctrl_gpio_get(sport->gpios, &ret);
return ret;
}
/* called with port.lock taken and irqs off */ staticvoid imx_uart_set_mctrl(struct uart_port *port, unsignedint mctrl)
{ struct imx_port *sport = to_imx_port(port);
u32 ucr3, uts;
if (!(port->rs485.flags & SER_RS485_ENABLED)) {
u32 ucr2;
/* * Turn off autoRTS if RTS is lowered and restore autoRTS * setting if RTS is raised.
*/
ucr2 = imx_uart_readl(sport, UCR2);
ucr2 &= ~(UCR2_CTS | UCR2_CTSC); if (mctrl & TIOCM_RTS) {
ucr2 |= UCR2_CTS; /* * UCR2_IRTS is unset if and only if the port is * configured for CRTSCTS, so we use inverted UCR2_IRTS * to get the state to restore to.
*/ if (!(ucr2 & UCR2_IRTS))
ucr2 |= UCR2_CTSC;
}
imx_uart_writel(sport, ucr2, UCR2);
}
/* * There are two kinds of RX DMA interrupts(such as in the MX6Q): * [1] the RX DMA buffer is full. * [2] the aging timer expires * * Condition [2] is triggered when a character has been sitting in the FIFO * for at least 8 byte durations.
*/ staticvoid imx_uart_dma_rx_callback(void *data)
{ struct imx_port *sport = data; struct dma_chan *chan = sport->dma_chan_rx; struct scatterlist *sgl = &sport->rx_sgl; struct tty_port *port = &sport->port.state->port; struct dma_tx_state state; struct circ_buf *rx_ring = &sport->rx_ring; enum dma_status status; unsignedint w_bytes = 0; unsignedint r_bytes; unsignedint bd_size;
status = dmaengine_tx_status(chan, sport->rx_cookie, &state);
if (status == DMA_ERROR) {
uart_port_lock(&sport->port);
imx_uart_clear_rx_errors(sport);
uart_port_unlock(&sport->port); return;
}
/* * The state-residue variable represents the empty space * relative to the entire buffer. Taking this in consideration * the head is always calculated base on the buffer total * length - DMA transaction residue. The UART script from the * SDMA firmware will jump to the next buffer descriptor, * once a DMA transaction if finalized (IMX53 RM - A.4.1.2.4). * Taking this in consideration the tail is always at the * beginning of the buffer descriptor that contains the head.
*/
/* Calculate the head */
rx_ring->head = sg_dma_len(sgl) - state.residue;
if (rx_ring->head <= sg_dma_len(sgl) &&
rx_ring->head > rx_ring->tail) {
/* Move data from tail to head */
r_bytes = rx_ring->head - rx_ring->tail;
/* If we received something, check for 0xff flood */
uart_port_lock(&sport->port);
imx_uart_check_flood(sport, imx_uart_readl(sport, USR2));
uart_port_unlock(&sport->port);
if (!(sport->port.ignore_status_mask & URXD_DUMMY_READ)) {
/* CPU claims ownership of RX DMA buffer */
dma_sync_sg_for_cpu(sport->port.dev, sgl, 1,
DMA_FROM_DEVICE);
if (!desc) {
dma_unmap_sg(dev, sgl, 1, DMA_FROM_DEVICE);
dev_err(dev, "We cannot prepare for the RX slave dma!\n"); return -EINVAL;
}
desc->callback = imx_uart_dma_rx_callback;
desc->callback_param = sport;
dev_dbg(dev, "RX: prepare for the DMA.\n");
sport->dma_is_rxing = 1;
sport->rx_cookie = dmaengine_submit(desc);
dma_async_issue_pending(chan); return 0;
}
/* called with port.lock taken and irqs off */ staticvoid imx_uart_clear_rx_errors(struct imx_port *sport)
{ struct tty_port *port = &sport->port.state->port;
u32 usr1, usr2;
/* * We have to ensure the tx state machine ends up in OFF. This * is especially important for rs485 where we must not leave * the RTS signal high, blocking the bus indefinitely. * * All interrupts are now disabled, so imx_uart_stop_tx() will * no longer be called from imx_uart_transmit_buffer(). It may * still be called via the hrtimers, and if those are in play, * we have to honour the delays.
*/ if (sport->tx_state == WAIT_AFTER_RTS || sport->tx_state == SEND)
imx_uart_stop_tx(port);
/* * In many cases (rs232 mode, or if tx_state was * WAIT_AFTER_RTS, or if tx_state was SEND and there is no * delay_rts_after_send), this will have moved directly to * OFF. In rs485 mode, tx_state might already have been * WAIT_AFTER_SEND and the hrtimer thus already started, or * the above imx_uart_stop_tx() call could have started it. In * those cases, we have to wait for the hrtimer to fire and * complete the transition to OFF.
*/
loops = port->rs485.flags & SER_RS485_ENABLED ?
port->rs485.delay_rts_after_send : 0; while (sport->tx_state != OFF && loops--) {
uart_port_unlock_irqrestore(&sport->port, flags);
msleep(1);
uart_port_lock_irqsave(&sport->port, &flags);
}
if (sport->tx_state != OFF) {
dev_warn(sport->port.dev, "unexpected tx_state %d\n",
sport->tx_state); /* * This machine may be busted, but ensure the RTS * signal is inactive in order not to block other * devices.
*/ if (port->rs485.flags & SER_RS485_ENABLED) {
ucr2 = imx_uart_readl(sport, UCR2); if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
imx_uart_rts_active(sport, &ucr2); else
imx_uart_rts_inactive(sport, &ucr2);
imx_uart_writel(sport, ucr2, UCR2);
}
sport->tx_state = OFF;
}
/* called with port.lock taken and irqs off */ staticvoid imx_uart_flush_buffer(struct uart_port *port)
{ struct imx_port *sport = to_imx_port(port); struct scatterlist *sgl = &sport->tx_sgl[0];
if (!sport->dma_chan_tx) return;
sport->tx_bytes = 0;
dmaengine_terminate_all(sport->dma_chan_tx); if (sport->dma_is_txing) {
u32 ucr1;
/* * We only support CS7 and CS8.
*/ while ((termios->c_cflag & CSIZE) != CS7 &&
(termios->c_cflag & CSIZE) != CS8) {
termios->c_cflag &= ~CSIZE;
termios->c_cflag |= old_csize;
old_csize = CS8;
}
timer_delete_sync(&sport->timer);
/* * Ask the core to calculate the divisor for us.
*/
baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
quot = uart_get_divisor(port, baud);
uart_port_lock_irqsave(&sport->port, &flags);
/* * Read current UCR2 and save it for future use, then clear all the bits * except those we will or may need to preserve.
*/
old_ucr2 = imx_uart_readl(sport, UCR2);
ucr2 = old_ucr2 & (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN | UCR2_CTS);
if (!sport->have_rtscts)
termios->c_cflag &= ~CRTSCTS;
if (port->rs485.flags & SER_RS485_ENABLED) { /* * RTS is mandatory for rs485 operation, so keep * it under manual control and keep transmitter * disabled.
*/ if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
imx_uart_rts_active(sport, &ucr2); else
imx_uart_rts_inactive(sport, &ucr2);
} elseif (termios->c_cflag & CRTSCTS) { /* * Only let receiver control RTS output if we were not requested * to have RTS inactive (which then should take precedence).
*/ if (ucr2 & UCR2_CTS)
ucr2 |= UCR2_CTSC;
}
if (termios->c_cflag & CRTSCTS)
ucr2 &= ~UCR2_IRTS; if (termios->c_cflag & CSTOPB)
ucr2 |= UCR2_STPB; if (termios->c_cflag & PARENB) {
ucr2 |= UCR2_PREN; if (termios->c_cflag & PARODD)
ucr2 |= UCR2_PROE;
}
/* * Two registers below should always be written both and in this * particular order. One consequence is that we need to check if any of * them changes and then update both. We do need the check for change * as even writing the same values seem to "restart" * transmission/receiving logic in the hardware, that leads to data * breakage even when rate doesn't in fact change. E.g., user switches * RTS/CTS handshake and suddenly gets broken bytes.
*/
old_ubir = imx_uart_readl(sport, UBIR);
old_ubmr = imx_uart_readl(sport, UBMR); if (old_ubir != num || old_ubmr != denom) {
imx_uart_writel(sport, num, UBIR);
imx_uart_writel(sport, denom, UBMR);
}
if (!imx_uart_is_imx1(sport))
imx_uart_writel(sport, sport->port.uartclk / div / 1000,
IMX21_ONEMS);
imx_uart_writel(sport, ucr2, UCR2);
if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
imx_uart_enable_ms(&sport->port);
/* * Configure/autoconfigure the port.
*/ staticvoid imx_uart_config_port(struct uart_port *port, int flags)
{ if (flags & UART_CONFIG_TYPE)
port->type = PORT_IMX;
}
/* * Verify the new serial_struct (for TIOCSSERIAL). * The only change we allow are to the flags and type, and * even then only between PORT_IMX and PORT_UNKNOWN
*/ staticint
imx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
{ int ret = 0;
if (ser->type != PORT_UNKNOWN && ser->type != PORT_IMX)
ret = -EINVAL; if (port->irq != ser->irq)
ret = -EINVAL; if (ser->io_type != UPIO_MEM)
ret = -EINVAL; if (port->uartclk / 16 != ser->baud_base)
ret = -EINVAL; if (port->mapbase != (unsignedlong)ser->iomem_base)
ret = -EINVAL; if (port->iobase != ser->port)
ret = -EINVAL; if (ser->hub6 != 0)
ret = -EINVAL; return ret;
}
/* * Be careful about the order of enabling bits here. First enable the * receiver (UARTEN + RXEN) and only then the corresponding irqs. * This prevents that a character that already sits in the RX fifo is * triggering an irq but the try to fetch it from there results in an * exception because UARTEN or RXEN is still off.
*/
ucr1 = imx_uart_readl(sport, UCR1);
ucr2 = imx_uart_readl(sport, UCR2);
if (imx_uart_is_imx1(sport))
ucr1 |= IMX1_UCR1_UARTCLKEN;
/* drain */ do {
status = imx_uart_readl(sport, USR1);
} while (~status & USR1_TRDY);
/* write */
imx_uart_writel(sport, c, URTX0);
/* flush */ do {
status = imx_uart_readl(sport, USR2);
} while (~status & USR2_TXDC);
} #endif
/* called with port.lock taken and irqs off or from .probe without locking */ staticint imx_uart_rs485_config(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485conf)
{ struct imx_port *sport = to_imx_port(port);
u32 ucr2, ufcr;
if (rs485conf->flags & SER_RS485_ENABLED) { /* Enable receiver if low-active RTS signal is requested */ if (sport->have_rtscts && !sport->have_rtsgpio &&
!(rs485conf->flags & SER_RS485_RTS_ON_SEND))
rs485conf->flags |= SER_RS485_RX_DURING_TX;
/* Make sure Rx is enabled in case Tx is active with Rx disabled */ if (!(rs485conf->flags & SER_RS485_ENABLED) ||
rs485conf->flags & SER_RS485_RX_DURING_TX) { /* If the receiver trigger is 0, set it to a default value */
ufcr = imx_uart_readl(sport, UFCR); if ((ufcr & UFCR_RXTL_MASK) == 0)
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
imx_uart_start_rx(port);
}
if (nbcon_exit_unsafe(wctxt)) { int len = READ_ONCE(wctxt->len); int i;
/* * Write out the message. Toggle unsafe for each byte in order * to give another (higher priority) context the opportunity * for a friendly takeover. If such a takeover occurs, this * context must reacquire ownership in order to perform final * actions (such as re-enabling the interrupts). * * IMPORTANT: wctxt->outbuf and wctxt->len are no longer valid * after a reacquire so writing the message must be * aborted.
*/ for (i = 0; i < len; i++) { if (!nbcon_enter_unsafe(wctxt)) break;
uart_console_write(port, wctxt->outbuf + i, 1,
imx_uart_console_putchar);
if (!nbcon_exit_unsafe(wctxt)) break;
}
}
while (!nbcon_enter_unsafe(wctxt))
nbcon_reacquire_nobuf(wctxt);
/* * Finally, wait for transmitter to become empty * and restore UCR1/2/3
*/
read_poll_timeout(imx_uart_readl, usr2, usr2 & USR2_TXDC,
0, USEC_PER_SEC, false, sport, USR2);
imx_uart_ucrs_restore(sport, &old_ucr);
nbcon_exit_unsafe(wctxt);
}
/* * If the port was already initialised (eg, by a boot loader), * try to determine the current setup.
*/ staticvoid
imx_uart_console_get_options(struct imx_port *sport, int *baud, int *parity, int *bits)
{
if (imx_uart_readl(sport, UCR1) & UCR1_UARTEN) { /* ok, the port was enabled */ unsignedint ucr2, ubir, ubmr, uartclk; unsignedint baud_raw; unsignedint ucfr_rfdiv;
ucr2 = imx_uart_readl(sport, UCR2);
*parity = 'n'; if (ucr2 & UCR2_PREN) { if (ucr2 & UCR2_PROE)
*parity = 'o'; else
*parity = 'e';
}
{ /* * The next code provides exact computation of * baud_raw = round(((uartclk/16) * (ubir + 1)) / (ubmr + 1)) * without need of float support or long long division, * which would be required to prevent 32bit arithmetic overflow
*/ unsignedint mul = ubir + 1; unsignedint div = 16 * (ubmr + 1); unsignedint rem = uartclk % div;
if (*baud != baud_raw)
dev_info(sport->port.dev, "Console IMX rounded baud rate from %d to %d\n",
baud_raw, *baud);
}
}
staticint
imx_uart_console_setup(struct console *co, char *options)
{ struct imx_port *sport; int baud = 9600; int bits = 8; int parity = 'n'; int flow = 'n'; int retval;
/* * Check whether an invalid uart number has been specified, and * if so, search for the first available port that does have * console support.
*/ if (co->index == -1 || co->index >= ARRAY_SIZE(imx_uart_ports))
co->index = 0;
sport = imx_uart_ports[co->index]; if (sport == NULL) return -ENODEV;
/* For setting the registers, we only need to enable the ipg clock. */
retval = clk_prepare_enable(sport->clk_ipg); if (retval) goto error_console;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.