xref: /openbmc/linux/drivers/tty/serial/stm32-usart.c (revision 33bb2f6ac3088936b7aad3cab6f439f91af0223c)
1e3b3d0f5SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
248a6092fSMaxime Coquelin /*
348a6092fSMaxime Coquelin  * Copyright (C) Maxime Coquelin 2015
43e5fcbacSBich HEMON  * Copyright (C) STMicroelectronics SA 2017
5ada8618fSAlexandre TORGUE  * Authors:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
68ebd9665SErwan Le Ray  *	     Gerald Baeza <gerald.baeza@foss.st.com>
78ebd9665SErwan Le Ray  *	     Erwan Le Ray <erwan.leray@foss.st.com>
848a6092fSMaxime Coquelin  *
948a6092fSMaxime Coquelin  * Inspired by st-asc.c from STMicroelectronics (c)
1048a6092fSMaxime Coquelin  */
1148a6092fSMaxime Coquelin 
1234891872SAlexandre TORGUE #include <linux/clk.h>
1348a6092fSMaxime Coquelin #include <linux/console.h>
1448a6092fSMaxime Coquelin #include <linux/delay.h>
1534891872SAlexandre TORGUE #include <linux/dma-direction.h>
1634891872SAlexandre TORGUE #include <linux/dmaengine.h>
1734891872SAlexandre TORGUE #include <linux/dma-mapping.h>
1834891872SAlexandre TORGUE #include <linux/io.h>
1934891872SAlexandre TORGUE #include <linux/iopoll.h>
2034891872SAlexandre TORGUE #include <linux/irq.h>
2134891872SAlexandre TORGUE #include <linux/module.h>
2248a6092fSMaxime Coquelin #include <linux/of.h>
2348a6092fSMaxime Coquelin #include <linux/of_platform.h>
2494616d9aSErwan Le Ray #include <linux/pinctrl/consumer.h>
2534891872SAlexandre TORGUE #include <linux/platform_device.h>
2634891872SAlexandre TORGUE #include <linux/pm_runtime.h>
27270e5a74SFabrice Gasnier #include <linux/pm_wakeirq.h>
2848a6092fSMaxime Coquelin #include <linux/serial_core.h>
2934891872SAlexandre TORGUE #include <linux/serial.h>
3034891872SAlexandre TORGUE #include <linux/spinlock.h>
3134891872SAlexandre TORGUE #include <linux/sysrq.h>
3234891872SAlexandre TORGUE #include <linux/tty_flip.h>
3334891872SAlexandre TORGUE #include <linux/tty.h>
3448a6092fSMaxime Coquelin 
356cf61b9bSManivannan Sadhasivam #include "serial_mctrl_gpio.h"
36bc5a0b55SAlexandre TORGUE #include "stm32-usart.h"
3748a6092fSMaxime Coquelin 
3856f9a76cSErwan Le Ray static void stm32_usart_stop_tx(struct uart_port *port);
3956f9a76cSErwan Le Ray static void stm32_usart_transmit_chars(struct uart_port *port);
4048a6092fSMaxime Coquelin 
4148a6092fSMaxime Coquelin static inline struct stm32_port *to_stm32_port(struct uart_port *port)
4248a6092fSMaxime Coquelin {
4348a6092fSMaxime Coquelin 	return container_of(port, struct stm32_port, port);
4448a6092fSMaxime Coquelin }
4548a6092fSMaxime Coquelin 
4656f9a76cSErwan Le Ray static void stm32_usart_set_bits(struct uart_port *port, u32 reg, u32 bits)
4748a6092fSMaxime Coquelin {
4848a6092fSMaxime Coquelin 	u32 val;
4948a6092fSMaxime Coquelin 
5048a6092fSMaxime Coquelin 	val = readl_relaxed(port->membase + reg);
5148a6092fSMaxime Coquelin 	val |= bits;
5248a6092fSMaxime Coquelin 	writel_relaxed(val, port->membase + reg);
5348a6092fSMaxime Coquelin }
5448a6092fSMaxime Coquelin 
5556f9a76cSErwan Le Ray static void stm32_usart_clr_bits(struct uart_port *port, u32 reg, u32 bits)
5648a6092fSMaxime Coquelin {
5748a6092fSMaxime Coquelin 	u32 val;
5848a6092fSMaxime Coquelin 
5948a6092fSMaxime Coquelin 	val = readl_relaxed(port->membase + reg);
6048a6092fSMaxime Coquelin 	val &= ~bits;
6148a6092fSMaxime Coquelin 	writel_relaxed(val, port->membase + reg);
6248a6092fSMaxime Coquelin }
6348a6092fSMaxime Coquelin 
6456f9a76cSErwan Le Ray static void stm32_usart_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE,
651bcda09dSBich HEMON 					 u32 delay_DDE, u32 baud)
661bcda09dSBich HEMON {
671bcda09dSBich HEMON 	u32 rs485_deat_dedt;
681bcda09dSBich HEMON 	u32 rs485_deat_dedt_max = (USART_CR1_DEAT_MASK >> USART_CR1_DEAT_SHIFT);
691bcda09dSBich HEMON 	bool over8;
701bcda09dSBich HEMON 
711bcda09dSBich HEMON 	*cr3 |= USART_CR3_DEM;
721bcda09dSBich HEMON 	over8 = *cr1 & USART_CR1_OVER8;
731bcda09dSBich HEMON 
741bcda09dSBich HEMON 	if (over8)
751bcda09dSBich HEMON 		rs485_deat_dedt = delay_ADE * baud * 8;
761bcda09dSBich HEMON 	else
771bcda09dSBich HEMON 		rs485_deat_dedt = delay_ADE * baud * 16;
781bcda09dSBich HEMON 
791bcda09dSBich HEMON 	rs485_deat_dedt = DIV_ROUND_CLOSEST(rs485_deat_dedt, 1000);
801bcda09dSBich HEMON 	rs485_deat_dedt = rs485_deat_dedt > rs485_deat_dedt_max ?
811bcda09dSBich HEMON 			  rs485_deat_dedt_max : rs485_deat_dedt;
821bcda09dSBich HEMON 	rs485_deat_dedt = (rs485_deat_dedt << USART_CR1_DEAT_SHIFT) &
831bcda09dSBich HEMON 			   USART_CR1_DEAT_MASK;
841bcda09dSBich HEMON 	*cr1 |= rs485_deat_dedt;
851bcda09dSBich HEMON 
861bcda09dSBich HEMON 	if (over8)
871bcda09dSBich HEMON 		rs485_deat_dedt = delay_DDE * baud * 8;
881bcda09dSBich HEMON 	else
891bcda09dSBich HEMON 		rs485_deat_dedt = delay_DDE * baud * 16;
901bcda09dSBich HEMON 
911bcda09dSBich HEMON 	rs485_deat_dedt = DIV_ROUND_CLOSEST(rs485_deat_dedt, 1000);
921bcda09dSBich HEMON 	rs485_deat_dedt = rs485_deat_dedt > rs485_deat_dedt_max ?
931bcda09dSBich HEMON 			  rs485_deat_dedt_max : rs485_deat_dedt;
941bcda09dSBich HEMON 	rs485_deat_dedt = (rs485_deat_dedt << USART_CR1_DEDT_SHIFT) &
951bcda09dSBich HEMON 			   USART_CR1_DEDT_MASK;
961bcda09dSBich HEMON 	*cr1 |= rs485_deat_dedt;
971bcda09dSBich HEMON }
981bcda09dSBich HEMON 
9956f9a76cSErwan Le Ray static int stm32_usart_config_rs485(struct uart_port *port,
1001bcda09dSBich HEMON 				    struct serial_rs485 *rs485conf)
1011bcda09dSBich HEMON {
1021bcda09dSBich HEMON 	struct stm32_port *stm32_port = to_stm32_port(port);
103d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
104d825f0beSStephen Boyd 	const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
1051bcda09dSBich HEMON 	u32 usartdiv, baud, cr1, cr3;
1061bcda09dSBich HEMON 	bool over8;
1071bcda09dSBich HEMON 
10856f9a76cSErwan Le Ray 	stm32_usart_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
1091bcda09dSBich HEMON 
1101bcda09dSBich HEMON 	port->rs485 = *rs485conf;
1111bcda09dSBich HEMON 
1121bcda09dSBich HEMON 	rs485conf->flags |= SER_RS485_RX_DURING_TX;
1131bcda09dSBich HEMON 
1141bcda09dSBich HEMON 	if (rs485conf->flags & SER_RS485_ENABLED) {
1151bcda09dSBich HEMON 		cr1 = readl_relaxed(port->membase + ofs->cr1);
1161bcda09dSBich HEMON 		cr3 = readl_relaxed(port->membase + ofs->cr3);
1171bcda09dSBich HEMON 		usartdiv = readl_relaxed(port->membase + ofs->brr);
1181bcda09dSBich HEMON 		usartdiv = usartdiv & GENMASK(15, 0);
1191bcda09dSBich HEMON 		over8 = cr1 & USART_CR1_OVER8;
1201bcda09dSBich HEMON 
1211bcda09dSBich HEMON 		if (over8)
1221bcda09dSBich HEMON 			usartdiv = usartdiv | (usartdiv & GENMASK(4, 0))
1231bcda09dSBich HEMON 				   << USART_BRR_04_R_SHIFT;
1241bcda09dSBich HEMON 
1251bcda09dSBich HEMON 		baud = DIV_ROUND_CLOSEST(port->uartclk, usartdiv);
12656f9a76cSErwan Le Ray 		stm32_usart_config_reg_rs485(&cr1, &cr3,
1271bcda09dSBich HEMON 					     rs485conf->delay_rts_before_send,
12856f9a76cSErwan Le Ray 					     rs485conf->delay_rts_after_send,
12956f9a76cSErwan Le Ray 					     baud);
1301bcda09dSBich HEMON 
1311bcda09dSBich HEMON 		if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
1321bcda09dSBich HEMON 			cr3 &= ~USART_CR3_DEP;
1331bcda09dSBich HEMON 			rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
1341bcda09dSBich HEMON 		} else {
1351bcda09dSBich HEMON 			cr3 |= USART_CR3_DEP;
1361bcda09dSBich HEMON 			rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
1371bcda09dSBich HEMON 		}
1381bcda09dSBich HEMON 
1391bcda09dSBich HEMON 		writel_relaxed(cr3, port->membase + ofs->cr3);
1401bcda09dSBich HEMON 		writel_relaxed(cr1, port->membase + ofs->cr1);
1411bcda09dSBich HEMON 	} else {
14256f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3,
14356f9a76cSErwan Le Ray 				     USART_CR3_DEM | USART_CR3_DEP);
14456f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr1,
1451bcda09dSBich HEMON 				     USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
1461bcda09dSBich HEMON 	}
1471bcda09dSBich HEMON 
14856f9a76cSErwan Le Ray 	stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
1491bcda09dSBich HEMON 
1501bcda09dSBich HEMON 	return 0;
1511bcda09dSBich HEMON }
1521bcda09dSBich HEMON 
15356f9a76cSErwan Le Ray static int stm32_usart_init_rs485(struct uart_port *port,
1541bcda09dSBich HEMON 				  struct platform_device *pdev)
1551bcda09dSBich HEMON {
1561bcda09dSBich HEMON 	struct serial_rs485 *rs485conf = &port->rs485;
1571bcda09dSBich HEMON 
1581bcda09dSBich HEMON 	rs485conf->flags = 0;
1591bcda09dSBich HEMON 	rs485conf->delay_rts_before_send = 0;
1601bcda09dSBich HEMON 	rs485conf->delay_rts_after_send = 0;
1611bcda09dSBich HEMON 
1621bcda09dSBich HEMON 	if (!pdev->dev.of_node)
1631bcda09dSBich HEMON 		return -ENODEV;
1641bcda09dSBich HEMON 
165c150c0f3SLukas Wunner 	return uart_get_rs485_mode(port);
1661bcda09dSBich HEMON }
1671bcda09dSBich HEMON 
168*33bb2f6aSErwan Le Ray static bool stm32_usart_rx_dma_enabled(struct uart_port *port)
16934891872SAlexandre TORGUE {
17034891872SAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
171d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
172*33bb2f6aSErwan Le Ray 
173*33bb2f6aSErwan Le Ray 	if (!stm32_port->rx_ch)
174*33bb2f6aSErwan Le Ray 		return false;
175*33bb2f6aSErwan Le Ray 
176*33bb2f6aSErwan Le Ray 	return !!(readl_relaxed(port->membase + ofs->cr3) & USART_CR3_DMAR);
177*33bb2f6aSErwan Le Ray }
178*33bb2f6aSErwan Le Ray 
179*33bb2f6aSErwan Le Ray /* Return true when data is pending (in pio mode), and false when no data is pending. */
180*33bb2f6aSErwan Le Ray static bool stm32_usart_pending_rx_pio(struct uart_port *port, u32 *sr)
181*33bb2f6aSErwan Le Ray {
182*33bb2f6aSErwan Le Ray 	struct stm32_port *stm32_port = to_stm32_port(port);
183*33bb2f6aSErwan Le Ray 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
18434891872SAlexandre TORGUE 
18534891872SAlexandre TORGUE 	*sr = readl_relaxed(port->membase + ofs->isr);
186*33bb2f6aSErwan Le Ray 	/* Get pending characters in RDR or FIFO */
187*33bb2f6aSErwan Le Ray 	if (*sr & USART_SR_RXNE) {
188*33bb2f6aSErwan Le Ray 		/* Get all pending characters from the RDR or the FIFO when using interrupts */
189*33bb2f6aSErwan Le Ray 		if (!stm32_usart_rx_dma_enabled(port))
190*33bb2f6aSErwan Le Ray 			return true;
19134891872SAlexandre TORGUE 
192*33bb2f6aSErwan Le Ray 		/* Handle only RX data errors when using DMA */
193*33bb2f6aSErwan Le Ray 		if (*sr & USART_SR_ERR_MASK)
194*33bb2f6aSErwan Le Ray 			return true;
19534891872SAlexandre TORGUE 	}
19634891872SAlexandre TORGUE 
197*33bb2f6aSErwan Le Ray 	return false;
198*33bb2f6aSErwan Le Ray }
199*33bb2f6aSErwan Le Ray 
200*33bb2f6aSErwan Le Ray static unsigned long stm32_usart_get_char_pio(struct uart_port *port)
20134891872SAlexandre TORGUE {
20234891872SAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
203d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
20434891872SAlexandre TORGUE 	unsigned long c;
20534891872SAlexandre TORGUE 
2066c5962f3SErwan Le Ray 	c = readl_relaxed(port->membase + ofs->rdr);
207*33bb2f6aSErwan Le Ray 	/* Apply RDR data mask */
2086c5962f3SErwan Le Ray 	c &= stm32_port->rdr_mask;
2096c5962f3SErwan Le Ray 
2106c5962f3SErwan Le Ray 	return c;
21134891872SAlexandre TORGUE }
21234891872SAlexandre TORGUE 
213*33bb2f6aSErwan Le Ray static void stm32_usart_receive_chars_pio(struct uart_port *port)
21448a6092fSMaxime Coquelin {
215ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
216d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
217*33bb2f6aSErwan Le Ray 	unsigned long c;
21848a6092fSMaxime Coquelin 	u32 sr;
21948a6092fSMaxime Coquelin 	char flag;
22048a6092fSMaxime Coquelin 
221*33bb2f6aSErwan Le Ray 	while (stm32_usart_pending_rx_pio(port, &sr)) {
22248a6092fSMaxime Coquelin 		sr |= USART_SR_DUMMY_RX;
22348a6092fSMaxime Coquelin 		flag = TTY_NORMAL;
22448a6092fSMaxime Coquelin 
2254f01d833SErwan Le Ray 		/*
2264f01d833SErwan Le Ray 		 * Status bits has to be cleared before reading the RDR:
2274f01d833SErwan Le Ray 		 * In FIFO mode, reading the RDR will pop the next data
2284f01d833SErwan Le Ray 		 * (if any) along with its status bits into the SR.
2294f01d833SErwan Le Ray 		 * Not doing so leads to misalignement between RDR and SR,
2304f01d833SErwan Le Ray 		 * and clear status bits of the next rx data.
2314f01d833SErwan Le Ray 		 *
2324f01d833SErwan Le Ray 		 * Clear errors flags for stm32f7 and stm32h7 compatible
2334f01d833SErwan Le Ray 		 * devices. On stm32f4 compatible devices, the error bit is
2344f01d833SErwan Le Ray 		 * cleared by the sequence [read SR - read DR].
2354f01d833SErwan Le Ray 		 */
2364f01d833SErwan Le Ray 		if ((sr & USART_SR_ERR_MASK) && ofs->icr != UNDEF_REG)
2371250ed71SFabrice Gasnier 			writel_relaxed(sr & USART_SR_ERR_MASK,
2381250ed71SFabrice Gasnier 				       port->membase + ofs->icr);
2394f01d833SErwan Le Ray 
240*33bb2f6aSErwan Le Ray 		c = stm32_usart_get_char_pio(port);
2414f01d833SErwan Le Ray 		port->icount.rx++;
24248a6092fSMaxime Coquelin 		if (sr & USART_SR_ERR_MASK) {
2434f01d833SErwan Le Ray 			if (sr & USART_SR_ORE) {
24448a6092fSMaxime Coquelin 				port->icount.overrun++;
24548a6092fSMaxime Coquelin 			} else if (sr & USART_SR_PE) {
24648a6092fSMaxime Coquelin 				port->icount.parity++;
24748a6092fSMaxime Coquelin 			} else if (sr & USART_SR_FE) {
2484f01d833SErwan Le Ray 				/* Break detection if character is null */
2494f01d833SErwan Le Ray 				if (!c) {
2504f01d833SErwan Le Ray 					port->icount.brk++;
2514f01d833SErwan Le Ray 					if (uart_handle_break(port))
2524f01d833SErwan Le Ray 						continue;
2534f01d833SErwan Le Ray 				} else {
25448a6092fSMaxime Coquelin 					port->icount.frame++;
25548a6092fSMaxime Coquelin 				}
2564f01d833SErwan Le Ray 			}
25748a6092fSMaxime Coquelin 
25848a6092fSMaxime Coquelin 			sr &= port->read_status_mask;
25948a6092fSMaxime Coquelin 
2604f01d833SErwan Le Ray 			if (sr & USART_SR_PE) {
26148a6092fSMaxime Coquelin 				flag = TTY_PARITY;
2624f01d833SErwan Le Ray 			} else if (sr & USART_SR_FE) {
2634f01d833SErwan Le Ray 				if (!c)
2644f01d833SErwan Le Ray 					flag = TTY_BREAK;
2654f01d833SErwan Le Ray 				else
26648a6092fSMaxime Coquelin 					flag = TTY_FRAME;
26748a6092fSMaxime Coquelin 			}
2684f01d833SErwan Le Ray 		}
26948a6092fSMaxime Coquelin 
270cea37afdSJohan Hovold 		if (uart_prepare_sysrq_char(port, c))
27148a6092fSMaxime Coquelin 			continue;
27248a6092fSMaxime Coquelin 		uart_insert_char(port, sr, USART_SR_ORE, c, flag);
27348a6092fSMaxime Coquelin 	}
274*33bb2f6aSErwan Le Ray }
275*33bb2f6aSErwan Le Ray 
276*33bb2f6aSErwan Le Ray static void stm32_usart_push_buffer_dma(struct uart_port *port, unsigned int dma_size)
277*33bb2f6aSErwan Le Ray {
278*33bb2f6aSErwan Le Ray 	struct stm32_port *stm32_port = to_stm32_port(port);
279*33bb2f6aSErwan Le Ray 	struct tty_port *ttyport = &stm32_port->port.state->port;
280*33bb2f6aSErwan Le Ray 	unsigned char *dma_start;
281*33bb2f6aSErwan Le Ray 	int dma_count, i;
282*33bb2f6aSErwan Le Ray 
283*33bb2f6aSErwan Le Ray 	dma_start = stm32_port->rx_buf + (RX_BUF_L - stm32_port->last_res);
284*33bb2f6aSErwan Le Ray 
285*33bb2f6aSErwan Le Ray 	/*
286*33bb2f6aSErwan Le Ray 	 * Apply rdr_mask on buffer in order to mask parity bit.
287*33bb2f6aSErwan Le Ray 	 * This loop is useless in cs8 mode because DMA copies only
288*33bb2f6aSErwan Le Ray 	 * 8 bits and already ignores parity bit.
289*33bb2f6aSErwan Le Ray 	 */
290*33bb2f6aSErwan Le Ray 	if (!(stm32_port->rdr_mask == (BIT(8) - 1)))
291*33bb2f6aSErwan Le Ray 		for (i = 0; i < dma_size; i++)
292*33bb2f6aSErwan Le Ray 			*(dma_start + i) &= stm32_port->rdr_mask;
293*33bb2f6aSErwan Le Ray 
294*33bb2f6aSErwan Le Ray 	dma_count = tty_insert_flip_string(ttyport, dma_start, dma_size);
295*33bb2f6aSErwan Le Ray 	port->icount.rx += dma_count;
296*33bb2f6aSErwan Le Ray 	if (dma_count != dma_size)
297*33bb2f6aSErwan Le Ray 		port->icount.buf_overrun++;
298*33bb2f6aSErwan Le Ray 	stm32_port->last_res -= dma_count;
299*33bb2f6aSErwan Le Ray 	if (stm32_port->last_res == 0)
300*33bb2f6aSErwan Le Ray 		stm32_port->last_res = RX_BUF_L;
301*33bb2f6aSErwan Le Ray }
302*33bb2f6aSErwan Le Ray 
303*33bb2f6aSErwan Le Ray static void stm32_usart_receive_chars_dma(struct uart_port *port)
304*33bb2f6aSErwan Le Ray {
305*33bb2f6aSErwan Le Ray 	struct stm32_port *stm32_port = to_stm32_port(port);
306*33bb2f6aSErwan Le Ray 	unsigned int dma_size;
307*33bb2f6aSErwan Le Ray 
308*33bb2f6aSErwan Le Ray 	/* DMA buffer is configured in cyclic mode and handles the rollback of the buffer. */
309*33bb2f6aSErwan Le Ray 	if (stm32_port->rx_dma_state.residue > stm32_port->last_res) {
310*33bb2f6aSErwan Le Ray 		/* Conditional first part: from last_res to end of DMA buffer */
311*33bb2f6aSErwan Le Ray 		dma_size = stm32_port->last_res;
312*33bb2f6aSErwan Le Ray 		stm32_usart_push_buffer_dma(port, dma_size);
313*33bb2f6aSErwan Le Ray 	}
314*33bb2f6aSErwan Le Ray 
315*33bb2f6aSErwan Le Ray 	dma_size = stm32_port->last_res - stm32_port->rx_dma_state.residue;
316*33bb2f6aSErwan Le Ray 	stm32_usart_push_buffer_dma(port, dma_size);
317*33bb2f6aSErwan Le Ray }
318*33bb2f6aSErwan Le Ray 
319*33bb2f6aSErwan Le Ray static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag)
320*33bb2f6aSErwan Le Ray {
321*33bb2f6aSErwan Le Ray 	struct tty_port *tport = &port->state->port;
322*33bb2f6aSErwan Le Ray 	struct stm32_port *stm32_port = to_stm32_port(port);
323*33bb2f6aSErwan Le Ray 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
324*33bb2f6aSErwan Le Ray 	enum dma_status rx_dma_status;
325*33bb2f6aSErwan Le Ray 	unsigned long flags;
326*33bb2f6aSErwan Le Ray 	u32 sr;
327*33bb2f6aSErwan Le Ray 
328*33bb2f6aSErwan Le Ray 	if (irqflag)
329*33bb2f6aSErwan Le Ray 		spin_lock_irqsave(&port->lock, flags);
330*33bb2f6aSErwan Le Ray 	else
331*33bb2f6aSErwan Le Ray 		spin_lock(&port->lock);
332*33bb2f6aSErwan Le Ray 
333*33bb2f6aSErwan Le Ray 	if (stm32_usart_rx_dma_enabled(port)) {
334*33bb2f6aSErwan Le Ray 		rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch,
335*33bb2f6aSErwan Le Ray 						    stm32_port->rx_ch->cookie,
336*33bb2f6aSErwan Le Ray 						    &stm32_port->rx_dma_state);
337*33bb2f6aSErwan Le Ray 		if (rx_dma_status == DMA_IN_PROGRESS) {
338*33bb2f6aSErwan Le Ray 			/* Empty DMA buffer */
339*33bb2f6aSErwan Le Ray 			stm32_usart_receive_chars_dma(port);
340*33bb2f6aSErwan Le Ray 			sr = readl_relaxed(port->membase + ofs->isr);
341*33bb2f6aSErwan Le Ray 			if (sr & USART_SR_ERR_MASK) {
342*33bb2f6aSErwan Le Ray 				/* Disable DMA request line */
343*33bb2f6aSErwan Le Ray 				stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
344*33bb2f6aSErwan Le Ray 
345*33bb2f6aSErwan Le Ray 				/* Switch to PIO mode to handle the errors */
346*33bb2f6aSErwan Le Ray 				stm32_usart_receive_chars_pio(port);
347*33bb2f6aSErwan Le Ray 
348*33bb2f6aSErwan Le Ray 				/* Switch back to DMA mode */
349*33bb2f6aSErwan Le Ray 				stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR);
350*33bb2f6aSErwan Le Ray 			}
351*33bb2f6aSErwan Le Ray 		} else {
352*33bb2f6aSErwan Le Ray 			/* Disable RX DMA */
353*33bb2f6aSErwan Le Ray 			dmaengine_terminate_async(stm32_port->rx_ch);
354*33bb2f6aSErwan Le Ray 			stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
355*33bb2f6aSErwan Le Ray 			/* Fall back to interrupt mode */
356*33bb2f6aSErwan Le Ray 			dev_dbg(port->dev, "DMA error, fallback to irq mode\n");
357*33bb2f6aSErwan Le Ray 			stm32_usart_receive_chars_pio(port);
358*33bb2f6aSErwan Le Ray 		}
359*33bb2f6aSErwan Le Ray 	} else {
360*33bb2f6aSErwan Le Ray 		stm32_usart_receive_chars_pio(port);
361*33bb2f6aSErwan Le Ray 	}
36248a6092fSMaxime Coquelin 
363cc58d0a3SErwan Le Ray 	if (irqflag)
364cc58d0a3SErwan Le Ray 		uart_unlock_and_check_sysrq_irqrestore(port, irqflag);
365cc58d0a3SErwan Le Ray 	else
366cea37afdSJohan Hovold 		uart_unlock_and_check_sysrq(port);
367ad767681SErwan Le Ray 
36848a6092fSMaxime Coquelin 	tty_flip_buffer_push(tport);
36948a6092fSMaxime Coquelin }
37048a6092fSMaxime Coquelin 
37156f9a76cSErwan Le Ray static void stm32_usart_tx_dma_complete(void *arg)
37234891872SAlexandre TORGUE {
37334891872SAlexandre TORGUE 	struct uart_port *port = arg;
37434891872SAlexandre TORGUE 	struct stm32_port *stm32port = to_stm32_port(port);
375d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
376f16b90c2SErwan Le Ray 	unsigned long flags;
37734891872SAlexandre TORGUE 
378fb4f2e04SErwan Le Ray 	dmaengine_terminate_async(stm32port->tx_ch);
37956f9a76cSErwan Le Ray 	stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
38034891872SAlexandre TORGUE 	stm32port->tx_dma_busy = false;
38134891872SAlexandre TORGUE 
38234891872SAlexandre TORGUE 	/* Let's see if we have pending data to send */
383f16b90c2SErwan Le Ray 	spin_lock_irqsave(&port->lock, flags);
38456f9a76cSErwan Le Ray 	stm32_usart_transmit_chars(port);
385f16b90c2SErwan Le Ray 	spin_unlock_irqrestore(&port->lock, flags);
38634891872SAlexandre TORGUE }
38734891872SAlexandre TORGUE 
38856f9a76cSErwan Le Ray static void stm32_usart_tx_interrupt_enable(struct uart_port *port)
389d075719eSErwan Le Ray {
390d075719eSErwan Le Ray 	struct stm32_port *stm32_port = to_stm32_port(port);
391d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
392d075719eSErwan Le Ray 
393d075719eSErwan Le Ray 	/*
394d075719eSErwan Le Ray 	 * Enables TX FIFO threashold irq when FIFO is enabled,
395d075719eSErwan Le Ray 	 * or TX empty irq when FIFO is disabled
396d075719eSErwan Le Ray 	 */
3972aa1bbb2SFabrice Gasnier 	if (stm32_port->fifoen && stm32_port->txftcfg >= 0)
39856f9a76cSErwan Le Ray 		stm32_usart_set_bits(port, ofs->cr3, USART_CR3_TXFTIE);
399d075719eSErwan Le Ray 	else
40056f9a76cSErwan Le Ray 		stm32_usart_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
401d075719eSErwan Le Ray }
402d075719eSErwan Le Ray 
403*33bb2f6aSErwan Le Ray static void stm32_usart_rx_dma_complete(void *arg)
404*33bb2f6aSErwan Le Ray {
405*33bb2f6aSErwan Le Ray 	struct uart_port *port = arg;
406*33bb2f6aSErwan Le Ray 
407*33bb2f6aSErwan Le Ray 	stm32_usart_receive_chars(port, true);
408*33bb2f6aSErwan Le Ray }
409*33bb2f6aSErwan Le Ray 
41056f9a76cSErwan Le Ray static void stm32_usart_tx_interrupt_disable(struct uart_port *port)
411d075719eSErwan Le Ray {
412d075719eSErwan Le Ray 	struct stm32_port *stm32_port = to_stm32_port(port);
413d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
414d075719eSErwan Le Ray 
4152aa1bbb2SFabrice Gasnier 	if (stm32_port->fifoen && stm32_port->txftcfg >= 0)
41656f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_TXFTIE);
417d075719eSErwan Le Ray 	else
41856f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
419d075719eSErwan Le Ray }
420d075719eSErwan Le Ray 
42156f9a76cSErwan Le Ray static void stm32_usart_transmit_chars_pio(struct uart_port *port)
42234891872SAlexandre TORGUE {
42334891872SAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
424d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
42534891872SAlexandre TORGUE 	struct circ_buf *xmit = &port->state->xmit;
42634891872SAlexandre TORGUE 
42734891872SAlexandre TORGUE 	if (stm32_port->tx_dma_busy) {
42856f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
42934891872SAlexandre TORGUE 		stm32_port->tx_dma_busy = false;
43034891872SAlexandre TORGUE 	}
43134891872SAlexandre TORGUE 
4325d9176edSErwan Le Ray 	while (!uart_circ_empty(xmit)) {
4335d9176edSErwan Le Ray 		/* Check that TDR is empty before filling FIFO */
4345d9176edSErwan Le Ray 		if (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE))
4355d9176edSErwan Le Ray 			break;
43634891872SAlexandre TORGUE 		writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
43734891872SAlexandre TORGUE 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
43834891872SAlexandre TORGUE 		port->icount.tx++;
43934891872SAlexandre TORGUE 	}
44034891872SAlexandre TORGUE 
4415d9176edSErwan Le Ray 	/* rely on TXE irq (mask or unmask) for sending remaining data */
4425d9176edSErwan Le Ray 	if (uart_circ_empty(xmit))
44356f9a76cSErwan Le Ray 		stm32_usart_tx_interrupt_disable(port);
4445d9176edSErwan Le Ray 	else
44556f9a76cSErwan Le Ray 		stm32_usart_tx_interrupt_enable(port);
4465d9176edSErwan Le Ray }
4475d9176edSErwan Le Ray 
44856f9a76cSErwan Le Ray static void stm32_usart_transmit_chars_dma(struct uart_port *port)
44934891872SAlexandre TORGUE {
45034891872SAlexandre TORGUE 	struct stm32_port *stm32port = to_stm32_port(port);
451d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
45234891872SAlexandre TORGUE 	struct circ_buf *xmit = &port->state->xmit;
45334891872SAlexandre TORGUE 	struct dma_async_tx_descriptor *desc = NULL;
45434891872SAlexandre TORGUE 	unsigned int count, i;
45534891872SAlexandre TORGUE 
45634891872SAlexandre TORGUE 	if (stm32port->tx_dma_busy)
45734891872SAlexandre TORGUE 		return;
45834891872SAlexandre TORGUE 
45934891872SAlexandre TORGUE 	stm32port->tx_dma_busy = true;
46034891872SAlexandre TORGUE 
46134891872SAlexandre TORGUE 	count = uart_circ_chars_pending(xmit);
46234891872SAlexandre TORGUE 
46334891872SAlexandre TORGUE 	if (count > TX_BUF_L)
46434891872SAlexandre TORGUE 		count = TX_BUF_L;
46534891872SAlexandre TORGUE 
46634891872SAlexandre TORGUE 	if (xmit->tail < xmit->head) {
46734891872SAlexandre TORGUE 		memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], count);
46834891872SAlexandre TORGUE 	} else {
46934891872SAlexandre TORGUE 		size_t one = UART_XMIT_SIZE - xmit->tail;
47034891872SAlexandre TORGUE 		size_t two;
47134891872SAlexandre TORGUE 
47234891872SAlexandre TORGUE 		if (one > count)
47334891872SAlexandre TORGUE 			one = count;
47434891872SAlexandre TORGUE 		two = count - one;
47534891872SAlexandre TORGUE 
47634891872SAlexandre TORGUE 		memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], one);
47734891872SAlexandre TORGUE 		if (two)
47834891872SAlexandre TORGUE 			memcpy(&stm32port->tx_buf[one], &xmit->buf[0], two);
47934891872SAlexandre TORGUE 	}
48034891872SAlexandre TORGUE 
48134891872SAlexandre TORGUE 	desc = dmaengine_prep_slave_single(stm32port->tx_ch,
48234891872SAlexandre TORGUE 					   stm32port->tx_dma_buf,
48334891872SAlexandre TORGUE 					   count,
48434891872SAlexandre TORGUE 					   DMA_MEM_TO_DEV,
48534891872SAlexandre TORGUE 					   DMA_PREP_INTERRUPT);
48634891872SAlexandre TORGUE 
487e7997f7fSErwan Le Ray 	if (!desc)
488e7997f7fSErwan Le Ray 		goto fallback_err;
48934891872SAlexandre TORGUE 
49056f9a76cSErwan Le Ray 	desc->callback = stm32_usart_tx_dma_complete;
49134891872SAlexandre TORGUE 	desc->callback_param = port;
49234891872SAlexandre TORGUE 
49334891872SAlexandre TORGUE 	/* Push current DMA TX transaction in the pending queue */
494e7997f7fSErwan Le Ray 	if (dma_submit_error(dmaengine_submit(desc))) {
495e7997f7fSErwan Le Ray 		/* dma no yet started, safe to free resources */
496e7997f7fSErwan Le Ray 		dmaengine_terminate_async(stm32port->tx_ch);
497e7997f7fSErwan Le Ray 		goto fallback_err;
498e7997f7fSErwan Le Ray 	}
49934891872SAlexandre TORGUE 
50034891872SAlexandre TORGUE 	/* Issue pending DMA TX requests */
50134891872SAlexandre TORGUE 	dma_async_issue_pending(stm32port->tx_ch);
50234891872SAlexandre TORGUE 
50356f9a76cSErwan Le Ray 	stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT);
50434891872SAlexandre TORGUE 
50534891872SAlexandre TORGUE 	xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
50634891872SAlexandre TORGUE 	port->icount.tx += count;
507e7997f7fSErwan Le Ray 	return;
508e7997f7fSErwan Le Ray 
509e7997f7fSErwan Le Ray fallback_err:
510e7997f7fSErwan Le Ray 	for (i = count; i > 0; i--)
51156f9a76cSErwan Le Ray 		stm32_usart_transmit_chars_pio(port);
51234891872SAlexandre TORGUE }
51334891872SAlexandre TORGUE 
51456f9a76cSErwan Le Ray static void stm32_usart_transmit_chars(struct uart_port *port)
51548a6092fSMaxime Coquelin {
516ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
517d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
51848a6092fSMaxime Coquelin 	struct circ_buf *xmit = &port->state->xmit;
51948a6092fSMaxime Coquelin 
52048a6092fSMaxime Coquelin 	if (port->x_char) {
52134891872SAlexandre TORGUE 		if (stm32_port->tx_dma_busy)
52256f9a76cSErwan Le Ray 			stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
523ada8618fSAlexandre TORGUE 		writel_relaxed(port->x_char, port->membase + ofs->tdr);
52448a6092fSMaxime Coquelin 		port->x_char = 0;
52548a6092fSMaxime Coquelin 		port->icount.tx++;
52634891872SAlexandre TORGUE 		if (stm32_port->tx_dma_busy)
52756f9a76cSErwan Le Ray 			stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT);
52848a6092fSMaxime Coquelin 		return;
52948a6092fSMaxime Coquelin 	}
53048a6092fSMaxime Coquelin 
531b83b957cSErwan Le Ray 	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
53256f9a76cSErwan Le Ray 		stm32_usart_tx_interrupt_disable(port);
53348a6092fSMaxime Coquelin 		return;
53448a6092fSMaxime Coquelin 	}
53548a6092fSMaxime Coquelin 
53664c32eabSErwan Le Ray 	if (ofs->icr == UNDEF_REG)
53756f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->isr, USART_SR_TC);
53864c32eabSErwan Le Ray 	else
5391250ed71SFabrice Gasnier 		writel_relaxed(USART_ICR_TCCF, port->membase + ofs->icr);
54064c32eabSErwan Le Ray 
54134891872SAlexandre TORGUE 	if (stm32_port->tx_ch)
54256f9a76cSErwan Le Ray 		stm32_usart_transmit_chars_dma(port);
54334891872SAlexandre TORGUE 	else
54456f9a76cSErwan Le Ray 		stm32_usart_transmit_chars_pio(port);
54548a6092fSMaxime Coquelin 
54648a6092fSMaxime Coquelin 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
54748a6092fSMaxime Coquelin 		uart_write_wakeup(port);
54848a6092fSMaxime Coquelin 
54948a6092fSMaxime Coquelin 	if (uart_circ_empty(xmit))
55056f9a76cSErwan Le Ray 		stm32_usart_tx_interrupt_disable(port);
55148a6092fSMaxime Coquelin }
55248a6092fSMaxime Coquelin 
55356f9a76cSErwan Le Ray static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
55448a6092fSMaxime Coquelin {
55548a6092fSMaxime Coquelin 	struct uart_port *port = ptr;
55612761869SErwan Le Ray 	struct tty_port *tport = &port->state->port;
557ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
558d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
55948a6092fSMaxime Coquelin 	u32 sr;
56048a6092fSMaxime Coquelin 
561ada8618fSAlexandre TORGUE 	sr = readl_relaxed(port->membase + ofs->isr);
56248a6092fSMaxime Coquelin 
5634cc0ed62SErwan Le Ray 	if ((sr & USART_SR_RTOF) && ofs->icr != UNDEF_REG)
5644cc0ed62SErwan Le Ray 		writel_relaxed(USART_ICR_RTOCF,
5654cc0ed62SErwan Le Ray 			       port->membase + ofs->icr);
5664cc0ed62SErwan Le Ray 
56712761869SErwan Le Ray 	if ((sr & USART_SR_WUF) && ofs->icr != UNDEF_REG) {
56812761869SErwan Le Ray 		/* Clear wake up flag and disable wake up interrupt */
569270e5a74SFabrice Gasnier 		writel_relaxed(USART_ICR_WUCF,
570270e5a74SFabrice Gasnier 			       port->membase + ofs->icr);
57112761869SErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_WUFIE);
57212761869SErwan Le Ray 		if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
57312761869SErwan Le Ray 			pm_wakeup_event(tport->tty->dev, 0);
57412761869SErwan Le Ray 	}
575270e5a74SFabrice Gasnier 
576*33bb2f6aSErwan Le Ray 	/*
577*33bb2f6aSErwan Le Ray 	 * rx errors in dma mode has to be handled ASAP to avoid overrun as the DMA request
578*33bb2f6aSErwan Le Ray 	 * line has been masked by HW and rx data are stacking in FIFO.
579*33bb2f6aSErwan Le Ray 	 */
580*33bb2f6aSErwan Le Ray 	if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) ||
581*33bb2f6aSErwan Le Ray 	    ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port)))
58256f9a76cSErwan Le Ray 		stm32_usart_receive_chars(port, false);
58348a6092fSMaxime Coquelin 
584ad767681SErwan Le Ray 	if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) {
585ad767681SErwan Le Ray 		spin_lock(&port->lock);
58656f9a76cSErwan Le Ray 		stm32_usart_transmit_chars(port);
58701d32d71SAlexandre TORGUE 		spin_unlock(&port->lock);
588ad767681SErwan Le Ray 	}
58901d32d71SAlexandre TORGUE 
590*33bb2f6aSErwan Le Ray 	if (stm32_usart_rx_dma_enabled(port))
59134891872SAlexandre TORGUE 		return IRQ_WAKE_THREAD;
59234891872SAlexandre TORGUE 	else
59334891872SAlexandre TORGUE 		return IRQ_HANDLED;
59434891872SAlexandre TORGUE }
59534891872SAlexandre TORGUE 
59656f9a76cSErwan Le Ray static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr)
59734891872SAlexandre TORGUE {
59834891872SAlexandre TORGUE 	struct uart_port *port = ptr;
59934891872SAlexandre TORGUE 
600cc58d0a3SErwan Le Ray 	/* Receiver timeout irq for DMA RX */
601cc58d0a3SErwan Le Ray 	stm32_usart_receive_chars(port, false);
60234891872SAlexandre TORGUE 
60348a6092fSMaxime Coquelin 	return IRQ_HANDLED;
60448a6092fSMaxime Coquelin }
60548a6092fSMaxime Coquelin 
60656f9a76cSErwan Le Ray static unsigned int stm32_usart_tx_empty(struct uart_port *port)
60748a6092fSMaxime Coquelin {
608ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
609d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
610ada8618fSAlexandre TORGUE 
6113db1d524SErwan Le Ray 	if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC)
6123db1d524SErwan Le Ray 		return TIOCSER_TEMT;
6133db1d524SErwan Le Ray 
6143db1d524SErwan Le Ray 	return 0;
61548a6092fSMaxime Coquelin }
61648a6092fSMaxime Coquelin 
61756f9a76cSErwan Le Ray static void stm32_usart_set_mctrl(struct uart_port *port, unsigned int mctrl)
61848a6092fSMaxime Coquelin {
619ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
620d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
621ada8618fSAlexandre TORGUE 
62248a6092fSMaxime Coquelin 	if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
62356f9a76cSErwan Le Ray 		stm32_usart_set_bits(port, ofs->cr3, USART_CR3_RTSE);
62448a6092fSMaxime Coquelin 	else
62556f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_RTSE);
6266cf61b9bSManivannan Sadhasivam 
6276cf61b9bSManivannan Sadhasivam 	mctrl_gpio_set(stm32_port->gpios, mctrl);
62848a6092fSMaxime Coquelin }
62948a6092fSMaxime Coquelin 
63056f9a76cSErwan Le Ray static unsigned int stm32_usart_get_mctrl(struct uart_port *port)
63148a6092fSMaxime Coquelin {
6326cf61b9bSManivannan Sadhasivam 	struct stm32_port *stm32_port = to_stm32_port(port);
6336cf61b9bSManivannan Sadhasivam 	unsigned int ret;
6346cf61b9bSManivannan Sadhasivam 
63548a6092fSMaxime Coquelin 	/* This routine is used to get signals of: DCD, DSR, RI, and CTS */
6366cf61b9bSManivannan Sadhasivam 	ret = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
6376cf61b9bSManivannan Sadhasivam 
6386cf61b9bSManivannan Sadhasivam 	return mctrl_gpio_get(stm32_port->gpios, &ret);
6396cf61b9bSManivannan Sadhasivam }
6406cf61b9bSManivannan Sadhasivam 
64156f9a76cSErwan Le Ray static void stm32_usart_enable_ms(struct uart_port *port)
6426cf61b9bSManivannan Sadhasivam {
6436cf61b9bSManivannan Sadhasivam 	mctrl_gpio_enable_ms(to_stm32_port(port)->gpios);
6446cf61b9bSManivannan Sadhasivam }
6456cf61b9bSManivannan Sadhasivam 
64656f9a76cSErwan Le Ray static void stm32_usart_disable_ms(struct uart_port *port)
6476cf61b9bSManivannan Sadhasivam {
6486cf61b9bSManivannan Sadhasivam 	mctrl_gpio_disable_ms(to_stm32_port(port)->gpios);
64948a6092fSMaxime Coquelin }
65048a6092fSMaxime Coquelin 
65148a6092fSMaxime Coquelin /* Transmit stop */
65256f9a76cSErwan Le Ray static void stm32_usart_stop_tx(struct uart_port *port)
65348a6092fSMaxime Coquelin {
654ad0c2748SMarek Vasut 	struct stm32_port *stm32_port = to_stm32_port(port);
655ad0c2748SMarek Vasut 	struct serial_rs485 *rs485conf = &port->rs485;
656ad0c2748SMarek Vasut 
65756f9a76cSErwan Le Ray 	stm32_usart_tx_interrupt_disable(port);
658ad0c2748SMarek Vasut 
659ad0c2748SMarek Vasut 	if (rs485conf->flags & SER_RS485_ENABLED) {
660ad0c2748SMarek Vasut 		if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
661ad0c2748SMarek Vasut 			mctrl_gpio_set(stm32_port->gpios,
662ad0c2748SMarek Vasut 					stm32_port->port.mctrl & ~TIOCM_RTS);
663ad0c2748SMarek Vasut 		} else {
664ad0c2748SMarek Vasut 			mctrl_gpio_set(stm32_port->gpios,
665ad0c2748SMarek Vasut 					stm32_port->port.mctrl | TIOCM_RTS);
666ad0c2748SMarek Vasut 		}
667ad0c2748SMarek Vasut 	}
66848a6092fSMaxime Coquelin }
66948a6092fSMaxime Coquelin 
67048a6092fSMaxime Coquelin /* There are probably characters waiting to be transmitted. */
67156f9a76cSErwan Le Ray static void stm32_usart_start_tx(struct uart_port *port)
67248a6092fSMaxime Coquelin {
673ad0c2748SMarek Vasut 	struct stm32_port *stm32_port = to_stm32_port(port);
674ad0c2748SMarek Vasut 	struct serial_rs485 *rs485conf = &port->rs485;
67548a6092fSMaxime Coquelin 	struct circ_buf *xmit = &port->state->xmit;
67648a6092fSMaxime Coquelin 
67748a6092fSMaxime Coquelin 	if (uart_circ_empty(xmit))
67848a6092fSMaxime Coquelin 		return;
67948a6092fSMaxime Coquelin 
680ad0c2748SMarek Vasut 	if (rs485conf->flags & SER_RS485_ENABLED) {
681ad0c2748SMarek Vasut 		if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
682ad0c2748SMarek Vasut 			mctrl_gpio_set(stm32_port->gpios,
683ad0c2748SMarek Vasut 					stm32_port->port.mctrl | TIOCM_RTS);
684ad0c2748SMarek Vasut 		} else {
685ad0c2748SMarek Vasut 			mctrl_gpio_set(stm32_port->gpios,
686ad0c2748SMarek Vasut 					stm32_port->port.mctrl & ~TIOCM_RTS);
687ad0c2748SMarek Vasut 		}
688ad0c2748SMarek Vasut 	}
689ad0c2748SMarek Vasut 
69056f9a76cSErwan Le Ray 	stm32_usart_transmit_chars(port);
69148a6092fSMaxime Coquelin }
69248a6092fSMaxime Coquelin 
6933d82be8bSErwan Le Ray /* Flush the transmit buffer. */
6943d82be8bSErwan Le Ray static void stm32_usart_flush_buffer(struct uart_port *port)
6953d82be8bSErwan Le Ray {
6963d82be8bSErwan Le Ray 	struct stm32_port *stm32_port = to_stm32_port(port);
6973d82be8bSErwan Le Ray 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
6983d82be8bSErwan Le Ray 
6993d82be8bSErwan Le Ray 	if (stm32_port->tx_ch) {
7003d82be8bSErwan Le Ray 		dmaengine_terminate_async(stm32_port->tx_ch);
7013d82be8bSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
7023d82be8bSErwan Le Ray 		stm32_port->tx_dma_busy = false;
7033d82be8bSErwan Le Ray 	}
7043d82be8bSErwan Le Ray }
7053d82be8bSErwan Le Ray 
70648a6092fSMaxime Coquelin /* Throttle the remote when input buffer is about to overflow. */
70756f9a76cSErwan Le Ray static void stm32_usart_throttle(struct uart_port *port)
70848a6092fSMaxime Coquelin {
709ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
710d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
71148a6092fSMaxime Coquelin 	unsigned long flags;
71248a6092fSMaxime Coquelin 
71348a6092fSMaxime Coquelin 	spin_lock_irqsave(&port->lock, flags);
71456f9a76cSErwan Le Ray 	stm32_usart_clr_bits(port, ofs->cr1, stm32_port->cr1_irq);
715d0a6a7bcSErwan Le Ray 	if (stm32_port->cr3_irq)
71656f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq);
717d0a6a7bcSErwan Le Ray 
71848a6092fSMaxime Coquelin 	spin_unlock_irqrestore(&port->lock, flags);
71948a6092fSMaxime Coquelin }
72048a6092fSMaxime Coquelin 
72148a6092fSMaxime Coquelin /* Unthrottle the remote, the input buffer can now accept data. */
72256f9a76cSErwan Le Ray static void stm32_usart_unthrottle(struct uart_port *port)
72348a6092fSMaxime Coquelin {
724ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
725d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
72648a6092fSMaxime Coquelin 	unsigned long flags;
72748a6092fSMaxime Coquelin 
72848a6092fSMaxime Coquelin 	spin_lock_irqsave(&port->lock, flags);
72956f9a76cSErwan Le Ray 	stm32_usart_set_bits(port, ofs->cr1, stm32_port->cr1_irq);
730d0a6a7bcSErwan Le Ray 	if (stm32_port->cr3_irq)
73156f9a76cSErwan Le Ray 		stm32_usart_set_bits(port, ofs->cr3, stm32_port->cr3_irq);
732d0a6a7bcSErwan Le Ray 
73348a6092fSMaxime Coquelin 	spin_unlock_irqrestore(&port->lock, flags);
73448a6092fSMaxime Coquelin }
73548a6092fSMaxime Coquelin 
73648a6092fSMaxime Coquelin /* Receive stop */
73756f9a76cSErwan Le Ray static void stm32_usart_stop_rx(struct uart_port *port)
73848a6092fSMaxime Coquelin {
739ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
740d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
741ada8618fSAlexandre TORGUE 
74256f9a76cSErwan Le Ray 	stm32_usart_clr_bits(port, ofs->cr1, stm32_port->cr1_irq);
743d0a6a7bcSErwan Le Ray 	if (stm32_port->cr3_irq)
74456f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq);
74548a6092fSMaxime Coquelin }
74648a6092fSMaxime Coquelin 
74748a6092fSMaxime Coquelin /* Handle breaks - ignored by us */
74856f9a76cSErwan Le Ray static void stm32_usart_break_ctl(struct uart_port *port, int break_state)
74948a6092fSMaxime Coquelin {
75048a6092fSMaxime Coquelin }
75148a6092fSMaxime Coquelin 
75256f9a76cSErwan Le Ray static int stm32_usart_startup(struct uart_port *port)
75348a6092fSMaxime Coquelin {
754ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
755d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
756f4518a8aSErwan Le Ray 	const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
75748a6092fSMaxime Coquelin 	const char *name = to_platform_device(port->dev)->name;
75848a6092fSMaxime Coquelin 	u32 val;
75948a6092fSMaxime Coquelin 	int ret;
76048a6092fSMaxime Coquelin 
76156f9a76cSErwan Le Ray 	ret = request_threaded_irq(port->irq, stm32_usart_interrupt,
76256f9a76cSErwan Le Ray 				   stm32_usart_threaded_interrupt,
763e359b441SJohan Hovold 				   IRQF_ONESHOT | IRQF_NO_SUSPEND,
764e359b441SJohan Hovold 				   name, port);
76548a6092fSMaxime Coquelin 	if (ret)
76648a6092fSMaxime Coquelin 		return ret;
76748a6092fSMaxime Coquelin 
7683cd66593SMartin Devera 	if (stm32_port->swap) {
7693cd66593SMartin Devera 		val = readl_relaxed(port->membase + ofs->cr2);
7703cd66593SMartin Devera 		val |= USART_CR2_SWAP;
7713cd66593SMartin Devera 		writel_relaxed(val, port->membase + ofs->cr2);
7723cd66593SMartin Devera 	}
7733cd66593SMartin Devera 
77484872dc4SErwan Le Ray 	/* RX FIFO Flush */
77584872dc4SErwan Le Ray 	if (ofs->rqr != UNDEF_REG)
776315e2d8aSErwan Le Ray 		writel_relaxed(USART_RQR_RXFRQ, port->membase + ofs->rqr);
77748a6092fSMaxime Coquelin 
77825a8e761SErwan Le Ray 	/* RX enabling */
779f4518a8aSErwan Le Ray 	val = stm32_port->cr1_irq | USART_CR1_RE | BIT(cfg->uart_enable_bit);
78056f9a76cSErwan Le Ray 	stm32_usart_set_bits(port, ofs->cr1, val);
78184872dc4SErwan Le Ray 
78248a6092fSMaxime Coquelin 	return 0;
78348a6092fSMaxime Coquelin }
78448a6092fSMaxime Coquelin 
78556f9a76cSErwan Le Ray static void stm32_usart_shutdown(struct uart_port *port)
78648a6092fSMaxime Coquelin {
787ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
788d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
789d825f0beSStephen Boyd 	const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
79064c32eabSErwan Le Ray 	u32 val, isr;
79164c32eabSErwan Le Ray 	int ret;
79248a6092fSMaxime Coquelin 
7936cf61b9bSManivannan Sadhasivam 	/* Disable modem control interrupts */
79456f9a76cSErwan Le Ray 	stm32_usart_disable_ms(port);
7956cf61b9bSManivannan Sadhasivam 
7964cc0ed62SErwan Le Ray 	val = USART_CR1_TXEIE | USART_CR1_TE;
7974cc0ed62SErwan Le Ray 	val |= stm32_port->cr1_irq | USART_CR1_RE;
79887f1f809SAlexandre TORGUE 	val |= BIT(cfg->uart_enable_bit);
799351a762aSGerald Baeza 	if (stm32_port->fifoen)
800351a762aSGerald Baeza 		val |= USART_CR1_FIFOEN;
80164c32eabSErwan Le Ray 
80264c32eabSErwan Le Ray 	ret = readl_relaxed_poll_timeout(port->membase + ofs->isr,
80364c32eabSErwan Le Ray 					 isr, (isr & USART_SR_TC),
80464c32eabSErwan Le Ray 					 10, 100000);
80564c32eabSErwan Le Ray 
806c31c3ea0SErwan Le Ray 	/* Send the TC error message only when ISR_TC is not set */
80764c32eabSErwan Le Ray 	if (ret)
808c31c3ea0SErwan Le Ray 		dev_err(port->dev, "Transmission is not complete\n");
80964c32eabSErwan Le Ray 
8109f77d192SErwan Le Ray 	/* flush RX & TX FIFO */
8119f77d192SErwan Le Ray 	if (ofs->rqr != UNDEF_REG)
8129f77d192SErwan Le Ray 		writel_relaxed(USART_RQR_TXFRQ | USART_RQR_RXFRQ,
8139f77d192SErwan Le Ray 			       port->membase + ofs->rqr);
8149f77d192SErwan Le Ray 
81556f9a76cSErwan Le Ray 	stm32_usart_clr_bits(port, ofs->cr1, val);
81648a6092fSMaxime Coquelin 
81748a6092fSMaxime Coquelin 	free_irq(port->irq, port);
81848a6092fSMaxime Coquelin }
81948a6092fSMaxime Coquelin 
82056f9a76cSErwan Le Ray static void stm32_usart_set_termios(struct uart_port *port,
82156f9a76cSErwan Le Ray 				    struct ktermios *termios,
82248a6092fSMaxime Coquelin 				    struct ktermios *old)
82348a6092fSMaxime Coquelin {
82448a6092fSMaxime Coquelin 	struct stm32_port *stm32_port = to_stm32_port(port);
825d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
826d825f0beSStephen Boyd 	const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
8271bcda09dSBich HEMON 	struct serial_rs485 *rs485conf = &port->rs485;
828c8a9d043SErwan Le Ray 	unsigned int baud, bits;
82948a6092fSMaxime Coquelin 	u32 usartdiv, mantissa, fraction, oversampling;
83048a6092fSMaxime Coquelin 	tcflag_t cflag = termios->c_cflag;
831f264c6f6SErwan Le Ray 	u32 cr1, cr2, cr3, isr;
83248a6092fSMaxime Coquelin 	unsigned long flags;
833f264c6f6SErwan Le Ray 	int ret;
83448a6092fSMaxime Coquelin 
83548a6092fSMaxime Coquelin 	if (!stm32_port->hw_flow_control)
83648a6092fSMaxime Coquelin 		cflag &= ~CRTSCTS;
83748a6092fSMaxime Coquelin 
83848a6092fSMaxime Coquelin 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8);
83948a6092fSMaxime Coquelin 
84048a6092fSMaxime Coquelin 	spin_lock_irqsave(&port->lock, flags);
84148a6092fSMaxime Coquelin 
842f264c6f6SErwan Le Ray 	ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
843f264c6f6SErwan Le Ray 						isr,
844f264c6f6SErwan Le Ray 						(isr & USART_SR_TC),
845f264c6f6SErwan Le Ray 						10, 100000);
846f264c6f6SErwan Le Ray 
847f264c6f6SErwan Le Ray 	/* Send the TC error message only when ISR_TC is not set. */
848f264c6f6SErwan Le Ray 	if (ret)
849f264c6f6SErwan Le Ray 		dev_err(port->dev, "Transmission is not complete\n");
850f264c6f6SErwan Le Ray 
85148a6092fSMaxime Coquelin 	/* Stop serial port and reset value */
852ada8618fSAlexandre TORGUE 	writel_relaxed(0, port->membase + ofs->cr1);
85348a6092fSMaxime Coquelin 
85484872dc4SErwan Le Ray 	/* flush RX & TX FIFO */
85584872dc4SErwan Le Ray 	if (ofs->rqr != UNDEF_REG)
856315e2d8aSErwan Le Ray 		writel_relaxed(USART_RQR_TXFRQ | USART_RQR_RXFRQ,
857315e2d8aSErwan Le Ray 			       port->membase + ofs->rqr);
8581bcda09dSBich HEMON 
85984872dc4SErwan Le Ray 	cr1 = USART_CR1_TE | USART_CR1_RE;
860351a762aSGerald Baeza 	if (stm32_port->fifoen)
861351a762aSGerald Baeza 		cr1 |= USART_CR1_FIFOEN;
8623cd66593SMartin Devera 	cr2 = stm32_port->swap ? USART_CR2_SWAP : 0;
86325a8e761SErwan Le Ray 
86425a8e761SErwan Le Ray 	/* Tx and RX FIFO configuration */
865d075719eSErwan Le Ray 	cr3 = readl_relaxed(port->membase + ofs->cr3);
86625a8e761SErwan Le Ray 	cr3 &= USART_CR3_TXFTIE | USART_CR3_RXFTIE;
86725a8e761SErwan Le Ray 	if (stm32_port->fifoen) {
8682aa1bbb2SFabrice Gasnier 		if (stm32_port->txftcfg >= 0)
8692aa1bbb2SFabrice Gasnier 			cr3 |= stm32_port->txftcfg << USART_CR3_TXFTCFG_SHIFT;
8702aa1bbb2SFabrice Gasnier 		if (stm32_port->rxftcfg >= 0)
8712aa1bbb2SFabrice Gasnier 			cr3 |= stm32_port->rxftcfg << USART_CR3_RXFTCFG_SHIFT;
87225a8e761SErwan Le Ray 	}
87348a6092fSMaxime Coquelin 
87448a6092fSMaxime Coquelin 	if (cflag & CSTOPB)
87548a6092fSMaxime Coquelin 		cr2 |= USART_CR2_STOP_2B;
87648a6092fSMaxime Coquelin 
8773ec2ff37SJiri Slaby 	bits = tty_get_char_size(cflag);
8786c5962f3SErwan Le Ray 	stm32_port->rdr_mask = (BIT(bits) - 1);
879c8a9d043SErwan Le Ray 
88048a6092fSMaxime Coquelin 	if (cflag & PARENB) {
881c8a9d043SErwan Le Ray 		bits++;
88248a6092fSMaxime Coquelin 		cr1 |= USART_CR1_PCE;
883c8a9d043SErwan Le Ray 	}
884c8a9d043SErwan Le Ray 
885c8a9d043SErwan Le Ray 	/*
886c8a9d043SErwan Le Ray 	 * Word length configuration:
887c8a9d043SErwan Le Ray 	 * CS8 + parity, 9 bits word aka [M1:M0] = 0b01
888c8a9d043SErwan Le Ray 	 * CS7 or (CS6 + parity), 7 bits word aka [M1:M0] = 0b10
889c8a9d043SErwan Le Ray 	 * CS8 or (CS7 + parity), 8 bits word aka [M1:M0] = 0b00
890c8a9d043SErwan Le Ray 	 * M0 and M1 already cleared by cr1 initialization.
891c8a9d043SErwan Le Ray 	 */
892c8a9d043SErwan Le Ray 	if (bits == 9)
893ada8618fSAlexandre TORGUE 		cr1 |= USART_CR1_M0;
894c8a9d043SErwan Le Ray 	else if ((bits == 7) && cfg->has_7bits_data)
895c8a9d043SErwan Le Ray 		cr1 |= USART_CR1_M1;
896c8a9d043SErwan Le Ray 	else if (bits != 8)
897c8a9d043SErwan Le Ray 		dev_dbg(port->dev, "Unsupported data bits config: %u bits\n"
898c8a9d043SErwan Le Ray 			, bits);
89948a6092fSMaxime Coquelin 
9004cc0ed62SErwan Le Ray 	if (ofs->rtor != UNDEF_REG && (stm32_port->rx_ch ||
9012aa1bbb2SFabrice Gasnier 				       (stm32_port->fifoen &&
9022aa1bbb2SFabrice Gasnier 					stm32_port->rxftcfg >= 0))) {
9034cc0ed62SErwan Le Ray 		if (cflag & CSTOPB)
9044cc0ed62SErwan Le Ray 			bits = bits + 3; /* 1 start bit + 2 stop bits */
9054cc0ed62SErwan Le Ray 		else
9064cc0ed62SErwan Le Ray 			bits = bits + 2; /* 1 start bit + 1 stop bit */
9074cc0ed62SErwan Le Ray 
9084cc0ed62SErwan Le Ray 		/* RX timeout irq to occur after last stop bit + bits */
9094cc0ed62SErwan Le Ray 		stm32_port->cr1_irq = USART_CR1_RTOIE;
9104cc0ed62SErwan Le Ray 		writel_relaxed(bits, port->membase + ofs->rtor);
9114cc0ed62SErwan Le Ray 		cr2 |= USART_CR2_RTOEN;
912*33bb2f6aSErwan Le Ray 		/*
913*33bb2f6aSErwan Le Ray 		 * Enable fifo threshold irq in two cases, either when there is no DMA, or when
914*33bb2f6aSErwan Le Ray 		 * wake up over usart, from low power until the DMA gets re-enabled by resume.
915*33bb2f6aSErwan Le Ray 		 */
916d0a6a7bcSErwan Le Ray 		stm32_port->cr3_irq =  USART_CR3_RXFTIE;
9174cc0ed62SErwan Le Ray 	}
9184cc0ed62SErwan Le Ray 
919d0a6a7bcSErwan Le Ray 	cr1 |= stm32_port->cr1_irq;
920d0a6a7bcSErwan Le Ray 	cr3 |= stm32_port->cr3_irq;
921d0a6a7bcSErwan Le Ray 
92248a6092fSMaxime Coquelin 	if (cflag & PARODD)
92348a6092fSMaxime Coquelin 		cr1 |= USART_CR1_PS;
92448a6092fSMaxime Coquelin 
92548a6092fSMaxime Coquelin 	port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
92648a6092fSMaxime Coquelin 	if (cflag & CRTSCTS) {
92748a6092fSMaxime Coquelin 		port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
92835abe98fSBich HEMON 		cr3 |= USART_CR3_CTSE | USART_CR3_RTSE;
92948a6092fSMaxime Coquelin 	}
93048a6092fSMaxime Coquelin 
93148a6092fSMaxime Coquelin 	usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
93248a6092fSMaxime Coquelin 
93348a6092fSMaxime Coquelin 	/*
93448a6092fSMaxime Coquelin 	 * The USART supports 16 or 8 times oversampling.
93548a6092fSMaxime Coquelin 	 * By default we prefer 16 times oversampling, so that the receiver
93648a6092fSMaxime Coquelin 	 * has a better tolerance to clock deviations.
93748a6092fSMaxime Coquelin 	 * 8 times oversampling is only used to achieve higher speeds.
93848a6092fSMaxime Coquelin 	 */
93948a6092fSMaxime Coquelin 	if (usartdiv < 16) {
94048a6092fSMaxime Coquelin 		oversampling = 8;
9411bcda09dSBich HEMON 		cr1 |= USART_CR1_OVER8;
94256f9a76cSErwan Le Ray 		stm32_usart_set_bits(port, ofs->cr1, USART_CR1_OVER8);
94348a6092fSMaxime Coquelin 	} else {
94448a6092fSMaxime Coquelin 		oversampling = 16;
9451bcda09dSBich HEMON 		cr1 &= ~USART_CR1_OVER8;
94656f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_OVER8);
94748a6092fSMaxime Coquelin 	}
94848a6092fSMaxime Coquelin 
94948a6092fSMaxime Coquelin 	mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT;
95048a6092fSMaxime Coquelin 	fraction = usartdiv % oversampling;
951ada8618fSAlexandre TORGUE 	writel_relaxed(mantissa | fraction, port->membase + ofs->brr);
95248a6092fSMaxime Coquelin 
95348a6092fSMaxime Coquelin 	uart_update_timeout(port, cflag, baud);
95448a6092fSMaxime Coquelin 
95548a6092fSMaxime Coquelin 	port->read_status_mask = USART_SR_ORE;
95648a6092fSMaxime Coquelin 	if (termios->c_iflag & INPCK)
95748a6092fSMaxime Coquelin 		port->read_status_mask |= USART_SR_PE | USART_SR_FE;
95848a6092fSMaxime Coquelin 	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
9594f01d833SErwan Le Ray 		port->read_status_mask |= USART_SR_FE;
96048a6092fSMaxime Coquelin 
96148a6092fSMaxime Coquelin 	/* Characters to ignore */
96248a6092fSMaxime Coquelin 	port->ignore_status_mask = 0;
96348a6092fSMaxime Coquelin 	if (termios->c_iflag & IGNPAR)
96448a6092fSMaxime Coquelin 		port->ignore_status_mask = USART_SR_PE | USART_SR_FE;
96548a6092fSMaxime Coquelin 	if (termios->c_iflag & IGNBRK) {
9664f01d833SErwan Le Ray 		port->ignore_status_mask |= USART_SR_FE;
96748a6092fSMaxime Coquelin 		/*
96848a6092fSMaxime Coquelin 		 * If we're ignoring parity and break indicators,
96948a6092fSMaxime Coquelin 		 * ignore overruns too (for real raw support).
97048a6092fSMaxime Coquelin 		 */
97148a6092fSMaxime Coquelin 		if (termios->c_iflag & IGNPAR)
97248a6092fSMaxime Coquelin 			port->ignore_status_mask |= USART_SR_ORE;
97348a6092fSMaxime Coquelin 	}
97448a6092fSMaxime Coquelin 
97548a6092fSMaxime Coquelin 	/* Ignore all characters if CREAD is not set */
97648a6092fSMaxime Coquelin 	if ((termios->c_cflag & CREAD) == 0)
97748a6092fSMaxime Coquelin 		port->ignore_status_mask |= USART_SR_DUMMY_RX;
97848a6092fSMaxime Coquelin 
979*33bb2f6aSErwan Le Ray 	if (stm32_port->rx_ch) {
980*33bb2f6aSErwan Le Ray 		/*
981*33bb2f6aSErwan Le Ray 		 * Setup DMA to collect only valid data and enable error irqs.
982*33bb2f6aSErwan Le Ray 		 * This also enables break reception when using DMA.
983*33bb2f6aSErwan Le Ray 		 */
984*33bb2f6aSErwan Le Ray 		cr1 |= USART_CR1_PEIE;
985*33bb2f6aSErwan Le Ray 		cr3 |= USART_CR3_EIE;
98634891872SAlexandre TORGUE 		cr3 |= USART_CR3_DMAR;
987*33bb2f6aSErwan Le Ray 		cr3 |= USART_CR3_DDRE;
988*33bb2f6aSErwan Le Ray 	}
98934891872SAlexandre TORGUE 
9901bcda09dSBich HEMON 	if (rs485conf->flags & SER_RS485_ENABLED) {
99156f9a76cSErwan Le Ray 		stm32_usart_config_reg_rs485(&cr1, &cr3,
9921bcda09dSBich HEMON 					     rs485conf->delay_rts_before_send,
99356f9a76cSErwan Le Ray 					     rs485conf->delay_rts_after_send,
99456f9a76cSErwan Le Ray 					     baud);
9951bcda09dSBich HEMON 		if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
9961bcda09dSBich HEMON 			cr3 &= ~USART_CR3_DEP;
9971bcda09dSBich HEMON 			rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
9981bcda09dSBich HEMON 		} else {
9991bcda09dSBich HEMON 			cr3 |= USART_CR3_DEP;
10001bcda09dSBich HEMON 			rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
10011bcda09dSBich HEMON 		}
10021bcda09dSBich HEMON 
10031bcda09dSBich HEMON 	} else {
10041bcda09dSBich HEMON 		cr3 &= ~(USART_CR3_DEM | USART_CR3_DEP);
10051bcda09dSBich HEMON 		cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
10061bcda09dSBich HEMON 	}
10071bcda09dSBich HEMON 
100812761869SErwan Le Ray 	/* Configure wake up from low power on start bit detection */
10093d530017SAlexandre Torgue 	if (stm32_port->wakeup_src) {
101012761869SErwan Le Ray 		cr3 &= ~USART_CR3_WUS_MASK;
101112761869SErwan Le Ray 		cr3 |= USART_CR3_WUS_START_BIT;
101212761869SErwan Le Ray 	}
101312761869SErwan Le Ray 
1014ada8618fSAlexandre TORGUE 	writel_relaxed(cr3, port->membase + ofs->cr3);
1015ada8618fSAlexandre TORGUE 	writel_relaxed(cr2, port->membase + ofs->cr2);
1016ada8618fSAlexandre TORGUE 	writel_relaxed(cr1, port->membase + ofs->cr1);
101748a6092fSMaxime Coquelin 
101856f9a76cSErwan Le Ray 	stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
101948a6092fSMaxime Coquelin 	spin_unlock_irqrestore(&port->lock, flags);
1020436c9793SErwan Le Ray 
1021436c9793SErwan Le Ray 	/* Handle modem control interrupts */
1022436c9793SErwan Le Ray 	if (UART_ENABLE_MS(port, termios->c_cflag))
1023436c9793SErwan Le Ray 		stm32_usart_enable_ms(port);
1024436c9793SErwan Le Ray 	else
1025436c9793SErwan Le Ray 		stm32_usart_disable_ms(port);
102648a6092fSMaxime Coquelin }
102748a6092fSMaxime Coquelin 
102856f9a76cSErwan Le Ray static const char *stm32_usart_type(struct uart_port *port)
102948a6092fSMaxime Coquelin {
103048a6092fSMaxime Coquelin 	return (port->type == PORT_STM32) ? DRIVER_NAME : NULL;
103148a6092fSMaxime Coquelin }
103248a6092fSMaxime Coquelin 
103356f9a76cSErwan Le Ray static void stm32_usart_release_port(struct uart_port *port)
103448a6092fSMaxime Coquelin {
103548a6092fSMaxime Coquelin }
103648a6092fSMaxime Coquelin 
103756f9a76cSErwan Le Ray static int stm32_usart_request_port(struct uart_port *port)
103848a6092fSMaxime Coquelin {
103948a6092fSMaxime Coquelin 	return 0;
104048a6092fSMaxime Coquelin }
104148a6092fSMaxime Coquelin 
104256f9a76cSErwan Le Ray static void stm32_usart_config_port(struct uart_port *port, int flags)
104348a6092fSMaxime Coquelin {
104448a6092fSMaxime Coquelin 	if (flags & UART_CONFIG_TYPE)
104548a6092fSMaxime Coquelin 		port->type = PORT_STM32;
104648a6092fSMaxime Coquelin }
104748a6092fSMaxime Coquelin 
104848a6092fSMaxime Coquelin static int
104956f9a76cSErwan Le Ray stm32_usart_verify_port(struct uart_port *port, struct serial_struct *ser)
105048a6092fSMaxime Coquelin {
105148a6092fSMaxime Coquelin 	/* No user changeable parameters */
105248a6092fSMaxime Coquelin 	return -EINVAL;
105348a6092fSMaxime Coquelin }
105448a6092fSMaxime Coquelin 
105556f9a76cSErwan Le Ray static void stm32_usart_pm(struct uart_port *port, unsigned int state,
105648a6092fSMaxime Coquelin 			   unsigned int oldstate)
105748a6092fSMaxime Coquelin {
105848a6092fSMaxime Coquelin 	struct stm32_port *stm32port = container_of(port,
105948a6092fSMaxime Coquelin 			struct stm32_port, port);
1060d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
1061d825f0beSStephen Boyd 	const struct stm32_usart_config *cfg = &stm32port->info->cfg;
106218ee37e1SJohan Hovold 	unsigned long flags;
106348a6092fSMaxime Coquelin 
106448a6092fSMaxime Coquelin 	switch (state) {
106548a6092fSMaxime Coquelin 	case UART_PM_STATE_ON:
1066fb6dcef6SErwan Le Ray 		pm_runtime_get_sync(port->dev);
106748a6092fSMaxime Coquelin 		break;
106848a6092fSMaxime Coquelin 	case UART_PM_STATE_OFF:
106948a6092fSMaxime Coquelin 		spin_lock_irqsave(&port->lock, flags);
107056f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
107148a6092fSMaxime Coquelin 		spin_unlock_irqrestore(&port->lock, flags);
1072fb6dcef6SErwan Le Ray 		pm_runtime_put_sync(port->dev);
107348a6092fSMaxime Coquelin 		break;
107448a6092fSMaxime Coquelin 	}
107548a6092fSMaxime Coquelin }
107648a6092fSMaxime Coquelin 
107748a6092fSMaxime Coquelin static const struct uart_ops stm32_uart_ops = {
107856f9a76cSErwan Le Ray 	.tx_empty	= stm32_usart_tx_empty,
107956f9a76cSErwan Le Ray 	.set_mctrl	= stm32_usart_set_mctrl,
108056f9a76cSErwan Le Ray 	.get_mctrl	= stm32_usart_get_mctrl,
108156f9a76cSErwan Le Ray 	.stop_tx	= stm32_usart_stop_tx,
108256f9a76cSErwan Le Ray 	.start_tx	= stm32_usart_start_tx,
108356f9a76cSErwan Le Ray 	.throttle	= stm32_usart_throttle,
108456f9a76cSErwan Le Ray 	.unthrottle	= stm32_usart_unthrottle,
108556f9a76cSErwan Le Ray 	.stop_rx	= stm32_usart_stop_rx,
108656f9a76cSErwan Le Ray 	.enable_ms	= stm32_usart_enable_ms,
108756f9a76cSErwan Le Ray 	.break_ctl	= stm32_usart_break_ctl,
108856f9a76cSErwan Le Ray 	.startup	= stm32_usart_startup,
108956f9a76cSErwan Le Ray 	.shutdown	= stm32_usart_shutdown,
10903d82be8bSErwan Le Ray 	.flush_buffer	= stm32_usart_flush_buffer,
109156f9a76cSErwan Le Ray 	.set_termios	= stm32_usart_set_termios,
109256f9a76cSErwan Le Ray 	.pm		= stm32_usart_pm,
109356f9a76cSErwan Le Ray 	.type		= stm32_usart_type,
109456f9a76cSErwan Le Ray 	.release_port	= stm32_usart_release_port,
109556f9a76cSErwan Le Ray 	.request_port	= stm32_usart_request_port,
109656f9a76cSErwan Le Ray 	.config_port	= stm32_usart_config_port,
109756f9a76cSErwan Le Ray 	.verify_port	= stm32_usart_verify_port,
109848a6092fSMaxime Coquelin };
109948a6092fSMaxime Coquelin 
11002aa1bbb2SFabrice Gasnier /*
11012aa1bbb2SFabrice Gasnier  * STM32H7 RX & TX FIFO threshold configuration (CR3 RXFTCFG / TXFTCFG)
11022aa1bbb2SFabrice Gasnier  * Note: 1 isn't a valid value in RXFTCFG / TXFTCFG. In this case,
11032aa1bbb2SFabrice Gasnier  * RXNEIE / TXEIE can be used instead of threshold irqs: RXFTIE / TXFTIE.
11042aa1bbb2SFabrice Gasnier  * So, RXFTCFG / TXFTCFG bitfields values are encoded as array index + 1.
11052aa1bbb2SFabrice Gasnier  */
11062aa1bbb2SFabrice Gasnier static const u32 stm32h7_usart_fifo_thresh_cfg[] = { 1, 2, 4, 8, 12, 14, 16 };
11072aa1bbb2SFabrice Gasnier 
11082aa1bbb2SFabrice Gasnier static void stm32_usart_get_ftcfg(struct platform_device *pdev, const char *p,
11092aa1bbb2SFabrice Gasnier 				  int *ftcfg)
11102aa1bbb2SFabrice Gasnier {
11112aa1bbb2SFabrice Gasnier 	u32 bytes, i;
11122aa1bbb2SFabrice Gasnier 
11132aa1bbb2SFabrice Gasnier 	/* DT option to get RX & TX FIFO threshold (default to 8 bytes) */
11142aa1bbb2SFabrice Gasnier 	if (of_property_read_u32(pdev->dev.of_node, p, &bytes))
11152aa1bbb2SFabrice Gasnier 		bytes = 8;
11162aa1bbb2SFabrice Gasnier 
11172aa1bbb2SFabrice Gasnier 	for (i = 0; i < ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg); i++)
11182aa1bbb2SFabrice Gasnier 		if (stm32h7_usart_fifo_thresh_cfg[i] >= bytes)
11192aa1bbb2SFabrice Gasnier 			break;
11202aa1bbb2SFabrice Gasnier 	if (i >= ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg))
11212aa1bbb2SFabrice Gasnier 		i = ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg) - 1;
11222aa1bbb2SFabrice Gasnier 
11232aa1bbb2SFabrice Gasnier 	dev_dbg(&pdev->dev, "%s set to %d bytes\n", p,
11242aa1bbb2SFabrice Gasnier 		stm32h7_usart_fifo_thresh_cfg[i]);
11252aa1bbb2SFabrice Gasnier 
11262aa1bbb2SFabrice Gasnier 	/* Provide FIFO threshold ftcfg (1 is invalid: threshold irq unused) */
11272aa1bbb2SFabrice Gasnier 	if (i)
11282aa1bbb2SFabrice Gasnier 		*ftcfg = i - 1;
11292aa1bbb2SFabrice Gasnier 	else
11302aa1bbb2SFabrice Gasnier 		*ftcfg = -EINVAL;
11312aa1bbb2SFabrice Gasnier }
11322aa1bbb2SFabrice Gasnier 
113397f3a085SErwan Le Ray static void stm32_usart_deinit_port(struct stm32_port *stm32port)
113497f3a085SErwan Le Ray {
113597f3a085SErwan Le Ray 	clk_disable_unprepare(stm32port->clk);
113697f3a085SErwan Le Ray }
113797f3a085SErwan Le Ray 
113856f9a76cSErwan Le Ray static int stm32_usart_init_port(struct stm32_port *stm32port,
113948a6092fSMaxime Coquelin 				 struct platform_device *pdev)
114048a6092fSMaxime Coquelin {
114148a6092fSMaxime Coquelin 	struct uart_port *port = &stm32port->port;
114248a6092fSMaxime Coquelin 	struct resource *res;
1143e0f2a902SErwan Le Ray 	int ret, irq;
114448a6092fSMaxime Coquelin 
1145e0f2a902SErwan Le Ray 	irq = platform_get_irq(pdev, 0);
1146217b04c6STang Bin 	if (irq < 0)
1147217b04c6STang Bin 		return irq;
114892fc0023SErwan Le Ray 
114948a6092fSMaxime Coquelin 	port->iotype	= UPIO_MEM;
115048a6092fSMaxime Coquelin 	port->flags	= UPF_BOOT_AUTOCONF;
115148a6092fSMaxime Coquelin 	port->ops	= &stm32_uart_ops;
115248a6092fSMaxime Coquelin 	port->dev	= &pdev->dev;
1153d075719eSErwan Le Ray 	port->fifosize	= stm32port->info->cfg.fifosize;
11549feedaa7SDmitry Safonov 	port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_STM32_CONSOLE);
1155e0f2a902SErwan Le Ray 	port->irq = irq;
115656f9a76cSErwan Le Ray 	port->rs485_config = stm32_usart_config_rs485;
11577d8f6861SBich HEMON 
115856f9a76cSErwan Le Ray 	ret = stm32_usart_init_rs485(port, pdev);
1159c150c0f3SLukas Wunner 	if (ret)
1160c150c0f3SLukas Wunner 		return ret;
11617d8f6861SBich HEMON 
11623d530017SAlexandre Torgue 	stm32port->wakeup_src = stm32port->info->cfg.has_wakeup &&
11633d530017SAlexandre Torgue 		of_property_read_bool(pdev->dev.of_node, "wakeup-source");
11642c58e560SErwan Le Ray 
11653cd66593SMartin Devera 	stm32port->swap = stm32port->info->cfg.has_swap &&
11663cd66593SMartin Devera 		of_property_read_bool(pdev->dev.of_node, "rx-tx-swap");
11673cd66593SMartin Devera 
1168351a762aSGerald Baeza 	stm32port->fifoen = stm32port->info->cfg.has_fifo;
11692aa1bbb2SFabrice Gasnier 	if (stm32port->fifoen) {
11702aa1bbb2SFabrice Gasnier 		stm32_usart_get_ftcfg(pdev, "rx-threshold",
11712aa1bbb2SFabrice Gasnier 				      &stm32port->rxftcfg);
11722aa1bbb2SFabrice Gasnier 		stm32_usart_get_ftcfg(pdev, "tx-threshold",
11732aa1bbb2SFabrice Gasnier 				      &stm32port->txftcfg);
11742aa1bbb2SFabrice Gasnier 	}
117548a6092fSMaxime Coquelin 
11763d881e32STang Bin 	port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
117748a6092fSMaxime Coquelin 	if (IS_ERR(port->membase))
117848a6092fSMaxime Coquelin 		return PTR_ERR(port->membase);
117948a6092fSMaxime Coquelin 	port->mapbase = res->start;
118048a6092fSMaxime Coquelin 
118148a6092fSMaxime Coquelin 	spin_lock_init(&port->lock);
118248a6092fSMaxime Coquelin 
118348a6092fSMaxime Coquelin 	stm32port->clk = devm_clk_get(&pdev->dev, NULL);
118448a6092fSMaxime Coquelin 	if (IS_ERR(stm32port->clk))
118548a6092fSMaxime Coquelin 		return PTR_ERR(stm32port->clk);
118648a6092fSMaxime Coquelin 
118748a6092fSMaxime Coquelin 	/* Ensure that clk rate is correct by enabling the clk */
118848a6092fSMaxime Coquelin 	ret = clk_prepare_enable(stm32port->clk);
118948a6092fSMaxime Coquelin 	if (ret)
119048a6092fSMaxime Coquelin 		return ret;
119148a6092fSMaxime Coquelin 
119248a6092fSMaxime Coquelin 	stm32port->port.uartclk = clk_get_rate(stm32port->clk);
1193ada80043SFabrice Gasnier 	if (!stm32port->port.uartclk) {
119448a6092fSMaxime Coquelin 		ret = -EINVAL;
11956cf61b9bSManivannan Sadhasivam 		goto err_clk;
1196ada80043SFabrice Gasnier 	}
119748a6092fSMaxime Coquelin 
11986cf61b9bSManivannan Sadhasivam 	stm32port->gpios = mctrl_gpio_init(&stm32port->port, 0);
11996cf61b9bSManivannan Sadhasivam 	if (IS_ERR(stm32port->gpios)) {
12006cf61b9bSManivannan Sadhasivam 		ret = PTR_ERR(stm32port->gpios);
12016cf61b9bSManivannan Sadhasivam 		goto err_clk;
12026cf61b9bSManivannan Sadhasivam 	}
12036cf61b9bSManivannan Sadhasivam 
12049359369aSErwan Le Ray 	/*
12059359369aSErwan Le Ray 	 * Both CTS/RTS gpios and "st,hw-flow-ctrl" (deprecated) or "uart-has-rtscts"
12069359369aSErwan Le Ray 	 * properties should not be specified.
12079359369aSErwan Le Ray 	 */
12086cf61b9bSManivannan Sadhasivam 	if (stm32port->hw_flow_control) {
12096cf61b9bSManivannan Sadhasivam 		if (mctrl_gpio_to_gpiod(stm32port->gpios, UART_GPIO_CTS) ||
12106cf61b9bSManivannan Sadhasivam 		    mctrl_gpio_to_gpiod(stm32port->gpios, UART_GPIO_RTS)) {
12116cf61b9bSManivannan Sadhasivam 			dev_err(&pdev->dev, "Conflicting RTS/CTS config\n");
12126cf61b9bSManivannan Sadhasivam 			ret = -EINVAL;
12136cf61b9bSManivannan Sadhasivam 			goto err_clk;
12146cf61b9bSManivannan Sadhasivam 		}
12156cf61b9bSManivannan Sadhasivam 	}
12166cf61b9bSManivannan Sadhasivam 
12176cf61b9bSManivannan Sadhasivam 	return ret;
12186cf61b9bSManivannan Sadhasivam 
12196cf61b9bSManivannan Sadhasivam err_clk:
12206cf61b9bSManivannan Sadhasivam 	clk_disable_unprepare(stm32port->clk);
12216cf61b9bSManivannan Sadhasivam 
122248a6092fSMaxime Coquelin 	return ret;
122348a6092fSMaxime Coquelin }
122448a6092fSMaxime Coquelin 
122556f9a76cSErwan Le Ray static struct stm32_port *stm32_usart_of_get_port(struct platform_device *pdev)
122648a6092fSMaxime Coquelin {
122748a6092fSMaxime Coquelin 	struct device_node *np = pdev->dev.of_node;
122848a6092fSMaxime Coquelin 	int id;
122948a6092fSMaxime Coquelin 
123048a6092fSMaxime Coquelin 	if (!np)
123148a6092fSMaxime Coquelin 		return NULL;
123248a6092fSMaxime Coquelin 
123348a6092fSMaxime Coquelin 	id = of_alias_get_id(np, "serial");
1234e5707915SGerald Baeza 	if (id < 0) {
1235e5707915SGerald Baeza 		dev_err(&pdev->dev, "failed to get alias id, errno %d\n", id);
1236e5707915SGerald Baeza 		return NULL;
1237e5707915SGerald Baeza 	}
123848a6092fSMaxime Coquelin 
123948a6092fSMaxime Coquelin 	if (WARN_ON(id >= STM32_MAX_PORTS))
124048a6092fSMaxime Coquelin 		return NULL;
124148a6092fSMaxime Coquelin 
12426fd9fffbSErwan Le Ray 	stm32_ports[id].hw_flow_control =
12436fd9fffbSErwan Le Ray 		of_property_read_bool (np, "st,hw-flow-ctrl") /*deprecated*/ ||
12446fd9fffbSErwan Le Ray 		of_property_read_bool (np, "uart-has-rtscts");
124548a6092fSMaxime Coquelin 	stm32_ports[id].port.line = id;
12464cc0ed62SErwan Le Ray 	stm32_ports[id].cr1_irq = USART_CR1_RXNEIE;
1247d0a6a7bcSErwan Le Ray 	stm32_ports[id].cr3_irq = 0;
1248e5707915SGerald Baeza 	stm32_ports[id].last_res = RX_BUF_L;
124948a6092fSMaxime Coquelin 	return &stm32_ports[id];
125048a6092fSMaxime Coquelin }
125148a6092fSMaxime Coquelin 
125248a6092fSMaxime Coquelin #ifdef CONFIG_OF
125348a6092fSMaxime Coquelin static const struct of_device_id stm32_match[] = {
1254ada8618fSAlexandre TORGUE 	{ .compatible = "st,stm32-uart", .data = &stm32f4_info},
1255ada8618fSAlexandre TORGUE 	{ .compatible = "st,stm32f7-uart", .data = &stm32f7_info},
1256270e5a74SFabrice Gasnier 	{ .compatible = "st,stm32h7-uart", .data = &stm32h7_info},
125748a6092fSMaxime Coquelin 	{},
125848a6092fSMaxime Coquelin };
125948a6092fSMaxime Coquelin 
126048a6092fSMaxime Coquelin MODULE_DEVICE_TABLE(of, stm32_match);
126148a6092fSMaxime Coquelin #endif
126248a6092fSMaxime Coquelin 
1263a7770a4bSErwan Le Ray static void stm32_usart_of_dma_rx_remove(struct stm32_port *stm32port,
1264a7770a4bSErwan Le Ray 					 struct platform_device *pdev)
1265a7770a4bSErwan Le Ray {
1266a7770a4bSErwan Le Ray 	if (stm32port->rx_buf)
1267a7770a4bSErwan Le Ray 		dma_free_coherent(&pdev->dev, RX_BUF_L, stm32port->rx_buf,
1268a7770a4bSErwan Le Ray 				  stm32port->rx_dma_buf);
1269a7770a4bSErwan Le Ray }
1270a7770a4bSErwan Le Ray 
127156f9a76cSErwan Le Ray static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port,
127234891872SAlexandre TORGUE 				       struct platform_device *pdev)
127334891872SAlexandre TORGUE {
1274d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
127534891872SAlexandre TORGUE 	struct uart_port *port = &stm32port->port;
127634891872SAlexandre TORGUE 	struct device *dev = &pdev->dev;
127734891872SAlexandre TORGUE 	struct dma_slave_config config;
127834891872SAlexandre TORGUE 	struct dma_async_tx_descriptor *desc = NULL;
127934891872SAlexandre TORGUE 	int ret;
128034891872SAlexandre TORGUE 
1281e359b441SJohan Hovold 	/*
1282e359b441SJohan Hovold 	 * Using DMA and threaded handler for the console could lead to
1283e359b441SJohan Hovold 	 * deadlocks.
1284e359b441SJohan Hovold 	 */
1285e359b441SJohan Hovold 	if (uart_console(port))
1286e359b441SJohan Hovold 		return -ENODEV;
1287e359b441SJohan Hovold 
128859bd4eedSTang Bin 	stm32port->rx_buf = dma_alloc_coherent(dev, RX_BUF_L,
128934891872SAlexandre TORGUE 					       &stm32port->rx_dma_buf,
129034891872SAlexandre TORGUE 					       GFP_KERNEL);
1291a7770a4bSErwan Le Ray 	if (!stm32port->rx_buf)
1292a7770a4bSErwan Le Ray 		return -ENOMEM;
129334891872SAlexandre TORGUE 
129434891872SAlexandre TORGUE 	/* Configure DMA channel */
129534891872SAlexandre TORGUE 	memset(&config, 0, sizeof(config));
12968e5481d9SArnd Bergmann 	config.src_addr = port->mapbase + ofs->rdr;
129734891872SAlexandre TORGUE 	config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
129834891872SAlexandre TORGUE 
129934891872SAlexandre TORGUE 	ret = dmaengine_slave_config(stm32port->rx_ch, &config);
130034891872SAlexandre TORGUE 	if (ret < 0) {
130134891872SAlexandre TORGUE 		dev_err(dev, "rx dma channel config failed\n");
1302a7770a4bSErwan Le Ray 		stm32_usart_of_dma_rx_remove(stm32port, pdev);
1303a7770a4bSErwan Le Ray 		return ret;
130434891872SAlexandre TORGUE 	}
130534891872SAlexandre TORGUE 
130634891872SAlexandre TORGUE 	/* Prepare a DMA cyclic transaction */
130734891872SAlexandre TORGUE 	desc = dmaengine_prep_dma_cyclic(stm32port->rx_ch,
130834891872SAlexandre TORGUE 					 stm32port->rx_dma_buf,
130934891872SAlexandre TORGUE 					 RX_BUF_L, RX_BUF_P, DMA_DEV_TO_MEM,
131034891872SAlexandre TORGUE 					 DMA_PREP_INTERRUPT);
131134891872SAlexandre TORGUE 	if (!desc) {
131234891872SAlexandre TORGUE 		dev_err(dev, "rx dma prep cyclic failed\n");
1313a7770a4bSErwan Le Ray 		stm32_usart_of_dma_rx_remove(stm32port, pdev);
1314a7770a4bSErwan Le Ray 		return -ENODEV;
131534891872SAlexandre TORGUE 	}
131634891872SAlexandre TORGUE 
1317*33bb2f6aSErwan Le Ray 	/* Set DMA callback */
1318*33bb2f6aSErwan Le Ray 	desc->callback = stm32_usart_rx_dma_complete;
1319*33bb2f6aSErwan Le Ray 	desc->callback_param = port;
132034891872SAlexandre TORGUE 
132134891872SAlexandre TORGUE 	/* Push current DMA transaction in the pending queue */
1322e7997f7fSErwan Le Ray 	ret = dma_submit_error(dmaengine_submit(desc));
1323e7997f7fSErwan Le Ray 	if (ret) {
1324e7997f7fSErwan Le Ray 		dmaengine_terminate_sync(stm32port->rx_ch);
1325a7770a4bSErwan Le Ray 		stm32_usart_of_dma_rx_remove(stm32port, pdev);
1326a7770a4bSErwan Le Ray 		return ret;
1327e7997f7fSErwan Le Ray 	}
132834891872SAlexandre TORGUE 
132934891872SAlexandre TORGUE 	/* Issue pending DMA requests */
133034891872SAlexandre TORGUE 	dma_async_issue_pending(stm32port->rx_ch);
133134891872SAlexandre TORGUE 
133234891872SAlexandre TORGUE 	return 0;
1333a7770a4bSErwan Le Ray }
133434891872SAlexandre TORGUE 
1335a7770a4bSErwan Le Ray static void stm32_usart_of_dma_tx_remove(struct stm32_port *stm32port,
1336a7770a4bSErwan Le Ray 					 struct platform_device *pdev)
1337a7770a4bSErwan Le Ray {
1338a7770a4bSErwan Le Ray 	if (stm32port->tx_buf)
1339a7770a4bSErwan Le Ray 		dma_free_coherent(&pdev->dev, TX_BUF_L, stm32port->tx_buf,
1340a7770a4bSErwan Le Ray 				  stm32port->tx_dma_buf);
134134891872SAlexandre TORGUE }
134234891872SAlexandre TORGUE 
134356f9a76cSErwan Le Ray static int stm32_usart_of_dma_tx_probe(struct stm32_port *stm32port,
134434891872SAlexandre TORGUE 				       struct platform_device *pdev)
134534891872SAlexandre TORGUE {
1346d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
134734891872SAlexandre TORGUE 	struct uart_port *port = &stm32port->port;
134834891872SAlexandre TORGUE 	struct device *dev = &pdev->dev;
134934891872SAlexandre TORGUE 	struct dma_slave_config config;
135034891872SAlexandre TORGUE 	int ret;
135134891872SAlexandre TORGUE 
135234891872SAlexandre TORGUE 	stm32port->tx_dma_busy = false;
135334891872SAlexandre TORGUE 
135459bd4eedSTang Bin 	stm32port->tx_buf = dma_alloc_coherent(dev, TX_BUF_L,
135534891872SAlexandre TORGUE 					       &stm32port->tx_dma_buf,
135634891872SAlexandre TORGUE 					       GFP_KERNEL);
1357a7770a4bSErwan Le Ray 	if (!stm32port->tx_buf)
1358a7770a4bSErwan Le Ray 		return -ENOMEM;
135934891872SAlexandre TORGUE 
136034891872SAlexandre TORGUE 	/* Configure DMA channel */
136134891872SAlexandre TORGUE 	memset(&config, 0, sizeof(config));
13628e5481d9SArnd Bergmann 	config.dst_addr = port->mapbase + ofs->tdr;
136334891872SAlexandre TORGUE 	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
136434891872SAlexandre TORGUE 
136534891872SAlexandre TORGUE 	ret = dmaengine_slave_config(stm32port->tx_ch, &config);
136634891872SAlexandre TORGUE 	if (ret < 0) {
136734891872SAlexandre TORGUE 		dev_err(dev, "tx dma channel config failed\n");
1368a7770a4bSErwan Le Ray 		stm32_usart_of_dma_tx_remove(stm32port, pdev);
1369a7770a4bSErwan Le Ray 		return ret;
137034891872SAlexandre TORGUE 	}
137134891872SAlexandre TORGUE 
137234891872SAlexandre TORGUE 	return 0;
137334891872SAlexandre TORGUE }
137434891872SAlexandre TORGUE 
137556f9a76cSErwan Le Ray static int stm32_usart_serial_probe(struct platform_device *pdev)
137648a6092fSMaxime Coquelin {
137748a6092fSMaxime Coquelin 	struct stm32_port *stm32port;
1378ada8618fSAlexandre TORGUE 	int ret;
137948a6092fSMaxime Coquelin 
138056f9a76cSErwan Le Ray 	stm32port = stm32_usart_of_get_port(pdev);
138148a6092fSMaxime Coquelin 	if (!stm32port)
138248a6092fSMaxime Coquelin 		return -ENODEV;
138348a6092fSMaxime Coquelin 
1384d825f0beSStephen Boyd 	stm32port->info = of_device_get_match_data(&pdev->dev);
1385d825f0beSStephen Boyd 	if (!stm32port->info)
1386ada8618fSAlexandre TORGUE 		return -EINVAL;
1387ada8618fSAlexandre TORGUE 
138856f9a76cSErwan Le Ray 	ret = stm32_usart_init_port(stm32port, pdev);
138948a6092fSMaxime Coquelin 	if (ret)
139048a6092fSMaxime Coquelin 		return ret;
139148a6092fSMaxime Coquelin 
13923d530017SAlexandre Torgue 	if (stm32port->wakeup_src) {
13933d530017SAlexandre Torgue 		device_set_wakeup_capable(&pdev->dev, true);
13943d530017SAlexandre Torgue 		ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
13955297f274SErwan Le Ray 		if (ret)
1396a7770a4bSErwan Le Ray 			goto err_deinit_port;
1397270e5a74SFabrice Gasnier 	}
1398270e5a74SFabrice Gasnier 
1399a7770a4bSErwan Le Ray 	stm32port->rx_ch = dma_request_chan(&pdev->dev, "rx");
1400a7770a4bSErwan Le Ray 	if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER) {
1401a7770a4bSErwan Le Ray 		ret = -EPROBE_DEFER;
1402a7770a4bSErwan Le Ray 		goto err_wakeirq;
1403a7770a4bSErwan Le Ray 	}
1404a7770a4bSErwan Le Ray 	/* Fall back in interrupt mode for any non-deferral error */
1405a7770a4bSErwan Le Ray 	if (IS_ERR(stm32port->rx_ch))
1406a7770a4bSErwan Le Ray 		stm32port->rx_ch = NULL;
140734891872SAlexandre TORGUE 
1408a7770a4bSErwan Le Ray 	stm32port->tx_ch = dma_request_chan(&pdev->dev, "tx");
1409a7770a4bSErwan Le Ray 	if (PTR_ERR(stm32port->tx_ch) == -EPROBE_DEFER) {
1410a7770a4bSErwan Le Ray 		ret = -EPROBE_DEFER;
1411a7770a4bSErwan Le Ray 		goto err_dma_rx;
1412a7770a4bSErwan Le Ray 	}
1413a7770a4bSErwan Le Ray 	/* Fall back in interrupt mode for any non-deferral error */
1414a7770a4bSErwan Le Ray 	if (IS_ERR(stm32port->tx_ch))
1415a7770a4bSErwan Le Ray 		stm32port->tx_ch = NULL;
1416a7770a4bSErwan Le Ray 
1417a7770a4bSErwan Le Ray 	if (stm32port->rx_ch && stm32_usart_of_dma_rx_probe(stm32port, pdev)) {
1418a7770a4bSErwan Le Ray 		/* Fall back in interrupt mode */
1419a7770a4bSErwan Le Ray 		dma_release_channel(stm32port->rx_ch);
1420a7770a4bSErwan Le Ray 		stm32port->rx_ch = NULL;
1421a7770a4bSErwan Le Ray 	}
1422a7770a4bSErwan Le Ray 
1423a7770a4bSErwan Le Ray 	if (stm32port->tx_ch && stm32_usart_of_dma_tx_probe(stm32port, pdev)) {
1424a7770a4bSErwan Le Ray 		/* Fall back in interrupt mode */
1425a7770a4bSErwan Le Ray 		dma_release_channel(stm32port->tx_ch);
1426a7770a4bSErwan Le Ray 		stm32port->tx_ch = NULL;
1427a7770a4bSErwan Le Ray 	}
1428a7770a4bSErwan Le Ray 
1429a7770a4bSErwan Le Ray 	if (!stm32port->rx_ch)
1430a7770a4bSErwan Le Ray 		dev_info(&pdev->dev, "interrupt mode for rx (no dma)\n");
1431a7770a4bSErwan Le Ray 	if (!stm32port->tx_ch)
1432a7770a4bSErwan Le Ray 		dev_info(&pdev->dev, "interrupt mode for tx (no dma)\n");
143334891872SAlexandre TORGUE 
143448a6092fSMaxime Coquelin 	platform_set_drvdata(pdev, &stm32port->port);
143548a6092fSMaxime Coquelin 
1436fb6dcef6SErwan Le Ray 	pm_runtime_get_noresume(&pdev->dev);
1437fb6dcef6SErwan Le Ray 	pm_runtime_set_active(&pdev->dev);
1438fb6dcef6SErwan Le Ray 	pm_runtime_enable(&pdev->dev);
143987fd0741SErwan Le Ray 
144087fd0741SErwan Le Ray 	ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port);
144187fd0741SErwan Le Ray 	if (ret)
144287fd0741SErwan Le Ray 		goto err_port;
144387fd0741SErwan Le Ray 
1444fb6dcef6SErwan Le Ray 	pm_runtime_put_sync(&pdev->dev);
1445fb6dcef6SErwan Le Ray 
144648a6092fSMaxime Coquelin 	return 0;
1447ada80043SFabrice Gasnier 
144887fd0741SErwan Le Ray err_port:
144987fd0741SErwan Le Ray 	pm_runtime_disable(&pdev->dev);
145087fd0741SErwan Le Ray 	pm_runtime_set_suspended(&pdev->dev);
145187fd0741SErwan Le Ray 	pm_runtime_put_noidle(&pdev->dev);
145287fd0741SErwan Le Ray 
145387fd0741SErwan Le Ray 	if (stm32port->tx_ch) {
1454a7770a4bSErwan Le Ray 		stm32_usart_of_dma_tx_remove(stm32port, pdev);
145587fd0741SErwan Le Ray 		dma_release_channel(stm32port->tx_ch);
145687fd0741SErwan Le Ray 	}
145787fd0741SErwan Le Ray 
1458a7770a4bSErwan Le Ray 	if (stm32port->rx_ch)
1459a7770a4bSErwan Le Ray 		stm32_usart_of_dma_rx_remove(stm32port, pdev);
146087fd0741SErwan Le Ray 
1461a7770a4bSErwan Le Ray err_dma_rx:
1462a7770a4bSErwan Le Ray 	if (stm32port->rx_ch)
1463a7770a4bSErwan Le Ray 		dma_release_channel(stm32port->rx_ch);
1464a7770a4bSErwan Le Ray 
1465a7770a4bSErwan Le Ray err_wakeirq:
14663d530017SAlexandre Torgue 	if (stm32port->wakeup_src)
14675297f274SErwan Le Ray 		dev_pm_clear_wake_irq(&pdev->dev);
14685297f274SErwan Le Ray 
1469a7770a4bSErwan Le Ray err_deinit_port:
14703d530017SAlexandre Torgue 	if (stm32port->wakeup_src)
14713d530017SAlexandre Torgue 		device_set_wakeup_capable(&pdev->dev, false);
1472270e5a74SFabrice Gasnier 
147397f3a085SErwan Le Ray 	stm32_usart_deinit_port(stm32port);
1474ada80043SFabrice Gasnier 
1475ada80043SFabrice Gasnier 	return ret;
147648a6092fSMaxime Coquelin }
147748a6092fSMaxime Coquelin 
147856f9a76cSErwan Le Ray static int stm32_usart_serial_remove(struct platform_device *pdev)
147948a6092fSMaxime Coquelin {
148048a6092fSMaxime Coquelin 	struct uart_port *port = platform_get_drvdata(pdev);
1481511c7b1bSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
1482d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
1483fb6dcef6SErwan Le Ray 	int err;
1484*33bb2f6aSErwan Le Ray 	u32 cr3;
1485fb6dcef6SErwan Le Ray 
1486fb6dcef6SErwan Le Ray 	pm_runtime_get_sync(&pdev->dev);
148787fd0741SErwan Le Ray 	err = uart_remove_one_port(&stm32_usart_driver, port);
148887fd0741SErwan Le Ray 	if (err)
148987fd0741SErwan Le Ray 		return(err);
149087fd0741SErwan Le Ray 
149187fd0741SErwan Le Ray 	pm_runtime_disable(&pdev->dev);
149287fd0741SErwan Le Ray 	pm_runtime_set_suspended(&pdev->dev);
149387fd0741SErwan Le Ray 	pm_runtime_put_noidle(&pdev->dev);
149434891872SAlexandre TORGUE 
1495*33bb2f6aSErwan Le Ray 	stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_PEIE);
1496*33bb2f6aSErwan Le Ray 	cr3 = readl_relaxed(port->membase + ofs->cr3);
1497*33bb2f6aSErwan Le Ray 	cr3 &= ~USART_CR3_EIE;
1498*33bb2f6aSErwan Le Ray 	cr3 &= ~USART_CR3_DMAR;
1499*33bb2f6aSErwan Le Ray 	cr3 &= ~USART_CR3_DDRE;
1500*33bb2f6aSErwan Le Ray 	writel_relaxed(cr3, port->membase + ofs->cr3);
150134891872SAlexandre TORGUE 
150287fd0741SErwan Le Ray 	if (stm32_port->tx_ch) {
150387fd0741SErwan Le Ray 		dmaengine_terminate_async(stm32_port->tx_ch);
1504a7770a4bSErwan Le Ray 		stm32_usart_of_dma_tx_remove(stm32_port, pdev);
150534891872SAlexandre TORGUE 		dma_release_channel(stm32_port->tx_ch);
150687fd0741SErwan Le Ray 	}
150734891872SAlexandre TORGUE 
1508a7770a4bSErwan Le Ray 	if (stm32_port->rx_ch) {
1509a7770a4bSErwan Le Ray 		dmaengine_terminate_async(stm32_port->rx_ch);
1510a7770a4bSErwan Le Ray 		stm32_usart_of_dma_rx_remove(stm32_port, pdev);
1511a7770a4bSErwan Le Ray 		dma_release_channel(stm32_port->rx_ch);
1512a7770a4bSErwan Le Ray 	}
1513a7770a4bSErwan Le Ray 
1514a7770a4bSErwan Le Ray 	stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
1515511c7b1bSAlexandre TORGUE 
15163d530017SAlexandre Torgue 	if (stm32_port->wakeup_src) {
15175297f274SErwan Le Ray 		dev_pm_clear_wake_irq(&pdev->dev);
1518270e5a74SFabrice Gasnier 		device_init_wakeup(&pdev->dev, false);
15195297f274SErwan Le Ray 	}
1520270e5a74SFabrice Gasnier 
152197f3a085SErwan Le Ray 	stm32_usart_deinit_port(stm32_port);
152248a6092fSMaxime Coquelin 
152387fd0741SErwan Le Ray 	return 0;
152448a6092fSMaxime Coquelin }
152548a6092fSMaxime Coquelin 
152648a6092fSMaxime Coquelin #ifdef CONFIG_SERIAL_STM32_CONSOLE
152756f9a76cSErwan Le Ray static void stm32_usart_console_putchar(struct uart_port *port, int ch)
152848a6092fSMaxime Coquelin {
1529ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
1530d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
1531ada8618fSAlexandre TORGUE 
1532ada8618fSAlexandre TORGUE 	while (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE))
153348a6092fSMaxime Coquelin 		cpu_relax();
153448a6092fSMaxime Coquelin 
1535ada8618fSAlexandre TORGUE 	writel_relaxed(ch, port->membase + ofs->tdr);
153648a6092fSMaxime Coquelin }
153748a6092fSMaxime Coquelin 
153856f9a76cSErwan Le Ray static void stm32_usart_console_write(struct console *co, const char *s,
153992fc0023SErwan Le Ray 				      unsigned int cnt)
154048a6092fSMaxime Coquelin {
154148a6092fSMaxime Coquelin 	struct uart_port *port = &stm32_ports[co->index].port;
1542ada8618fSAlexandre TORGUE 	struct stm32_port *stm32_port = to_stm32_port(port);
1543d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
1544d825f0beSStephen Boyd 	const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
154548a6092fSMaxime Coquelin 	unsigned long flags;
154648a6092fSMaxime Coquelin 	u32 old_cr1, new_cr1;
154748a6092fSMaxime Coquelin 	int locked = 1;
154848a6092fSMaxime Coquelin 
1549cea37afdSJohan Hovold 	if (oops_in_progress)
1550cea37afdSJohan Hovold 		locked = spin_trylock_irqsave(&port->lock, flags);
155148a6092fSMaxime Coquelin 	else
1552cea37afdSJohan Hovold 		spin_lock_irqsave(&port->lock, flags);
155348a6092fSMaxime Coquelin 
155487f1f809SAlexandre TORGUE 	/* Save and disable interrupts, enable the transmitter */
1555ada8618fSAlexandre TORGUE 	old_cr1 = readl_relaxed(port->membase + ofs->cr1);
155648a6092fSMaxime Coquelin 	new_cr1 = old_cr1 & ~USART_CR1_IE_MASK;
155787f1f809SAlexandre TORGUE 	new_cr1 |=  USART_CR1_TE | BIT(cfg->uart_enable_bit);
1558ada8618fSAlexandre TORGUE 	writel_relaxed(new_cr1, port->membase + ofs->cr1);
155948a6092fSMaxime Coquelin 
156056f9a76cSErwan Le Ray 	uart_console_write(port, s, cnt, stm32_usart_console_putchar);
156148a6092fSMaxime Coquelin 
156248a6092fSMaxime Coquelin 	/* Restore interrupt state */
1563ada8618fSAlexandre TORGUE 	writel_relaxed(old_cr1, port->membase + ofs->cr1);
156448a6092fSMaxime Coquelin 
156548a6092fSMaxime Coquelin 	if (locked)
1566cea37afdSJohan Hovold 		spin_unlock_irqrestore(&port->lock, flags);
156748a6092fSMaxime Coquelin }
156848a6092fSMaxime Coquelin 
156956f9a76cSErwan Le Ray static int stm32_usart_console_setup(struct console *co, char *options)
157048a6092fSMaxime Coquelin {
157148a6092fSMaxime Coquelin 	struct stm32_port *stm32port;
157248a6092fSMaxime Coquelin 	int baud = 9600;
157348a6092fSMaxime Coquelin 	int bits = 8;
157448a6092fSMaxime Coquelin 	int parity = 'n';
157548a6092fSMaxime Coquelin 	int flow = 'n';
157648a6092fSMaxime Coquelin 
157748a6092fSMaxime Coquelin 	if (co->index >= STM32_MAX_PORTS)
157848a6092fSMaxime Coquelin 		return -ENODEV;
157948a6092fSMaxime Coquelin 
158048a6092fSMaxime Coquelin 	stm32port = &stm32_ports[co->index];
158148a6092fSMaxime Coquelin 
158248a6092fSMaxime Coquelin 	/*
158348a6092fSMaxime Coquelin 	 * This driver does not support early console initialization
158448a6092fSMaxime Coquelin 	 * (use ARM early printk support instead), so we only expect
158548a6092fSMaxime Coquelin 	 * this to be called during the uart port registration when the
158648a6092fSMaxime Coquelin 	 * driver gets probed and the port should be mapped at that point.
158748a6092fSMaxime Coquelin 	 */
158892fc0023SErwan Le Ray 	if (stm32port->port.mapbase == 0 || !stm32port->port.membase)
158948a6092fSMaxime Coquelin 		return -ENXIO;
159048a6092fSMaxime Coquelin 
159148a6092fSMaxime Coquelin 	if (options)
159248a6092fSMaxime Coquelin 		uart_parse_options(options, &baud, &parity, &bits, &flow);
159348a6092fSMaxime Coquelin 
159448a6092fSMaxime Coquelin 	return uart_set_options(&stm32port->port, co, baud, parity, bits, flow);
159548a6092fSMaxime Coquelin }
159648a6092fSMaxime Coquelin 
159748a6092fSMaxime Coquelin static struct console stm32_console = {
159848a6092fSMaxime Coquelin 	.name		= STM32_SERIAL_NAME,
159948a6092fSMaxime Coquelin 	.device		= uart_console_device,
160056f9a76cSErwan Le Ray 	.write		= stm32_usart_console_write,
160156f9a76cSErwan Le Ray 	.setup		= stm32_usart_console_setup,
160248a6092fSMaxime Coquelin 	.flags		= CON_PRINTBUFFER,
160348a6092fSMaxime Coquelin 	.index		= -1,
160448a6092fSMaxime Coquelin 	.data		= &stm32_usart_driver,
160548a6092fSMaxime Coquelin };
160648a6092fSMaxime Coquelin 
160748a6092fSMaxime Coquelin #define STM32_SERIAL_CONSOLE (&stm32_console)
160848a6092fSMaxime Coquelin 
160948a6092fSMaxime Coquelin #else
161048a6092fSMaxime Coquelin #define STM32_SERIAL_CONSOLE NULL
161148a6092fSMaxime Coquelin #endif /* CONFIG_SERIAL_STM32_CONSOLE */
161248a6092fSMaxime Coquelin 
161348a6092fSMaxime Coquelin static struct uart_driver stm32_usart_driver = {
161448a6092fSMaxime Coquelin 	.driver_name	= DRIVER_NAME,
161548a6092fSMaxime Coquelin 	.dev_name	= STM32_SERIAL_NAME,
161648a6092fSMaxime Coquelin 	.major		= 0,
161748a6092fSMaxime Coquelin 	.minor		= 0,
161848a6092fSMaxime Coquelin 	.nr		= STM32_MAX_PORTS,
161948a6092fSMaxime Coquelin 	.cons		= STM32_SERIAL_CONSOLE,
162048a6092fSMaxime Coquelin };
162148a6092fSMaxime Coquelin 
162256f9a76cSErwan Le Ray static void __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port,
1623fe94347dSErwan Le Ray 							bool enable)
1624270e5a74SFabrice Gasnier {
1625270e5a74SFabrice Gasnier 	struct stm32_port *stm32_port = to_stm32_port(port);
1626d825f0beSStephen Boyd 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
1627270e5a74SFabrice Gasnier 
16283d530017SAlexandre Torgue 	if (!stm32_port->wakeup_src)
1629270e5a74SFabrice Gasnier 		return;
1630270e5a74SFabrice Gasnier 
163112761869SErwan Le Ray 	/*
163212761869SErwan Le Ray 	 * Enable low-power wake-up and wake-up irq if argument is set to
163312761869SErwan Le Ray 	 * "enable", disable low-power wake-up and wake-up irq otherwise
163412761869SErwan Le Ray 	 */
1635270e5a74SFabrice Gasnier 	if (enable) {
163656f9a76cSErwan Le Ray 		stm32_usart_set_bits(port, ofs->cr1, USART_CR1_UESM);
163712761869SErwan Le Ray 		stm32_usart_set_bits(port, ofs->cr3, USART_CR3_WUFIE);
1638270e5a74SFabrice Gasnier 	} else {
163956f9a76cSErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_UESM);
164012761869SErwan Le Ray 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_WUFIE);
1641270e5a74SFabrice Gasnier 	}
1642270e5a74SFabrice Gasnier }
1643270e5a74SFabrice Gasnier 
164456f9a76cSErwan Le Ray static int __maybe_unused stm32_usart_serial_suspend(struct device *dev)
1645270e5a74SFabrice Gasnier {
1646270e5a74SFabrice Gasnier 	struct uart_port *port = dev_get_drvdata(dev);
1647270e5a74SFabrice Gasnier 
1648270e5a74SFabrice Gasnier 	uart_suspend_port(&stm32_usart_driver, port);
1649270e5a74SFabrice Gasnier 
16501631eeeaSErwan Le Ray 	if (device_may_wakeup(dev) || device_wakeup_path(dev))
165156f9a76cSErwan Le Ray 		stm32_usart_serial_en_wakeup(port, true);
1652270e5a74SFabrice Gasnier 
165355484fccSErwan Le Ray 	/*
165455484fccSErwan Le Ray 	 * When "no_console_suspend" is enabled, keep the pinctrl default state
165555484fccSErwan Le Ray 	 * and rely on bootloader stage to restore this state upon resume.
165655484fccSErwan Le Ray 	 * Otherwise, apply the idle or sleep states depending on wakeup
165755484fccSErwan Le Ray 	 * capabilities.
165855484fccSErwan Le Ray 	 */
165955484fccSErwan Le Ray 	if (console_suspend_enabled || !uart_console(port)) {
16601631eeeaSErwan Le Ray 		if (device_may_wakeup(dev) || device_wakeup_path(dev))
166155484fccSErwan Le Ray 			pinctrl_pm_select_idle_state(dev);
166255484fccSErwan Le Ray 		else
166394616d9aSErwan Le Ray 			pinctrl_pm_select_sleep_state(dev);
166455484fccSErwan Le Ray 	}
166594616d9aSErwan Le Ray 
1666270e5a74SFabrice Gasnier 	return 0;
1667270e5a74SFabrice Gasnier }
1668270e5a74SFabrice Gasnier 
166956f9a76cSErwan Le Ray static int __maybe_unused stm32_usart_serial_resume(struct device *dev)
1670270e5a74SFabrice Gasnier {
1671270e5a74SFabrice Gasnier 	struct uart_port *port = dev_get_drvdata(dev);
1672270e5a74SFabrice Gasnier 
167394616d9aSErwan Le Ray 	pinctrl_pm_select_default_state(dev);
167494616d9aSErwan Le Ray 
16751631eeeaSErwan Le Ray 	if (device_may_wakeup(dev) || device_wakeup_path(dev))
167656f9a76cSErwan Le Ray 		stm32_usart_serial_en_wakeup(port, false);
1677270e5a74SFabrice Gasnier 
1678270e5a74SFabrice Gasnier 	return uart_resume_port(&stm32_usart_driver, port);
1679270e5a74SFabrice Gasnier }
1680270e5a74SFabrice Gasnier 
168156f9a76cSErwan Le Ray static int __maybe_unused stm32_usart_runtime_suspend(struct device *dev)
1682fb6dcef6SErwan Le Ray {
1683fb6dcef6SErwan Le Ray 	struct uart_port *port = dev_get_drvdata(dev);
1684fb6dcef6SErwan Le Ray 	struct stm32_port *stm32port = container_of(port,
1685fb6dcef6SErwan Le Ray 			struct stm32_port, port);
1686fb6dcef6SErwan Le Ray 
1687fb6dcef6SErwan Le Ray 	clk_disable_unprepare(stm32port->clk);
1688fb6dcef6SErwan Le Ray 
1689fb6dcef6SErwan Le Ray 	return 0;
1690fb6dcef6SErwan Le Ray }
1691fb6dcef6SErwan Le Ray 
169256f9a76cSErwan Le Ray static int __maybe_unused stm32_usart_runtime_resume(struct device *dev)
1693fb6dcef6SErwan Le Ray {
1694fb6dcef6SErwan Le Ray 	struct uart_port *port = dev_get_drvdata(dev);
1695fb6dcef6SErwan Le Ray 	struct stm32_port *stm32port = container_of(port,
1696fb6dcef6SErwan Le Ray 			struct stm32_port, port);
1697fb6dcef6SErwan Le Ray 
1698fb6dcef6SErwan Le Ray 	return clk_prepare_enable(stm32port->clk);
1699fb6dcef6SErwan Le Ray }
1700fb6dcef6SErwan Le Ray 
1701270e5a74SFabrice Gasnier static const struct dev_pm_ops stm32_serial_pm_ops = {
170256f9a76cSErwan Le Ray 	SET_RUNTIME_PM_OPS(stm32_usart_runtime_suspend,
170356f9a76cSErwan Le Ray 			   stm32_usart_runtime_resume, NULL)
170456f9a76cSErwan Le Ray 	SET_SYSTEM_SLEEP_PM_OPS(stm32_usart_serial_suspend,
170556f9a76cSErwan Le Ray 				stm32_usart_serial_resume)
1706270e5a74SFabrice Gasnier };
1707270e5a74SFabrice Gasnier 
170848a6092fSMaxime Coquelin static struct platform_driver stm32_serial_driver = {
170956f9a76cSErwan Le Ray 	.probe		= stm32_usart_serial_probe,
171056f9a76cSErwan Le Ray 	.remove		= stm32_usart_serial_remove,
171148a6092fSMaxime Coquelin 	.driver	= {
171248a6092fSMaxime Coquelin 		.name	= DRIVER_NAME,
1713270e5a74SFabrice Gasnier 		.pm	= &stm32_serial_pm_ops,
171448a6092fSMaxime Coquelin 		.of_match_table = of_match_ptr(stm32_match),
171548a6092fSMaxime Coquelin 	},
171648a6092fSMaxime Coquelin };
171748a6092fSMaxime Coquelin 
171856f9a76cSErwan Le Ray static int __init stm32_usart_init(void)
171948a6092fSMaxime Coquelin {
172048a6092fSMaxime Coquelin 	static char banner[] __initdata = "STM32 USART driver initialized";
172148a6092fSMaxime Coquelin 	int ret;
172248a6092fSMaxime Coquelin 
172348a6092fSMaxime Coquelin 	pr_info("%s\n", banner);
172448a6092fSMaxime Coquelin 
172548a6092fSMaxime Coquelin 	ret = uart_register_driver(&stm32_usart_driver);
172648a6092fSMaxime Coquelin 	if (ret)
172748a6092fSMaxime Coquelin 		return ret;
172848a6092fSMaxime Coquelin 
172948a6092fSMaxime Coquelin 	ret = platform_driver_register(&stm32_serial_driver);
173048a6092fSMaxime Coquelin 	if (ret)
173148a6092fSMaxime Coquelin 		uart_unregister_driver(&stm32_usart_driver);
173248a6092fSMaxime Coquelin 
173348a6092fSMaxime Coquelin 	return ret;
173448a6092fSMaxime Coquelin }
173548a6092fSMaxime Coquelin 
173656f9a76cSErwan Le Ray static void __exit stm32_usart_exit(void)
173748a6092fSMaxime Coquelin {
173848a6092fSMaxime Coquelin 	platform_driver_unregister(&stm32_serial_driver);
173948a6092fSMaxime Coquelin 	uart_unregister_driver(&stm32_usart_driver);
174048a6092fSMaxime Coquelin }
174148a6092fSMaxime Coquelin 
174256f9a76cSErwan Le Ray module_init(stm32_usart_init);
174356f9a76cSErwan Le Ray module_exit(stm32_usart_exit);
174448a6092fSMaxime Coquelin 
174548a6092fSMaxime Coquelin MODULE_ALIAS("platform:" DRIVER_NAME);
174648a6092fSMaxime Coquelin MODULE_DESCRIPTION("STMicroelectronics STM32 serial port driver");
174748a6092fSMaxime Coquelin MODULE_LICENSE("GPL v2");
1748