Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0+ */ 2 : /* 3 : * Driver for 8250/16550-type serial ports 4 : * 5 : * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. 6 : * 7 : * Copyright (C) 2001 Russell King. 8 : */ 9 : 10 : #include <linux/serial_8250.h> 11 : #include <linux/serial_reg.h> 12 : #include <linux/dmaengine.h> 13 : 14 : #include "../serial_mctrl_gpio.h" 15 : 16 : struct uart_8250_dma { 17 : int (*tx_dma)(struct uart_8250_port *p); 18 : int (*rx_dma)(struct uart_8250_port *p); 19 : 20 : /* Filter function */ 21 : dma_filter_fn fn; 22 : /* Parameter to the filter function */ 23 : void *rx_param; 24 : void *tx_param; 25 : 26 : struct dma_slave_config rxconf; 27 : struct dma_slave_config txconf; 28 : 29 : struct dma_chan *rxchan; 30 : struct dma_chan *txchan; 31 : 32 : /* Device address base for DMA operations */ 33 : phys_addr_t rx_dma_addr; 34 : phys_addr_t tx_dma_addr; 35 : 36 : /* DMA address of the buffer in memory */ 37 : dma_addr_t rx_addr; 38 : dma_addr_t tx_addr; 39 : 40 : dma_cookie_t rx_cookie; 41 : dma_cookie_t tx_cookie; 42 : 43 : void *rx_buf; 44 : 45 : size_t rx_size; 46 : size_t tx_size; 47 : 48 : unsigned char tx_running; 49 : unsigned char tx_err; 50 : unsigned char rx_running; 51 : }; 52 : 53 : struct old_serial_port { 54 : unsigned int uart; 55 : unsigned int baud_base; 56 : unsigned int port; 57 : unsigned int irq; 58 : upf_t flags; 59 : unsigned char io_type; 60 : unsigned char __iomem *iomem_base; 61 : unsigned short iomem_reg_shift; 62 : }; 63 : 64 : struct serial8250_config { 65 : const char *name; 66 : unsigned short fifo_size; 67 : unsigned short tx_loadsz; 68 : unsigned char fcr; 69 : unsigned char rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE]; 70 : unsigned int flags; 71 : }; 72 : 73 : #define UART_CAP_FIFO (1 << 8) /* UART has FIFO */ 74 : #define UART_CAP_EFR (1 << 9) /* UART has EFR */ 75 : #define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */ 76 : #define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */ 77 : #define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ 78 : #define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */ 79 : #define UART_CAP_HFIFO (1 << 14) /* UART has a "hidden" FIFO */ 80 : #define UART_CAP_RPM (1 << 15) /* Runtime PM is active while idle */ 81 : #define UART_CAP_IRDA (1 << 16) /* UART supports IrDA line discipline */ 82 : #define UART_CAP_MINI (1 << 17) /* Mini UART on BCM283X family lacks: 83 : * STOP PARITY EPAR SPAR WLEN5 WLEN6 84 : */ 85 : 86 : #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ 87 : #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ 88 : #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ 89 : #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ 90 : #define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ 91 : 92 : 93 : #ifdef CONFIG_SERIAL_8250_SHARE_IRQ 94 : #define SERIAL8250_SHARE_IRQS 1 95 : #else 96 : #define SERIAL8250_SHARE_IRQS 0 97 : #endif 98 : 99 : #define SERIAL8250_PORT_FLAGS(_base, _irq, _flags) \ 100 : { \ 101 : .iobase = _base, \ 102 : .irq = _irq, \ 103 : .uartclk = 1843200, \ 104 : .iotype = UPIO_PORT, \ 105 : .flags = UPF_BOOT_AUTOCONF | (_flags), \ 106 : } 107 : 108 : #define SERIAL8250_PORT(_base, _irq) SERIAL8250_PORT_FLAGS(_base, _irq, 0) 109 : 110 : 111 0 : static inline int serial_in(struct uart_8250_port *up, int offset) 112 : { 113 14705 : return up->port.serial_in(&up->port, offset); 114 : } 115 : 116 10276 : static inline void serial_out(struct uart_8250_port *up, int offset, int value) 117 : { 118 9845 : up->port.serial_out(&up->port, offset, value); 119 3 : } 120 : 121 : void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p); 122 : 123 : static inline int serial_dl_read(struct uart_8250_port *up) 124 : { 125 : return up->dl_read(up); 126 : } 127 : 128 2 : static inline void serial_dl_write(struct uart_8250_port *up, int value) 129 : { 130 2 : up->dl_write(up, value); 131 : } 132 : 133 397 : static inline bool serial8250_set_THRI(struct uart_8250_port *up) 134 : { 135 397 : if (up->ier & UART_IER_THRI) 136 : return false; 137 208 : up->ier |= UART_IER_THRI; 138 208 : serial_out(up, UART_IER, up->ier); 139 208 : return true; 140 : } 141 : 142 208 : static inline bool serial8250_clear_THRI(struct uart_8250_port *up) 143 : { 144 208 : if (!(up->ier & UART_IER_THRI)) 145 : return false; 146 208 : up->ier &= ~UART_IER_THRI; 147 208 : serial_out(up, UART_IER, up->ier); 148 208 : return true; 149 : } 150 : 151 : struct uart_8250_port *serial8250_get_port(int line); 152 : 153 : void serial8250_rpm_get(struct uart_8250_port *p); 154 : void serial8250_rpm_put(struct uart_8250_port *p); 155 : 156 : void serial8250_rpm_get_tx(struct uart_8250_port *p); 157 : void serial8250_rpm_put_tx(struct uart_8250_port *p); 158 : 159 : int serial8250_em485_config(struct uart_port *port, struct serial_rs485 *rs485); 160 : void serial8250_em485_start_tx(struct uart_8250_port *p); 161 : void serial8250_em485_stop_tx(struct uart_8250_port *p); 162 : void serial8250_em485_destroy(struct uart_8250_port *p); 163 : 164 : /* MCR <-> TIOCM conversion */ 165 5 : static inline int serial8250_TIOCM_to_MCR(int tiocm) 166 : { 167 5 : int mcr = 0; 168 : 169 5 : if (tiocm & TIOCM_RTS) 170 1 : mcr |= UART_MCR_RTS; 171 5 : if (tiocm & TIOCM_DTR) 172 5 : mcr |= UART_MCR_DTR; 173 5 : if (tiocm & TIOCM_OUT1) 174 0 : mcr |= UART_MCR_OUT1; 175 5 : if (tiocm & TIOCM_OUT2) 176 3 : mcr |= UART_MCR_OUT2; 177 5 : if (tiocm & TIOCM_LOOP) 178 0 : mcr |= UART_MCR_LOOP; 179 : 180 5 : return mcr; 181 : } 182 : 183 : static inline int serial8250_MCR_to_TIOCM(int mcr) 184 : { 185 : int tiocm = 0; 186 : 187 : if (mcr & UART_MCR_RTS) 188 : tiocm |= TIOCM_RTS; 189 : if (mcr & UART_MCR_DTR) 190 : tiocm |= TIOCM_DTR; 191 : if (mcr & UART_MCR_OUT1) 192 : tiocm |= TIOCM_OUT1; 193 : if (mcr & UART_MCR_OUT2) 194 : tiocm |= TIOCM_OUT2; 195 : if (mcr & UART_MCR_LOOP) 196 : tiocm |= TIOCM_LOOP; 197 : 198 : return tiocm; 199 : } 200 : 201 : /* MSR <-> TIOCM conversion */ 202 0 : static inline int serial8250_MSR_to_TIOCM(int msr) 203 : { 204 0 : int tiocm = 0; 205 : 206 0 : if (msr & UART_MSR_DCD) 207 0 : tiocm |= TIOCM_CAR; 208 0 : if (msr & UART_MSR_RI) 209 0 : tiocm |= TIOCM_RNG; 210 0 : if (msr & UART_MSR_DSR) 211 0 : tiocm |= TIOCM_DSR; 212 0 : if (msr & UART_MSR_CTS) 213 0 : tiocm |= TIOCM_CTS; 214 : 215 0 : return tiocm; 216 : } 217 : 218 6 : static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) 219 : { 220 6 : serial_out(up, UART_MCR, value); 221 : 222 6 : if (up->gpios) 223 1 : mctrl_gpio_set(up->gpios, serial8250_MCR_to_TIOCM(value)); 224 0 : } 225 : 226 1 : static inline int serial8250_in_MCR(struct uart_8250_port *up) 227 : { 228 1 : int mctrl; 229 : 230 1 : mctrl = serial_in(up, UART_MCR); 231 : 232 1 : if (up->gpios) { 233 0 : unsigned int mctrl_gpio = 0; 234 : 235 0 : mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio); 236 0 : mctrl |= serial8250_TIOCM_to_MCR(mctrl_gpio); 237 : } 238 : 239 1 : return mctrl; 240 : } 241 : 242 : #if defined(__alpha__) && !defined(CONFIG_PCI) 243 : /* 244 : * Digital did something really horribly wrong with the OUT1 and OUT2 245 : * lines on at least some ALPHA's. The failure mode is that if either 246 : * is cleared, the machine locks up with endless interrupts. 247 : */ 248 : #define ALPHA_KLUDGE_MCR (UART_MCR_OUT2 | UART_MCR_OUT1) 249 : #else 250 : #define ALPHA_KLUDGE_MCR 0 251 : #endif 252 : 253 : #ifdef CONFIG_SERIAL_8250_PNP 254 : int serial8250_pnp_init(void); 255 : void serial8250_pnp_exit(void); 256 : #else 257 1 : static inline int serial8250_pnp_init(void) { return 0; } 258 0 : static inline void serial8250_pnp_exit(void) { } 259 : #endif 260 : 261 : #ifdef CONFIG_SERIAL_8250_FINTEK 262 : int fintek_8250_probe(struct uart_8250_port *uart); 263 : #else 264 : static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; } 265 : #endif 266 : 267 : #ifdef CONFIG_ARCH_OMAP1 268 : static inline int is_omap1_8250(struct uart_8250_port *pt) 269 : { 270 : int res; 271 : 272 : switch (pt->port.mapbase) { 273 : case OMAP1_UART1_BASE: 274 : case OMAP1_UART2_BASE: 275 : case OMAP1_UART3_BASE: 276 : res = 1; 277 : break; 278 : default: 279 : res = 0; 280 : break; 281 : } 282 : 283 : return res; 284 : } 285 : 286 : static inline int is_omap1510_8250(struct uart_8250_port *pt) 287 : { 288 : if (!cpu_is_omap1510()) 289 : return 0; 290 : 291 : return is_omap1_8250(pt); 292 : } 293 : #else 294 7 : static inline int is_omap1_8250(struct uart_8250_port *pt) 295 : { 296 7 : return 0; 297 : } 298 2 : static inline int is_omap1510_8250(struct uart_8250_port *pt) 299 : { 300 2 : return 0; 301 : } 302 : #endif 303 : 304 : #ifdef CONFIG_SERIAL_8250_DMA 305 : extern int serial8250_tx_dma(struct uart_8250_port *); 306 : extern int serial8250_rx_dma(struct uart_8250_port *); 307 : extern void serial8250_rx_dma_flush(struct uart_8250_port *); 308 : extern int serial8250_request_dma(struct uart_8250_port *); 309 : extern void serial8250_release_dma(struct uart_8250_port *); 310 : #else 311 0 : static inline int serial8250_tx_dma(struct uart_8250_port *p) 312 : { 313 0 : return -1; 314 : } 315 0 : static inline int serial8250_rx_dma(struct uart_8250_port *p) 316 : { 317 0 : return -1; 318 : } 319 : static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { } 320 0 : static inline int serial8250_request_dma(struct uart_8250_port *p) 321 : { 322 0 : return -1; 323 : } 324 : static inline void serial8250_release_dma(struct uart_8250_port *p) { } 325 : #endif 326 : 327 0 : static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) 328 : { 329 0 : unsigned char status; 330 : 331 0 : status = serial_in(up, 0x04); /* EXCR2 */ 332 : #define PRESL(x) ((x) & 0x30) 333 0 : if (PRESL(status) == 0x10) { 334 : /* already in high speed mode */ 335 : return 0; 336 : } else { 337 0 : status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ 338 0 : status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ 339 0 : serial_out(up, 0x04, status); 340 : } 341 0 : return 1; 342 : } 343 : 344 : static inline int serial_index(struct uart_port *port) 345 : { 346 : return port->minor - 64; 347 : }