0061-tty-serial-ar933x-uart-rs485-gpio.patch 8.3 KB

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