Commit 0c11b888 authored by Heiko Schocher's avatar Heiko Schocher Committed by Greg Kroah-Hartman
Browse files

tty: 8250_of: Use software emulated RS485 direction control



Use software emulated RS485 direction control to provide RS485 API

Currently it is not possible to use rs485 as pointer to
rs485_config struct in struct uart_port is NULL in case we
configure the port through device tree.

Signed-off-by: default avatarHeiko Schocher <hs@denx.de>

Link: https://lore.kernel.org/r/20190913050105.1132080-1-hs@denx.de


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 39f80919
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -48,6 +48,36 @@ static inline void tegra_serial_handle_break(struct uart_port *port)
}
#endif

static int of_8250_rs485_config(struct uart_port *port,
				  struct serial_rs485 *rs485)
{
	struct uart_8250_port *up = up_to_u8250p(port);

	/* Clamp the delays to [0, 100ms] */
	rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U);
	rs485->delay_rts_after_send  = min(rs485->delay_rts_after_send, 100U);

	port->rs485 = *rs485;

	/*
	 * Both serial8250_em485_init and serial8250_em485_destroy
	 * are idempotent
	 */
	if (rs485->flags & SER_RS485_ENABLED) {
		int ret = serial8250_em485_init(up);

		if (ret) {
			rs485->flags &= ~SER_RS485_ENABLED;
			port->rs485.flags &= ~SER_RS485_ENABLED;
		}
		return ret;
	}

	serial8250_em485_destroy(up);

	return 0;
}

/*
 * Fill a struct uart_port for a given device node
 */
@@ -178,6 +208,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
		port->flags |= UPF_SKIP_TEST;

	port->dev = &ofdev->dev;
	port->rs485_config = of_8250_rs485_config;

	switch (type) {
	case PORT_TEGRA: