Commit 3bcea529 authored by Marek Vasut's avatar Marek Vasut Committed by Greg Kroah-Hartman
Browse files

serial: stm32: Factor out GPIO RTS toggling into separate function



Pull out the GPIO RTS enable and disable handling into separate function.
Limit the scope of GPIO RTS toggling only to GPIO emulated RS485 too.

Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Erwan Le Ray <erwan.leray@foss.st.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jean Philippe Romain <jean-philippe.romain@foss.st.com>
Cc: Valentin Caron <valentin.caron@foss.st.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
To: linux-serial@vger.kernel.org
Link: https://lore.kernel.org/r/20220430162845.244655-1-marex@denx.de


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4487cd3e
Loading
Loading
Loading
Loading
+38 −21
Original line number Diff line number Diff line
@@ -442,6 +442,42 @@ static void stm32_usart_tx_interrupt_disable(struct uart_port *port)
		stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
}

static void stm32_usart_rs485_rts_enable(struct uart_port *port)
{
	struct stm32_port *stm32_port = to_stm32_port(port);
	struct serial_rs485 *rs485conf = &port->rs485;

	if (stm32_port->hw_flow_control ||
	    !(rs485conf->flags & SER_RS485_ENABLED))
		return;

	if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
		mctrl_gpio_set(stm32_port->gpios,
			       stm32_port->port.mctrl | TIOCM_RTS);
	} else {
		mctrl_gpio_set(stm32_port->gpios,
			       stm32_port->port.mctrl & ~TIOCM_RTS);
	}
}

static void stm32_usart_rs485_rts_disable(struct uart_port *port)
{
	struct stm32_port *stm32_port = to_stm32_port(port);
	struct serial_rs485 *rs485conf = &port->rs485;

	if (stm32_port->hw_flow_control ||
	    !(rs485conf->flags & SER_RS485_ENABLED))
		return;

	if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
		mctrl_gpio_set(stm32_port->gpios,
			       stm32_port->port.mctrl & ~TIOCM_RTS);
	} else {
		mctrl_gpio_set(stm32_port->gpios,
			       stm32_port->port.mctrl | TIOCM_RTS);
	}
}

static void stm32_usart_transmit_chars_pio(struct uart_port *port)
{
	struct stm32_port *stm32_port = to_stm32_port(port);
@@ -713,43 +749,24 @@ static void stm32_usart_disable_ms(struct uart_port *port)
static void stm32_usart_stop_tx(struct uart_port *port)
{
	struct stm32_port *stm32_port = to_stm32_port(port);
	struct serial_rs485 *rs485conf = &port->rs485;
	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;

	stm32_usart_tx_interrupt_disable(port);
	if (stm32_usart_tx_dma_started(stm32_port) && stm32_usart_tx_dma_enabled(stm32_port))
		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);

	if (rs485conf->flags & SER_RS485_ENABLED) {
		if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
			mctrl_gpio_set(stm32_port->gpios,
					stm32_port->port.mctrl & ~TIOCM_RTS);
		} else {
			mctrl_gpio_set(stm32_port->gpios,
					stm32_port->port.mctrl | TIOCM_RTS);
		}
	}
	stm32_usart_rs485_rts_disable(port);
}

/* There are probably characters waiting to be transmitted. */
static void stm32_usart_start_tx(struct uart_port *port)
{
	struct stm32_port *stm32_port = to_stm32_port(port);
	struct serial_rs485 *rs485conf = &port->rs485;
	struct circ_buf *xmit = &port->state->xmit;

	if (uart_circ_empty(xmit) && !port->x_char)
		return;

	if (rs485conf->flags & SER_RS485_ENABLED) {
		if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
			mctrl_gpio_set(stm32_port->gpios,
					stm32_port->port.mctrl | TIOCM_RTS);
		} else {
			mctrl_gpio_set(stm32_port->gpios,
					stm32_port->port.mctrl & ~TIOCM_RTS);
		}
	}
	stm32_usart_rs485_rts_enable(port);

	stm32_usart_transmit_chars(port);
}