in serial/stm32-usart.c [956:1162]
static void stm32_usart_set_termios(struct uart_port *port,
struct ktermios *termios,
struct ktermios *old)
{
struct stm32_port *stm32_port = to_stm32_port(port);
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
struct serial_rs485 *rs485conf = &port->rs485;
unsigned int baud, bits;
u32 usartdiv, mantissa, fraction, oversampling;
tcflag_t cflag = termios->c_cflag;
u32 cr1, cr2, cr3, isr;
unsigned long flags;
int ret;
if (!stm32_port->hw_flow_control)
cflag &= ~CRTSCTS;
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8);
spin_lock_irqsave(&port->lock, flags);
ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
isr,
(isr & USART_SR_TC),
10, 100000);
/* Send the TC error message only when ISR_TC is not set. */
if (ret)
dev_err(port->dev, "Transmission is not complete\n");
/* Stop serial port and reset value */
writel_relaxed(0, port->membase + ofs->cr1);
/* flush RX & TX FIFO */
if (ofs->rqr != UNDEF_REG)
writel_relaxed(USART_RQR_TXFRQ | USART_RQR_RXFRQ,
port->membase + ofs->rqr);
cr1 = USART_CR1_TE | USART_CR1_RE;
if (stm32_port->fifoen)
cr1 |= USART_CR1_FIFOEN;
cr2 = stm32_port->swap ? USART_CR2_SWAP : 0;
/* Tx and RX FIFO configuration */
cr3 = readl_relaxed(port->membase + ofs->cr3);
cr3 &= USART_CR3_TXFTIE | USART_CR3_RXFTIE;
if (stm32_port->fifoen) {
if (stm32_port->txftcfg >= 0)
cr3 |= stm32_port->txftcfg << USART_CR3_TXFTCFG_SHIFT;
if (stm32_port->rxftcfg >= 0)
cr3 |= stm32_port->rxftcfg << USART_CR3_RXFTCFG_SHIFT;
}
if (cflag & CSTOPB)
cr2 |= USART_CR2_STOP_2B;
bits = tty_get_char_size(cflag);
stm32_port->rdr_mask = (BIT(bits) - 1);
if (cflag & PARENB) {
bits++;
cr1 |= USART_CR1_PCE;
}
/*
* Word length configuration:
* CS8 + parity, 9 bits word aka [M1:M0] = 0b01
* CS7 or (CS6 + parity), 7 bits word aka [M1:M0] = 0b10
* CS8 or (CS7 + parity), 8 bits word aka [M1:M0] = 0b00
* M0 and M1 already cleared by cr1 initialization.
*/
if (bits == 9)
cr1 |= USART_CR1_M0;
else if ((bits == 7) && cfg->has_7bits_data)
cr1 |= USART_CR1_M1;
else if (bits != 8)
dev_dbg(port->dev, "Unsupported data bits config: %u bits\n"
, bits);
if (ofs->rtor != UNDEF_REG && (stm32_port->rx_ch ||
(stm32_port->fifoen &&
stm32_port->rxftcfg >= 0))) {
if (cflag & CSTOPB)
bits = bits + 3; /* 1 start bit + 2 stop bits */
else
bits = bits + 2; /* 1 start bit + 1 stop bit */
/* RX timeout irq to occur after last stop bit + bits */
stm32_port->cr1_irq = USART_CR1_RTOIE;
writel_relaxed(bits, port->membase + ofs->rtor);
cr2 |= USART_CR2_RTOEN;
/*
* Enable fifo threshold irq in two cases, either when there is no DMA, or when
* wake up over usart, from low power until the DMA gets re-enabled by resume.
*/
stm32_port->cr3_irq = USART_CR3_RXFTIE;
}
cr1 |= stm32_port->cr1_irq;
cr3 |= stm32_port->cr3_irq;
if (cflag & PARODD)
cr1 |= USART_CR1_PS;
port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
if (cflag & CRTSCTS) {
port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
cr3 |= USART_CR3_CTSE | USART_CR3_RTSE;
}
usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
/*
* The USART supports 16 or 8 times oversampling.
* By default we prefer 16 times oversampling, so that the receiver
* has a better tolerance to clock deviations.
* 8 times oversampling is only used to achieve higher speeds.
*/
if (usartdiv < 16) {
oversampling = 8;
cr1 |= USART_CR1_OVER8;
stm32_usart_set_bits(port, ofs->cr1, USART_CR1_OVER8);
} else {
oversampling = 16;
cr1 &= ~USART_CR1_OVER8;
stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_OVER8);
}
mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT;
fraction = usartdiv % oversampling;
writel_relaxed(mantissa | fraction, port->membase + ofs->brr);
uart_update_timeout(port, cflag, baud);
port->read_status_mask = USART_SR_ORE;
if (termios->c_iflag & INPCK)
port->read_status_mask |= USART_SR_PE | USART_SR_FE;
if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
port->read_status_mask |= USART_SR_FE;
/* Characters to ignore */
port->ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
port->ignore_status_mask = USART_SR_PE | USART_SR_FE;
if (termios->c_iflag & IGNBRK) {
port->ignore_status_mask |= USART_SR_FE;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
port->ignore_status_mask |= USART_SR_ORE;
}
/* Ignore all characters if CREAD is not set */
if ((termios->c_cflag & CREAD) == 0)
port->ignore_status_mask |= USART_SR_DUMMY_RX;
if (stm32_port->rx_ch) {
/*
* Setup DMA to collect only valid data and enable error irqs.
* This also enables break reception when using DMA.
*/
cr1 |= USART_CR1_PEIE;
cr3 |= USART_CR3_EIE;
cr3 |= USART_CR3_DMAR;
cr3 |= USART_CR3_DDRE;
}
if (rs485conf->flags & SER_RS485_ENABLED) {
stm32_usart_config_reg_rs485(&cr1, &cr3,
rs485conf->delay_rts_before_send,
rs485conf->delay_rts_after_send,
baud);
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
cr3 &= ~USART_CR3_DEP;
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
} else {
cr3 |= USART_CR3_DEP;
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
}
} else {
cr3 &= ~(USART_CR3_DEM | USART_CR3_DEP);
cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
}
/* Configure wake up from low power on start bit detection */
if (stm32_port->wakeup_src) {
cr3 &= ~USART_CR3_WUS_MASK;
cr3 |= USART_CR3_WUS_START_BIT;
}
writel_relaxed(cr3, port->membase + ofs->cr3);
writel_relaxed(cr2, port->membase + ofs->cr2);
writel_relaxed(cr1, port->membase + ofs->cr1);
stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
spin_unlock_irqrestore(&port->lock, flags);
/* Handle modem control interrupts */
if (UART_ENABLE_MS(port, termios->c_cflag))
stm32_usart_enable_ms(port);
else
stm32_usart_disable_ms(port);
}