kernel: properly insert local mtd partition parsers
[oweals/openwrt.git] / target / linux / ath79 / patches-5.4 / 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 --- a/drivers/tty/serial/Kconfig
36 +++ b/drivers/tty/serial/Kconfig
37 @@ -1279,6 +1279,7 @@ config SERIAL_AR933X
38         tristate "AR933X serial port support"
39         depends on HAVE_CLK && ATH79
40         select SERIAL_CORE
41 +       select SERIAL_MCTRL_GPIO if GPIOLIB
42         help
43           If you have an Atheros AR933X SOC based board and want to use the
44           built-in UART of the SoC, say Y to this option.
45 --- a/drivers/tty/serial/ar933x_uart.c
46 +++ b/drivers/tty/serial/ar933x_uart.c
47 @@ -13,6 +13,7 @@
48  #include <linux/console.h>
49  #include <linux/sysrq.h>
50  #include <linux/delay.h>
51 +#include <linux/gpio/consumer.h>
52  #include <linux/platform_device.h>
53  #include <linux/of.h>
54  #include <linux/of_platform.h>
55 @@ -29,6 +30,8 @@
56  
57  #include <asm/mach-ath79/ar933x_uart.h>
58  
59 +#include "serial_mctrl_gpio.h"
60 +
61  #define DRIVER_NAME "ar933x-uart"
62  
63  #define AR933X_UART_MAX_SCALE  0xff
64 @@ -47,6 +50,8 @@ struct ar933x_uart_port {
65         unsigned int            min_baud;
66         unsigned int            max_baud;
67         struct clk              *clk;
68 +       struct mctrl_gpios      *gpios;
69 +       struct gpio_desc        *rts_gpiod;
70  };
71  
72  static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
73 @@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_i
74         ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
75  }
76  
77 +static inline void ar933x_uart_start_rx_interrupt(struct ar933x_uart_port *up)
78 +{
79 +       up->ier |= AR933X_UART_INT_RX_VALID;
80 +       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
81 +}
82 +
83 +static inline void ar933x_uart_stop_rx_interrupt(struct ar933x_uart_port *up)
84 +{
85 +       up->ier &= ~AR933X_UART_INT_RX_VALID;
86 +       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
87 +}
88 +
89  static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
90  {
91         unsigned int rdata;
92 @@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty
93  
94  static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
95  {
96 -       return TIOCM_CAR;
97 +       struct ar933x_uart_port *up =
98 +               container_of(port, struct ar933x_uart_port, port);
99 +       int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
100 +
101 +       mctrl_gpio_get(up->gpios, &ret);
102 +
103 +       return ret;
104  }
105  
106  static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
107  {
108 +       struct ar933x_uart_port *up =
109 +               container_of(port, struct ar933x_uart_port, port);
110 +
111 +       mctrl_gpio_set(up->gpios, mctrl);
112  }
113  
114  static void ar933x_uart_start_tx(struct uart_port *port)
115 @@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct
116         ar933x_uart_start_tx_interrupt(up);
117  }
118  
119 +static void ar933x_uart_wait_tx_complete(struct ar933x_uart_port *up)
120 +{
121 +       unsigned int status;
122 +       unsigned int timeout = 60000;
123 +
124 +       /* Wait up to 60ms for the character(s) to be sent. */
125 +       do {
126 +               status = ar933x_uart_read(up, AR933X_UART_CS_REG);
127 +               if (--timeout == 0)
128 +                       break;
129 +               udelay(1);
130 +       } while (status & AR933X_UART_CS_TX_BUSY);
131 +
132 +       if (timeout == 0)
133 +               dev_err(up->port.dev, "waiting for TX timed out\n");
134 +}
135 +
136 +static void ar933x_uart_rx_flush(struct ar933x_uart_port *up)
137 +{
138 +       unsigned int status;
139 +
140 +       /* clear RX_VALID interrupt */
141 +       ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_RX_VALID);
142 +
143 +       /* remove characters from the RX FIFO */
144 +       do {
145 +               ar933x_uart_write(up, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
146 +               status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
147 +       } while (status & AR933X_UART_DATA_RX_CSR);
148 +}
149 +
150  static void ar933x_uart_stop_tx(struct uart_port *port)
151  {
152         struct ar933x_uart_port *up =
153 @@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct u
154         struct ar933x_uart_port *up =
155                 container_of(port, struct ar933x_uart_port, port);
156  
157 -       up->ier &= ~AR933X_UART_INT_RX_VALID;
158 -       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
159 +       ar933x_uart_stop_rx_interrupt(up);
160  }
161  
162  static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
163 @@ -340,11 +397,20 @@ static void ar933x_uart_rx_chars(struct
164  static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
165  {
166         struct circ_buf *xmit = &up->port.state->xmit;
167 +       struct serial_rs485 *rs485conf = &up->port.rs485;
168         int count;
169 +       bool half_duplex_send = false;
170  
171         if (uart_tx_stopped(&up->port))
172                 return;
173  
174 +       if ((rs485conf->flags & SER_RS485_ENABLED) &&
175 +           (up->port.x_char || !uart_circ_empty(xmit))) {
176 +               ar933x_uart_stop_rx_interrupt(up);
177 +               gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_ON_SEND));
178 +               half_duplex_send = true;
179 +       }
180 +
181         count = up->port.fifosize;
182         do {
183                 unsigned int rdata;
184 @@ -372,8 +438,14 @@ static void ar933x_uart_tx_chars(struct
185         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
186                 uart_write_wakeup(&up->port);
187  
188 -       if (!uart_circ_empty(xmit))
189 +       if (!uart_circ_empty(xmit)) {
190                 ar933x_uart_start_tx_interrupt(up);
191 +       } else if (half_duplex_send) {
192 +               ar933x_uart_wait_tx_complete(up);
193 +               ar933x_uart_rx_flush(up);
194 +               ar933x_uart_start_rx_interrupt(up);
195 +               gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND));
196 +       }
197  }
198  
199  static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
200 @@ -435,8 +507,7 @@ static int ar933x_uart_startup(struct ua
201                 AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
202  
203         /* Enable RX interrupts */
204 -       up->ier = AR933X_UART_INT_RX_VALID;
205 -       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
206 +       ar933x_uart_start_rx_interrupt(up);
207  
208         spin_unlock_irqrestore(&up->port.lock, flags);
209  
210 @@ -519,6 +590,21 @@ static const struct uart_ops ar933x_uart
211         .verify_port    = ar933x_uart_verify_port,
212  };
213  
214 +static int ar933x_config_rs485(struct uart_port *port,
215 +                               struct serial_rs485 *rs485conf)
216 +{
217 +       struct ar933x_uart_port *up =
218 +               container_of(port, struct ar933x_uart_port, port);
219 +
220 +       if ((rs485conf->flags & SER_RS485_ENABLED) &&
221 +           !up->rts_gpiod) {
222 +               dev_err(port->dev, "RS485 needs rts-gpio\n");
223 +               return 1;
224 +       }
225 +       port->rs485 = *rs485conf;
226 +       return 0;
227 +}
228 +
229  #ifdef CONFIG_SERIAL_AR933X_CONSOLE
230  static struct ar933x_uart_port *
231  ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
232 @@ -688,6 +774,8 @@ static int ar933x_uart_probe(struct plat
233                 goto err_disable_clk;
234         }
235  
236 +       uart_get_rs485_mode(&pdev->dev, &port->rs485);
237 +
238         port->mapbase = mem_res->start;
239         port->line = id;
240         port->irq = irq_res->start;
241 @@ -698,6 +786,7 @@ static int ar933x_uart_probe(struct plat
242         port->regshift = 2;
243         port->fifosize = AR933X_UART_FIFO_SIZE;
244         port->ops = &ar933x_uart_ops;
245 +       port->rs485_config = ar933x_config_rs485;
246  
247         baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
248         up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
249 @@ -705,6 +794,18 @@ static int ar933x_uart_probe(struct plat
250         baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
251         up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
252  
253 +       up->gpios = mctrl_gpio_init(port, 0);
254 +       if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
255 +               return PTR_ERR(up->gpios);
256 +
257 +       up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);
258 +
259 +       if ((port->rs485.flags & SER_RS485_ENABLED) &&
260 +           !up->rts_gpiod) {
261 +               dev_err(&pdev->dev, "lacking rts-gpio, disabling RS485\n");
262 +               port->rs485.flags &= ~SER_RS485_ENABLED;
263 +       }
264 +
265  #ifdef CONFIG_SERIAL_AR933X_CONSOLE
266         ar933x_console_ports[up->port.line] = up;
267  #endif