Re: [RFC] tty/serial/8250: use mctrl_gpio helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Yegor,

On 03/09/2016 03:03 AM, yegorslists@xxxxxxxxxxxxxx wrote:
> From: Yegor Yefremov <yegorslists@xxxxxxxxxxxxxx>
> 
> This patch permits the usage fo GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI
> signals.

Comments below.


> Signed-off-by: Yegor Yefremov <yegorslists@xxxxxxxxxxxxxx>
> ---
>  Documentation/devicetree/bindings/serial/8250.txt | 21 +++++++++++++++++++++
>  drivers/tty/serial/8250/8250.h                    |  2 ++
>  drivers/tty/serial/8250/8250_core.c               |  5 +++++
>  drivers/tty/serial/8250/8250_port.c               | 11 ++++++++++-
>  drivers/tty/serial/8250/Kconfig                   |  1 +
>  include/linux/serial_8250.h                       |  1 +
>  6 files changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
> index 936ab5b..277e0ee 100644
> --- a/Documentation/devicetree/bindings/serial/8250.txt
> +++ b/Documentation/devicetree/bindings/serial/8250.txt
> @@ -42,6 +42,9 @@ Optional properties:
>  - auto-flow-control: one way to enable automatic flow control support. The
>    driver is allowed to detect support for the capability even without this
>    property.
> +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
> +  line respectively. It will use specified GPIO instead of the peripheral
> +  function pin for the UART feature. If unsure, don't specify this property.
>  
>  Note:
>  * fsl,ns16550:
> @@ -63,3 +66,21 @@ Example:
>  		interrupts = <10>;
>  		reg-shift = <2>;
>  	};
> +
> +Example for OMAP UART using GPIO-based modem control signals:
> +
> +	uart4: serial@49042000 {
> +		compatible = "ti,omap3-uart";
> +		reg = <0x49042000 0x400>;
> +		interrupts = <80>;

> +		dmas = <&sdma 81 &sdma 82>;
> +		dma-names = "tx", "rx";

Drop the DMA example; omap3 sdma is broken wrt to uart.


> +		ti,hwmods = "uart4";
> +		clock-frequency = <48000000>;
> +		cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
> +		rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
> +		dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
> +		dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
> +		dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
> +		rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
> +	};
> diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
> index d54dcd8..98ee73c 100644
> --- a/drivers/tty/serial/8250/8250.h
> +++ b/drivers/tty/serial/8250/8250.h
> @@ -15,6 +15,8 @@
>  #include <linux/serial_reg.h>
>  #include <linux/dmaengine.h>
>  
> +#include "../serial_mctrl_gpio.h"
> +
>  struct uart_8250_dma {
>  	int (*tx_dma)(struct uart_8250_port *p);
>  	int (*rx_dma)(struct uart_8250_port *p, unsigned int iir);
> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
> index c9720a9..cadcaa5 100644
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -1004,6 +1004,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
>  		if (up->port.flags & UPF_FIXED_TYPE)
>  			uart->port.type = up->port.type;
>  
> +		uart->gpios = mctrl_gpio_init(&uart->port, 0);
> +		if (IS_ERR(uart->gpios))
> +			return PTR_ERR(uart->gpios);
> +
>  		serial8250_set_defaults(uart);
>  
>  		/* Possibly override default I/O functions.  */
> @@ -1049,6 +1053,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
>  
>  			ret = 0;
>  		}
> +
>  	}
>  	mutex_unlock(&serial_mutex);
>  
> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
> index 8d262bc..e7bfeef 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -1393,6 +1393,8 @@ static void serial8250_disable_ms(struct uart_port *port)
>  	if (up->bugs & UART_BUG_NOMSR)
>  		return;
>  
> +	mctrl_gpio_disable_ms(up->gpios);
> +
>  	up->ier &= ~UART_IER_MSI;
>  	serial_port_out(port, UART_IER, up->ier);
>  }
> @@ -1405,6 +1407,8 @@ static void serial8250_enable_ms(struct uart_port *port)
>  	if (up->bugs & UART_BUG_NOMSR)
>  		return;
>  
> +	mctrl_gpio_enable_ms(up->gpios);
> +
>  	up->ier |= UART_IER_MSI;
>  
>  	serial8250_rpm_get(up);
> @@ -1680,7 +1684,8 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
>  		ret |= TIOCM_DSR;
>  	if (status & UART_MSR_CTS)
>  		ret |= TIOCM_CTS;
> -	return ret;
> +
> +	return mctrl_gpio_get(up->gpios, &ret);

This is ugly; why is mctrl pass-by-reference when it's returned anyway?

	return mctrl_gpio_get(up->gpio, ret);


>  }
>  
>  void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
> @@ -1707,10 +1712,14 @@ EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl);
>  
>  static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
>  {
> +	struct uart_8250_port *up = up_to_u8250p(port);
> +
>  	if (port->set_mctrl)
>  		port->set_mctrl(port, mctrl);
>  	else
>  		serial8250_do_set_mctrl(port, mctrl);
> +
> +	mctrl_gpio_set(up->gpios, mctrl);

The 8250 driver virtualizes RTS because some h/w does not
support RTS override with autoRTS on.

So this won't work properly.
And this won't work for RS485.

Rather, transform

	serial_out(port, UART_MCR, val);
	serial_port_out(up, UART_MCR, val);

to

	serial8250_out_MCR(up, val);

and add the gpio setting to that.
Do the transform first in a prequel patch; then add gpio to that.

Similarly for serial_in(port, UART_MCR)

Regards,
Peter Hurley


>  }
>  
>  static void serial8250_break_ctl(struct uart_port *port, int break_state)
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index b03cb517..997e9a8 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -6,6 +6,7 @@
>  config SERIAL_8250
>  	tristate "8250/16550 and compatible serial support"
>  	select SERIAL_CORE
> +	select SERIAL_MCTRL_GPIO if GPIOLIB
>  	---help---
>  	  This selects whether you want to include the driver for the standard
>  	  serial ports.  The standard answer is Y.  People who might say N
> diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
> index faa0e03..86a3ef4 100644
> --- a/include/linux/serial_8250.h
> +++ b/include/linux/serial_8250.h
> @@ -104,6 +104,7 @@ struct uart_8250_port {
>  						 *   if no_console_suspend
>  						 */
>  	unsigned char		probe;
> +	struct mctrl_gpios	*gpios;
>  #define UART_PROBE_RSA	(1 << 0)
>  
>  	/*
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux