linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Add software flow control support for STM32 UART
@ 2020-04-12 18:09 mani
  2020-04-12 18:09 ` [PATCH 1/2] dt-bindings: serial: Add binding for software flow control in " mani
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: mani @ 2020-04-12 18:09 UTC (permalink / raw)
  To: gregkh, robh+dt, mcoquelin.stm32, alexandre.torgue
  Cc: linux-serial, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Manivannan Sadhasivam

From: Manivannan Sadhasivam <mani@kernel.org>

Hello,

This patchset adds software flow control support for STM32 UART controller.
This is necessary for the upcoming STM32MP1 based board called Stinger96
IoT-Box. On that board, a bluetooth chip is connected to one of the UART
controller but the CTS/RTS lines got swapped mistakenly. So in order to
workaround that hardware bug and also to support the usecase of using only
Tx/Rx pins, this patchset adds software flow control support.

This patchset has been validated w/ Stinger96 IoT-Box connected to Murata
WiFi-BT combo chip.

Thanks,
Mani

Manivannan Sadhasivam (2):
  dt-bindings: serial: Add binding for software flow control in STM32
    UART
  tty: serial: Add software flow control support for STM32 USART

 .../bindings/serial/st,stm32-uart.yaml        |  15 +-
 drivers/tty/serial/stm32-usart.c              | 143 +++++++++++++++++-
 drivers/tty/serial/stm32-usart.h              |   4 +
 3 files changed, 155 insertions(+), 7 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] dt-bindings: serial: Add binding for software flow control in STM32 UART
  2020-04-12 18:09 [PATCH 0/2] Add software flow control support for STM32 UART mani
@ 2020-04-12 18:09 ` mani
  2020-04-12 18:09 ` [PATCH 2/2] tty: serial: Add software flow control support for STM32 USART mani
  2020-04-13  9:17 ` [PATCH 0/2] Add software flow control support for STM32 UART Andy Shevchenko
  2 siblings, 0 replies; 5+ messages in thread
From: mani @ 2020-04-12 18:09 UTC (permalink / raw)
  To: gregkh, robh+dt, mcoquelin.stm32, alexandre.torgue
  Cc: linux-serial, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Manivannan Sadhasivam

From: Manivannan Sadhasivam <mani@kernel.org>

Add devicetree binding for software flow control in STM32 UART
controller. While at it, let's also fix one schema error reported by
`make dtbs_check`.

Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
---

Rob: Still the `dtbs_check` validation fails. This is due to the
`linux,rs485-enabled-at-boot-time` property. I don't have any idea on how
to fix this.

 .../devicetree/bindings/serial/st,stm32-uart.yaml | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml b/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml
index 238c44192d31..ea5797a1b403 100644
--- a/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml
@@ -38,13 +38,26 @@ properties:
     description: enable hardware flow control
     $ref: /schemas/types.yaml#/definitions/flag
 
+  st,sw-flow-ctrl:
+    description: enable software flow control
+    $ref: /schemas/types.yaml#/definitions/flag
+
+  rts-gpios:
+    description: RTS pin used if st,sw-flow-ctrl is true
+    maxItems: 1
+
+  cts-gpios:
+    description: CTS pin used if st,sw-flow-ctrl is true
+    maxItems: 1
+
   dmas:
     minItems: 1
     maxItems: 2
 
   dma-names:
     items:
-      enum: [ rx, tx ]
+      - const: rx
+      - const: tx
     minItems: 1
     maxItems: 2
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] tty: serial: Add software flow control support for STM32 USART
  2020-04-12 18:09 [PATCH 0/2] Add software flow control support for STM32 UART mani
  2020-04-12 18:09 ` [PATCH 1/2] dt-bindings: serial: Add binding for software flow control in " mani
@ 2020-04-12 18:09 ` mani
  2020-04-13  9:17 ` [PATCH 0/2] Add software flow control support for STM32 UART Andy Shevchenko
  2 siblings, 0 replies; 5+ messages in thread
From: mani @ 2020-04-12 18:09 UTC (permalink / raw)
  To: gregkh, robh+dt, mcoquelin.stm32, alexandre.torgue
  Cc: linux-serial, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Manivannan Sadhasivam

From: Manivannan Sadhasivam <mani@kernel.org>

Add software flow control support for STM32 USART controller. This could
be useful when the hardware RTS/CTS pins are not available in the
design.

Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
---
 drivers/tty/serial/stm32-usart.c | 143 +++++++++++++++++++++++++++++--
 drivers/tty/serial/stm32-usart.h |   4 +
 2 files changed, 141 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 5e93e8d40f59..f8adc108ae19 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -19,6 +19,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
@@ -94,6 +95,20 @@ static void stm32_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE,
 	*cr1 |= rs485_deat_dedt;
 }
 
+static irqreturn_t stm32_cts_handler(int irq, void *dev_id)
+{
+	struct stm32_port *stm32port = (struct stm32_port *)dev_id;
+	struct uart_port *port = &stm32port->port;
+
+	spin_lock(&port->lock);
+	if (gpio_is_valid(stm32port->cts_gpio) && stm32port->ms_enabled)
+		uart_handle_cts_change(port,
+				!gpio_get_value(stm32port->cts_gpio));
+	spin_unlock(&port->lock);
+
+	return IRQ_HANDLED;
+}
+
 static int stm32_config_rs485(struct uart_port *port,
 			      struct serial_rs485 *rs485conf)
 {
@@ -506,16 +521,39 @@ static void stm32_set_mctrl(struct uart_port *port, unsigned int mctrl)
 	struct stm32_port *stm32_port = to_stm32_port(port);
 	struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 
-	if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
-		stm32_set_bits(port, ofs->cr3, USART_CR3_RTSE);
-	else
-		stm32_clr_bits(port, ofs->cr3, USART_CR3_RTSE);
+	if (stm32_port->hw_flow_control) {
+		if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
+			stm32_set_bits(port, ofs->cr3, USART_CR3_RTSE);
+		else
+			stm32_clr_bits(port, ofs->cr3, USART_CR3_RTSE);
+	} else if (stm32_port->sw_flow_control) {
+		if ((mctrl & TIOCM_RTS))
+			gpio_set_value(stm32_port->rts_gpio, 0);
+		else
+			gpio_set_value(stm32_port->rts_gpio, 1);
+	}
 }
 
+/* This routine is used to get signals of: DCD, DSR, RI, and CTS */
 static unsigned int stm32_get_mctrl(struct uart_port *port)
 {
-	/* This routine is used to get signals of: DCD, DSR, RI, and CTS */
+	struct stm32_port *stm32_port = to_stm32_port(port);
+
+	if (!stm32_port->ms_enabled)
+		goto cts_asserted;
+
+	if (stm32_port->sw_flow_control) {
+		if (!gpio_get_value(stm32_port->cts_gpio))
+			goto cts_asserted;
+		else
+			goto cts_deasserted;
+	}
+
+cts_asserted:
 	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+
+cts_deasserted:
+	return TIOCM_CAR | TIOCM_DSR;
 }
 
 /* Transmit stop */
@@ -582,6 +620,28 @@ static void stm32_break_ctl(struct uart_port *port, int break_state)
 {
 }
 
+static void stm32_enable_ms(struct uart_port *port)
+{
+	struct stm32_port *stm32_port = to_stm32_port(port);
+
+	if (!stm32_port->sw_flow_control)
+		return;
+
+	stm32_port->ms_enabled = true;
+	enable_irq(gpio_to_irq(stm32_port->cts_gpio));
+}
+
+static void stm32_disable_ms(struct uart_port *port)
+{
+	struct stm32_port *stm32_port = to_stm32_port(port);
+
+	if (!stm32_port->sw_flow_control)
+		return;
+
+	stm32_port->ms_enabled = false;
+	disable_irq(gpio_to_irq(stm32_port->cts_gpio));
+}
+
 static int stm32_startup(struct uart_port *port)
 {
 	struct stm32_port *stm32_port = to_stm32_port(port);
@@ -615,6 +675,19 @@ static int stm32_startup(struct uart_port *port)
 		val |= USART_CR1_FIFOEN;
 	stm32_set_bits(port, ofs->cr1, val);
 
+	stm32_port->ms_enabled = false;
+	if (stm32_port->sw_flow_control) {
+		irq_modify_status(gpio_to_irq(stm32_port->cts_gpio),
+				  IRQ_NOREQUEST, IRQ_NOAUTOEN);
+		ret = request_irq(gpio_to_irq(stm32_port->cts_gpio),
+			stm32_cts_handler, IRQF_TRIGGER_FALLING |
+			IRQF_TRIGGER_RISING, "stm32_cts_irq", stm32_port);
+		if (ret != 0) {
+			dev_err(port->dev, "request gpio irq fail\n");
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
@@ -642,6 +715,14 @@ static void stm32_shutdown(struct uart_port *port)
 	stm32_clr_bits(port, ofs->cr1, val);
 
 	free_irq(port->irq, port);
+
+	if (stm32_port->ms_enabled)
+		stm32_disable_ms(port);
+
+	if (stm32_port->sw_flow_control) {
+		gpio_set_value(stm32_port->rts_gpio, 1);
+		free_irq(gpio_to_irq(stm32_port->cts_gpio), stm32_port);
+	}
 }
 
 static unsigned int stm32_get_databits(struct ktermios *termios)
@@ -812,6 +893,14 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
 	if ((termios->c_cflag & CREAD) == 0)
 		port->ignore_status_mask |= USART_SR_DUMMY_RX;
 
+	if (UART_ENABLE_MS(port, termios->c_cflag)) {
+		if (!stm32_port->ms_enabled)
+			stm32_enable_ms(port);
+	} else {
+		if (stm32_port->ms_enabled)
+			stm32_disable_ms(port);
+	}
+
 	if (stm32_port->rx_ch)
 		cr3 |= USART_CR3_DMAR;
 
@@ -898,6 +987,7 @@ static const struct uart_ops stm32_uart_ops = {
 	.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,
@@ -970,7 +1060,7 @@ static int stm32_init_port(struct stm32_port *stm32port,
 static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
-	int id;
+	int id, ret;
 
 	if (!np)
 		return NULL;
@@ -990,6 +1080,47 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
 	stm32_ports[id].cr1_irq = USART_CR1_RXNEIE;
 	stm32_ports[id].cr3_irq = 0;
 	stm32_ports[id].last_res = RX_BUF_L;
+
+	stm32_ports[id].sw_flow_control = of_property_read_bool(np,
+							"st,sw-flow-ctrl");
+	if (stm32_ports[id].sw_flow_control) {
+		if (of_find_property(np, "cts-gpios", NULL))
+			stm32_ports[id].cts_gpio =
+				of_get_named_gpio(np, "cts-gpios", 0);
+		else
+			stm32_ports[id].cts_gpio = -1;
+
+		if (of_find_property(np, "rts-gpios", NULL))
+			stm32_ports[id].rts_gpio =
+				of_get_named_gpio(np, "rts-gpios", 0);
+		else
+			stm32_ports[id].rts_gpio = -1;
+
+		if ((!gpio_is_valid(stm32_ports[id].cts_gpio)) ||
+			(!gpio_is_valid(stm32_ports[id].rts_gpio))) {
+				dev_err(&pdev->dev,
+					"SW flow control must have cts and rts gpio");
+				return NULL;
+		}
+
+		ret = devm_gpio_request(&pdev->dev, stm32_ports[id].cts_gpio,
+				"st-cts-gpio");
+		if (ret) {
+			dev_err(&pdev->dev, "Unable request cts gpio");
+			return NULL;
+		}
+
+		gpio_direction_input(stm32_ports[id].cts_gpio);
+		ret = devm_gpio_request(&pdev->dev, stm32_ports[id].rts_gpio,
+				"st-rts-gpio");
+		if (ret) {
+			dev_err(&pdev->dev, "Unable request rts gpio");
+			return NULL;
+		}
+
+		gpio_direction_output(stm32_ports[id].rts_gpio, 1);
+	}
+
 	return &stm32_ports[id];
 }
 
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
index a175c1094dc8..87b30f514e15 100644
--- a/drivers/tty/serial/stm32-usart.h
+++ b/drivers/tty/serial/stm32-usart.h
@@ -274,6 +274,10 @@ struct stm32_port {
 	bool fifoen;
 	int wakeirq;
 	int rdr_mask;		/* receive data register mask */
+	bool sw_flow_control;
+	unsigned int cts_gpio;
+	unsigned int rts_gpio;
+	bool ms_enabled;
 };
 
 static struct stm32_port stm32_ports[STM32_MAX_PORTS];
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] Add software flow control support for STM32 UART
  2020-04-12 18:09 [PATCH 0/2] Add software flow control support for STM32 UART mani
  2020-04-12 18:09 ` [PATCH 1/2] dt-bindings: serial: Add binding for software flow control in " mani
  2020-04-12 18:09 ` [PATCH 2/2] tty: serial: Add software flow control support for STM32 USART mani
@ 2020-04-13  9:17 ` Andy Shevchenko
  2020-04-16 17:37   ` Manivannan Sadhasivam
  2 siblings, 1 reply; 5+ messages in thread
From: Andy Shevchenko @ 2020-04-13  9:17 UTC (permalink / raw)
  To: mani
  Cc: Greg Kroah-Hartman, Rob Herring, Maxime Coquelin,
	Alexandre TORGUE, open list:SERIAL DRIVERS, devicetree,
	linux-stm32, linux-arm Mailing List, Linux Kernel Mailing List

On Mon, Apr 13, 2020 at 7:06 AM <mani@kernel.org> wrote:
>
> From: Manivannan Sadhasivam <mani@kernel.org>
>
> Hello,
>
> This patchset adds software flow control support for STM32 UART controller.
> This is necessary for the upcoming STM32MP1 based board called Stinger96
> IoT-Box. On that board, a bluetooth chip is connected to one of the UART
> controller but the CTS/RTS lines got swapped mistakenly. So in order to
> workaround that hardware bug and also to support the usecase of using only
> Tx/Rx pins, this patchset adds software flow control support.
>
> This patchset has been validated w/ Stinger96 IoT-Box connected to Murata
> WiFi-BT combo chip.
>

I think it's a mix of terminology or so. Looking into the patches I
found that it's required to have GPIOs for SW flow control.
No, SW flow control does not require any additional signals, except RxD/TxD.

On top of that, it seems you adding mctrl-gpio functionality. Why
can't you use that one? And thus no bindings needs to be updated.

> Thanks,
> Mani
>
> Manivannan Sadhasivam (2):
>   dt-bindings: serial: Add binding for software flow control in STM32
>     UART
>   tty: serial: Add software flow control support for STM32 USART
>
>  .../bindings/serial/st,stm32-uart.yaml        |  15 +-
>  drivers/tty/serial/stm32-usart.c              | 143 +++++++++++++++++-
>  drivers/tty/serial/stm32-usart.h              |   4 +
>  3 files changed, 155 insertions(+), 7 deletions(-)
>
> --
> 2.17.1
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] Add software flow control support for STM32 UART
  2020-04-13  9:17 ` [PATCH 0/2] Add software flow control support for STM32 UART Andy Shevchenko
@ 2020-04-16 17:37   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 5+ messages in thread
From: Manivannan Sadhasivam @ 2020-04-16 17:37 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Greg Kroah-Hartman, Rob Herring, Maxime Coquelin,
	Alexandre TORGUE, open list:SERIAL DRIVERS, devicetree,
	linux-stm32, linux-arm Mailing List, Linux Kernel Mailing List

Hi Andy,

On Mon, Apr 13, 2020 at 12:17:21PM +0300, Andy Shevchenko wrote:
> On Mon, Apr 13, 2020 at 7:06 AM <mani@kernel.org> wrote:
> >
> > From: Manivannan Sadhasivam <mani@kernel.org>
> >
> > Hello,
> >
> > This patchset adds software flow control support for STM32 UART controller.
> > This is necessary for the upcoming STM32MP1 based board called Stinger96
> > IoT-Box. On that board, a bluetooth chip is connected to one of the UART
> > controller but the CTS/RTS lines got swapped mistakenly. So in order to
> > workaround that hardware bug and also to support the usecase of using only
> > Tx/Rx pins, this patchset adds software flow control support.
> >
> > This patchset has been validated w/ Stinger96 IoT-Box connected to Murata
> > WiFi-BT combo chip.
> >
> 
> I think it's a mix of terminology or so. Looking into the patches I
> found that it's required to have GPIOs for SW flow control.
> No, SW flow control does not require any additional signals, except RxD/TxD.
> 

