.. | .. |
---|
1 | | -// SPDX-License-Identifier: GPL-2.0+ |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0+ */ |
---|
2 | 2 | /* |
---|
3 | 3 | * Driver for 8250/16550-type serial ports |
---|
4 | 4 | * |
---|
.. | .. |
---|
10 | 10 | #include <linux/serial_8250.h> |
---|
11 | 11 | #include <linux/serial_reg.h> |
---|
12 | 12 | #include <linux/dmaengine.h> |
---|
| 13 | + |
---|
| 14 | +#include "../serial_mctrl_gpio.h" |
---|
13 | 15 | |
---|
14 | 16 | struct uart_8250_dma { |
---|
15 | 17 | int (*tx_dma)(struct uart_8250_port *p); |
---|
.. | .. |
---|
46 | 48 | unsigned char tx_running; |
---|
47 | 49 | unsigned char tx_err; |
---|
48 | 50 | unsigned char rx_running; |
---|
49 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
---|
| 51 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
50 | 52 | size_t rx_index; |
---|
51 | 53 | #endif |
---|
52 | 54 | }; |
---|
.. | .. |
---|
89 | 91 | #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ |
---|
90 | 92 | #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ |
---|
91 | 93 | #define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ |
---|
| 94 | +#define UART_BUG_TXRACE (1 << 5) /* UART Tx fails to set remote DR */ |
---|
92 | 95 | |
---|
93 | 96 | |
---|
94 | 97 | #ifdef CONFIG_SERIAL_8250_SHARE_IRQ |
---|
.. | .. |
---|
119 | 122 | up->port.serial_out(&up->port, offset, value); |
---|
120 | 123 | } |
---|
121 | 124 | |
---|
| 125 | +/* |
---|
| 126 | + * For the 16C950 |
---|
| 127 | + */ |
---|
| 128 | +static void serial_icr_write(struct uart_8250_port *up, int offset, int value) |
---|
| 129 | +{ |
---|
| 130 | + serial_out(up, UART_SCR, offset); |
---|
| 131 | + serial_out(up, UART_ICR, value); |
---|
| 132 | +} |
---|
| 133 | + |
---|
| 134 | +static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up, |
---|
| 135 | + int offset) |
---|
| 136 | +{ |
---|
| 137 | + unsigned int value; |
---|
| 138 | + |
---|
| 139 | + serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD); |
---|
| 140 | + serial_out(up, UART_SCR, offset); |
---|
| 141 | + value = serial_in(up, UART_ICR); |
---|
| 142 | + serial_icr_write(up, UART_ACR, up->acr); |
---|
| 143 | + |
---|
| 144 | + return value; |
---|
| 145 | +} |
---|
| 146 | + |
---|
122 | 147 | void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p); |
---|
123 | 148 | |
---|
124 | 149 | static inline int serial_dl_read(struct uart_8250_port *up) |
---|
.. | .. |
---|
131 | 156 | up->dl_write(up, value); |
---|
132 | 157 | } |
---|
133 | 158 | |
---|
| 159 | +static inline bool serial8250_set_THRI(struct uart_8250_port *up) |
---|
| 160 | +{ |
---|
| 161 | + if (up->ier & UART_IER_THRI) |
---|
| 162 | + return false; |
---|
| 163 | + up->ier |= UART_IER_THRI; |
---|
| 164 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
| 165 | + up->ier |= UART_IER_PTIME; |
---|
| 166 | +#endif |
---|
| 167 | + serial_out(up, UART_IER, up->ier); |
---|
| 168 | + return true; |
---|
| 169 | +} |
---|
| 170 | + |
---|
| 171 | +static inline bool serial8250_clear_THRI(struct uart_8250_port *up) |
---|
| 172 | +{ |
---|
| 173 | + if (!(up->ier & UART_IER_THRI)) |
---|
| 174 | + return false; |
---|
| 175 | + up->ier &= ~UART_IER_THRI; |
---|
| 176 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
| 177 | + up->ier &= ~UART_IER_PTIME; |
---|
| 178 | +#endif |
---|
| 179 | + serial_out(up, UART_IER, up->ier); |
---|
| 180 | + return true; |
---|
| 181 | +} |
---|
| 182 | + |
---|
134 | 183 | struct uart_8250_port *serial8250_get_port(int line); |
---|
135 | 184 | |
---|
136 | 185 | void serial8250_rpm_get(struct uart_8250_port *p); |
---|
.. | .. |
---|
139 | 188 | void serial8250_rpm_get_tx(struct uart_8250_port *p); |
---|
140 | 189 | void serial8250_rpm_put_tx(struct uart_8250_port *p); |
---|
141 | 190 | |
---|
142 | | -int serial8250_em485_init(struct uart_8250_port *p); |
---|
| 191 | +int serial8250_em485_config(struct uart_port *port, struct serial_rs485 *rs485); |
---|
| 192 | +void serial8250_em485_start_tx(struct uart_8250_port *p); |
---|
| 193 | +void serial8250_em485_stop_tx(struct uart_8250_port *p); |
---|
143 | 194 | void serial8250_em485_destroy(struct uart_8250_port *p); |
---|
| 195 | + |
---|
| 196 | +/* MCR <-> TIOCM conversion */ |
---|
| 197 | +static inline int serial8250_TIOCM_to_MCR(int tiocm) |
---|
| 198 | +{ |
---|
| 199 | + int mcr = 0; |
---|
| 200 | + |
---|
| 201 | + if (tiocm & TIOCM_RTS) |
---|
| 202 | + mcr |= UART_MCR_RTS; |
---|
| 203 | + if (tiocm & TIOCM_DTR) |
---|
| 204 | + mcr |= UART_MCR_DTR; |
---|
| 205 | + if (tiocm & TIOCM_OUT1) |
---|
| 206 | + mcr |= UART_MCR_OUT1; |
---|
| 207 | + if (tiocm & TIOCM_OUT2) |
---|
| 208 | + mcr |= UART_MCR_OUT2; |
---|
| 209 | + if (tiocm & TIOCM_LOOP) |
---|
| 210 | + mcr |= UART_MCR_LOOP; |
---|
| 211 | + |
---|
| 212 | + return mcr; |
---|
| 213 | +} |
---|
| 214 | + |
---|
| 215 | +static inline int serial8250_MCR_to_TIOCM(int mcr) |
---|
| 216 | +{ |
---|
| 217 | + int tiocm = 0; |
---|
| 218 | + |
---|
| 219 | + if (mcr & UART_MCR_RTS) |
---|
| 220 | + tiocm |= TIOCM_RTS; |
---|
| 221 | + if (mcr & UART_MCR_DTR) |
---|
| 222 | + tiocm |= TIOCM_DTR; |
---|
| 223 | + if (mcr & UART_MCR_OUT1) |
---|
| 224 | + tiocm |= TIOCM_OUT1; |
---|
| 225 | + if (mcr & UART_MCR_OUT2) |
---|
| 226 | + tiocm |= TIOCM_OUT2; |
---|
| 227 | + if (mcr & UART_MCR_LOOP) |
---|
| 228 | + tiocm |= TIOCM_LOOP; |
---|
| 229 | + |
---|
| 230 | + return tiocm; |
---|
| 231 | +} |
---|
| 232 | + |
---|
| 233 | +/* MSR <-> TIOCM conversion */ |
---|
| 234 | +static inline int serial8250_MSR_to_TIOCM(int msr) |
---|
| 235 | +{ |
---|
| 236 | + int tiocm = 0; |
---|
| 237 | + |
---|
| 238 | + if (msr & UART_MSR_DCD) |
---|
| 239 | + tiocm |= TIOCM_CAR; |
---|
| 240 | + if (msr & UART_MSR_RI) |
---|
| 241 | + tiocm |= TIOCM_RNG; |
---|
| 242 | + if (msr & UART_MSR_DSR) |
---|
| 243 | + tiocm |= TIOCM_DSR; |
---|
| 244 | + if (msr & UART_MSR_CTS) |
---|
| 245 | + tiocm |= TIOCM_CTS; |
---|
| 246 | + |
---|
| 247 | + return tiocm; |
---|
| 248 | +} |
---|
144 | 249 | |
---|
145 | 250 | static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) |
---|
146 | 251 | { |
---|
147 | 252 | serial_out(up, UART_MCR, value); |
---|
| 253 | + |
---|
| 254 | + if (up->gpios) |
---|
| 255 | + mctrl_gpio_set(up->gpios, serial8250_MCR_to_TIOCM(value)); |
---|
148 | 256 | } |
---|
149 | 257 | |
---|
150 | 258 | static inline int serial8250_in_MCR(struct uart_8250_port *up) |
---|
151 | 259 | { |
---|
152 | | - return serial_in(up, UART_MCR); |
---|
| 260 | + int mctrl; |
---|
| 261 | + |
---|
| 262 | + mctrl = serial_in(up, UART_MCR); |
---|
| 263 | + |
---|
| 264 | + if (up->gpios) { |
---|
| 265 | + unsigned int mctrl_gpio = 0; |
---|
| 266 | + |
---|
| 267 | + mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio); |
---|
| 268 | + mctrl |= serial8250_TIOCM_to_MCR(mctrl_gpio); |
---|
| 269 | + } |
---|
| 270 | + |
---|
| 271 | + return mctrl; |
---|
153 | 272 | } |
---|
154 | 273 | |
---|
155 | 274 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
---|
.. | .. |
---|
217 | 336 | #ifdef CONFIG_SERIAL_8250_DMA |
---|
218 | 337 | extern int serial8250_tx_dma(struct uart_8250_port *); |
---|
219 | 338 | extern int serial8250_rx_dma(struct uart_8250_port *); |
---|
| 339 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
| 340 | +extern int serial8250_start_rx_dma(struct uart_8250_port *); |
---|
| 341 | +#endif |
---|
220 | 342 | extern void serial8250_rx_dma_flush(struct uart_8250_port *); |
---|
221 | 343 | extern int serial8250_request_dma(struct uart_8250_port *); |
---|
222 | 344 | extern void serial8250_release_dma(struct uart_8250_port *); |
---|
| 345 | + |
---|
| 346 | +static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) |
---|
| 347 | +{ |
---|
| 348 | + struct uart_8250_dma *dma = p->dma; |
---|
| 349 | + |
---|
| 350 | + return dma && dma->tx_running; |
---|
| 351 | +} |
---|
223 | 352 | #else |
---|
224 | 353 | static inline int serial8250_tx_dma(struct uart_8250_port *p) |
---|
225 | 354 | { |
---|
.. | .. |
---|
229 | 358 | { |
---|
230 | 359 | return -1; |
---|
231 | 360 | } |
---|
| 361 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
| 362 | +static inline int serial8250_start_rx_dma(struct uart_8250_port *p) |
---|
| 363 | +{ |
---|
| 364 | + return -1; |
---|
| 365 | +} |
---|
| 366 | +#endif |
---|
232 | 367 | static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { } |
---|
233 | 368 | static inline int serial8250_request_dma(struct uart_8250_port *p) |
---|
234 | 369 | { |
---|
235 | 370 | return -1; |
---|
236 | 371 | } |
---|
237 | 372 | static inline void serial8250_release_dma(struct uart_8250_port *p) { } |
---|
| 373 | + |
---|
| 374 | +static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) |
---|
| 375 | +{ |
---|
| 376 | + return false; |
---|
| 377 | +} |
---|
238 | 378 | #endif |
---|
239 | 379 | |
---|
240 | 380 | static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) |
---|