c0edac906a234503c1643c94257dedfcde4cc977
[openwrt/staging/jow.git] / target / linux / ath79 / patches-4.19 / 0061-tty-serial-ar933x-uart-rs485-gpio.patch
1 From patchwork Fri Feb 21 21:23:31 2020
2 Content-Type: text/plain; charset="utf-8"
3 MIME-Version: 1.0
4 Content-Transfer-Encoding: 7bit
5 X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
6 X-Patchwork-Id: 1198835
7 Date: Fri, 21 Feb 2020 22:23:31 +0100
8 From: Daniel Golle <daniel@makrotopia.org>
9 To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org
10 Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
11 Jiri Slaby <jslaby@suse.com>, Petr =?utf-8?q?=C5=A0tetiar?= <ynezz@true.cz>,
12 Chuanhong Guo <gch981213@gmail.com>, Piotr Dymacz <pepe2k@gmail.com>
13 Subject: [PATCH v2] serial: ar933x_uart: add RS485 support
14 Message-ID: <20200221212331.GA21467@makrotopia.org>
15 MIME-Version: 1.0
16 Content-Disposition: inline
17 Sender: linux-kernel-owner@vger.kernel.org
18 Precedence: bulk
19 List-ID: <linux-kernel.vger.kernel.org>
20 X-Mailing-List: linux-kernel@vger.kernel.org
21
22 Emulate half-duplex operation and use mctrl_gpio to add support for
23 RS485 tranceiver with transmit/receive switch hooked to RTS GPIO line.
24 This is needed to make use of the RS485 port found on Teltonika RUT955.
25
26 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
27 ---
28 v2: use bool to indicate ongoing half-duplex send, use it afterwards
29 to decide whether we've just been in a send operation.
30
31 drivers/tty/serial/Kconfig | 1 +
32 drivers/tty/serial/ar933x_uart.c | 113 +++++++++++++++++++++++++++++--
33 2 files changed, 108 insertions(+), 6 deletions(-)
34
35 diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
36 index 52eaac21ff9f..b675924138e0 100644
37 --- a/drivers/tty/serial/Kconfig
38 +++ b/drivers/tty/serial/Kconfig
39 @@ -1279,6 +1279,7 @@ config SERIAL_AR933X
40 tristate "AR933X serial port support"
41 depends on HAVE_CLK && ATH79
42 select SERIAL_CORE
43 + select SERIAL_MCTRL_GPIO if GPIOLIB
44 help
45 If you have an Atheros AR933X SOC based board and want to use the
46 built-in UART of the SoC, say Y to this option.
47 diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c
48 index ea12f10610b6..7e7f1398019f 100644
49 --- a/drivers/tty/serial/ar933x_uart.c
50 +++ b/drivers/tty/serial/ar933x_uart.c
51 @@ -13,6 +13,7 @@
52 #include <linux/console.h>
53 #include <linux/sysrq.h>
54 #include <linux/delay.h>
55 +#include <linux/gpio/consumer.h>
56 #include <linux/platform_device.h>
57 #include <linux/of.h>
58 #include <linux/of_platform.h>
59 @@ -29,6 +30,8 @@
60
61 #include <asm/mach-ath79/ar933x_uart.h>
62
63 +#include "serial_mctrl_gpio.h"
64 +
65 #define DRIVER_NAME "ar933x-uart"
66
67 #define AR933X_UART_MAX_SCALE 0xff
68 @@ -47,6 +50,8 @@ struct ar933x_uart_port {
69 unsigned int min_baud;
70 unsigned int max_baud;
71 struct clk *clk;
72 + struct mctrl_gpios *gpios;
73 + struct gpio_desc *rts_gpiod;
74 };
75
76 static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
77 @@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up)
78 ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
79 }
80
81 +static inline void ar933x_uart_start_rx_interrupt(struct ar933x_uart_port *up)
82 +{
83 + up->ier |= AR933X_UART_INT_RX_VALID;
84 + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
85 +}
86 +
87 +static inline void ar933x_uart_stop_rx_interrupt(struct ar933x_uart_port *up)
88 +{
89 + up->ier &= ~AR933X_UART_INT_RX_VALID;
90 + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
91 +}
92 +
93 static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
94 {
95 unsigned int rdata;
96 @@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty(struct uart_port *port)
97
98 static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
99 {
100 - return TIOCM_CAR;
101 + struct ar933x_uart_port *up =
102 + container_of(port, struct ar933x_uart_port, port);
103 + int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
104 +
105 + mctrl_gpio_get(up->gpios, &ret);
106 +
107 + return ret;
108 }
109
110 static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
111 {
112 + struct ar933x_uart_port *up =
113 + container_of(port, struct ar933x_uart_port, port);
114 +
115 + mctrl_gpio_set(up->gpios, mctrl);
116 }
117
118 static void ar933x_uart_start_tx(struct uart_port *port)
119 @@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct uart_port *port)
120 ar933x_uart_start_tx_interrupt(up);
121 }
122
123 +static void ar933x_uart_wait_tx_complete(struct ar933x_uart_port *up)
124 +{
125 + unsigned int status;
126 + unsigned int timeout = 60000;
127 +
128 + /* Wait up to 60ms for the character(s) to be sent. */
129 + do {
130 + status = ar933x_uart_read(up, AR933X_UART_CS_REG);
131 + if (--timeout == 0)
132 + break;
133 + udelay(1);
134 + } while (status & AR933X_UART_CS_TX_BUSY);
135 +
136 + if (timeout == 0)
137 + dev_err(up->port.dev, "waiting for TX timed out\n");
138 +}
139 +
140 +static void ar933x_uart_rx_flush(struct ar933x_uart_port *up)
141 +{
142 + unsigned int status;
143 +
144 + /* clear RX_VALID interrupt */
145 + ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_RX_VALID);
146 +
147 + /* remove characters from the RX FIFO */
148 + do {
149 + ar933x_uart_write(up, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
150 + status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
151 + } while (status & AR933X_UART_DATA_RX_CSR);
152 +}
153 +
154 static void ar933x_uart_stop_tx(struct uart_port *port)
155 {
156 struct ar933x_uart_port *up =
157 @@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct uart_port *port)
158 struct ar933x_uart_port *up =
159 container_of(port, struct ar933x_uart_port, port);
160
161 - up->ier &= ~AR933X_UART_INT_RX_VALID;
162 - ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
163 + ar933x_uart_stop_rx_interrupt(up);
164 }
165
166 static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
167 @@ -336,11 +393,20 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
168 static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
169 {
170 struct circ_buf *xmit = &up->port.state->xmit;
171 + struct serial_rs485 *rs485conf = &up->port.rs485;
172 int count;
173 + bool half_duplex_send = false;
174
175 if (uart_tx_stopped(&up->port))
176 return;
177
178 + if ((rs485conf->flags & SER_RS485_ENABLED) &&
179 + (up->port.x_char || !uart_circ_empty(xmit))) {
180 + ar933x_uart_stop_rx_interrupt(up);
181 + gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_ON_SEND));
182 + half_duplex_send = true;
183 + }
184 +
185 count = up->port.fifosize;
186 do {
187 unsigned int rdata;
188 @@ -368,8 +434,14 @@ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
189 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
190 uart_write_wakeup(&up->port);
191
192 - if (!uart_circ_empty(xmit))
193 + if (!uart_circ_empty(xmit)) {
194 ar933x_uart_start_tx_interrupt(up);
195 + } else if (half_duplex_send) {
196 + ar933x_uart_wait_tx_complete(up);
197 + ar933x_uart_rx_flush(up);
198 + ar933x_uart_start_rx_interrupt(up);
199 + gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND));
200 + }
201 }
202
203 static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
204 @@ -427,8 +499,7 @@ static int ar933x_uart_startup(struct uart_port *port)
205 AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
206
207 /* Enable RX interrupts */
208 - up->ier = AR933X_UART_INT_RX_VALID;
209 - ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
210 + ar933x_uart_start_rx_interrupt(up);
211
212 spin_unlock_irqrestore(&up->port.lock, flags);
213
214 @@ -511,6 +582,21 @@ static const struct uart_ops ar933x_uart_ops = {
215 .verify_port = ar933x_uart_verify_port,
216 };
217
218 +static int ar933x_config_rs485(struct uart_port *port,
219 + struct serial_rs485 *rs485conf)
220 +{
221 + struct ar933x_uart_port *up =
222 + container_of(port, struct ar933x_uart_port, port);
223 +
224 + if ((rs485conf->flags & SER_RS485_ENABLED) &&
225 + !up->rts_gpiod) {
226 + dev_err(port->dev, "RS485 needs rts-gpio\n");
227 + return 1;
228 + }
229 + port->rs485 = *rs485conf;
230 + return 0;
231 +}
232 +
233 #ifdef CONFIG_SERIAL_AR933X_CONSOLE
234 static struct ar933x_uart_port *
235 ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
236 @@ -680,6 +766,8 @@ static int ar933x_uart_probe(struct platform_device *pdev)
237 goto err_disable_clk;
238 }
239
240 + uart_get_rs485_mode(&pdev->dev, &port->rs485);
241 +
242 port->mapbase = mem_res->start;
243 port->line = id;
244 port->irq = irq_res->start;
245 @@ -690,6 +778,7 @@ static int ar933x_uart_probe(struct platform_device *pdev)
246 port->regshift = 2;
247 port->fifosize = AR933X_UART_FIFO_SIZE;
248 port->ops = &ar933x_uart_ops;
249 + port->rs485_config = ar933x_config_rs485;
250
251 baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
252 up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
253 @@ -697,6 +786,18 @@ static int ar933x_uart_probe(struct platform_device *pdev)
254 baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
255 up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
256
257 + up->gpios = mctrl_gpio_init(port, 0);
258 + if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
259 + return PTR_ERR(up->gpios);
260 +
261 + up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);
262 +
263 + if ((port->rs485.flags & SER_RS485_ENABLED) &&
264 + !up->rts_gpiod) {
265 + dev_err(&pdev->dev, "lacking rts-gpio, disabling RS485\n");
266 + port->rs485.flags &= ~SER_RS485_ENABLED;
267 + }
268 +
269 #ifdef CONFIG_SERIAL_AR933X_CONSOLE
270 ar933x_console_ports[up->port.line] = up;
271 #endif