#include <linux/tty_flip.h>
#include <linux/tty.h>
+#include "serial_mctrl_gpio.h"
#include "stm32-usart.h"
static void stm32_stop_tx(struct uart_port *port);
stm32_set_bits(port, ofs->cr3, USART_CR3_RTSE);
else
stm32_clr_bits(port, ofs->cr3, USART_CR3_RTSE);
+
+ mctrl_gpio_set(stm32_port->gpios, mctrl);
}
static unsigned int stm32_get_mctrl(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ unsigned int ret;
+
/* This routine is used to get signals of: DCD, DSR, RI, and CTS */
- return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+ ret = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+
+ return mctrl_gpio_get(stm32_port->gpios, &ret);
+}
+
+static void stm32_enable_ms(struct uart_port *port)
+{
+ mctrl_gpio_enable_ms(to_stm32_port(port)->gpios);
+}
+
+static void stm32_disable_ms(struct uart_port *port)
+{
+ mctrl_gpio_disable_ms(to_stm32_port(port)->gpios);
}
/* Transmit stop */
u32 val, isr;
int ret;
+ /* Disable modem control interrupts */
+ stm32_disable_ms(port);
+
val = USART_CR1_TXEIE | USART_CR1_TE;
val |= stm32_port->cr1_irq | USART_CR1_RE;
val |= BIT(cfg->uart_enable_bit);
cr3 |= USART_CR3_CTSE | USART_CR3_RTSE;
}
+ /* Handle modem control interrupts */
+ if (UART_ENABLE_MS(port, termios->c_cflag))
+ stm32_enable_ms(port);
+ else
+ stm32_disable_ms(port);
+
usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
/*
.throttle = stm32_throttle,
.unthrottle = stm32_unthrottle,
.stop_rx = stm32_stop_rx,
+ .enable_ms = stm32_enable_ms,
.break_ctl = stm32_break_ctl,
.startup = stm32_startup,
.shutdown = stm32_shutdown,
stm32port->port.uartclk = clk_get_rate(stm32port->clk);
if (!stm32port->port.uartclk) {
- clk_disable_unprepare(stm32port->clk);
ret = -EINVAL;
+ goto err_clk;
+ }
+
+ stm32port->gpios = mctrl_gpio_init(&stm32port->port, 0);
+ if (IS_ERR(stm32port->gpios)) {
+ ret = PTR_ERR(stm32port->gpios);
+ goto err_clk;
}
+ /* Both CTS/RTS gpios and "st,hw-flow-ctrl" should not be specified */
+ if (stm32port->hw_flow_control) {
+ if (mctrl_gpio_to_gpiod(stm32port->gpios, UART_GPIO_CTS) ||
+ mctrl_gpio_to_gpiod(stm32port->gpios, UART_GPIO_RTS)) {
+ dev_err(&pdev->dev, "Conflicting RTS/CTS config\n");
+ ret = -EINVAL;
+ goto err_clk;
+ }
+ }
+
+ return ret;
+
+err_clk:
+ clk_disable_unprepare(stm32port->clk);
+
return ret;
}