Yikes. Yes I got it wrong. 'st,hw-flow-ctrl' property confused me :)

> On top of that, it seems you adding mctrl-gpio functionality. Why
> can't you use that one? And thus no bindings needs to be updated.
> 

Sure. This looks feasible. Will submit a follow up patch.

Thanks,
Mani

> > Thanks,
> > Mani
> >
> > Manivannan Sadhasivam (2):
> >   dt-bindings: serial: Add binding for software flow control in STM32
> >     UART
> >   tty: serial: Add software flow control support for STM32 USART
> >
> >  .../bindings/serial/st,stm32-uart.yaml        |  15 +-
> >  drivers/tty/serial/stm32-usart.c              | 143 +++++++++++++++++-
> >  drivers/tty/serial/stm32-usart.h              |   4 +
> >  3 files changed, 155 insertions(+), 7 deletions(-)
> >
> > --
> > 2.17.1
> >
> 
> 
> -- 
> With Best Regards,
> Andy Shevchenko

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-04-16 17:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-12 18:09 [PATCH 0/2] Add software flow control support for STM32 UART mani
2020-04-12 18:09 ` [PATCH 1/2] dt-bindings: serial: Add binding for software flow control in " mani
2020-04-12 18:09 ` [PATCH 2/2] tty: serial: Add software flow control support for STM32 USART mani
2020-04-13  9:17 ` [PATCH 0/2] Add software flow control support for STM32 UART Andy Shevchenko
2020-04-16 17:37   ` Manivannan Sadhasivam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).