Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: serial: add Freescale lpuart driver support

Add Freescale lpuart driver support. The lpuart device
can be found on Vybrid VF610 and Layerscape LS-1 SoCs.

Signed-off-by: Jingchang Lu <b35083@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jingchang Lu and committed by
Greg Kroah-Hartman
c9e2e946 1ba7055a

+906
+14
Documentation/devicetree/bindings/tty/serial/fsl-lpuart.txt
··· 1 + * Freescale low power universal asynchronous receiver/transmitter (lpuart) 2 + 3 + Required properties: 4 + - compatible : Should be "fsl,<soc>-lpuart" 5 + - reg : Address and length of the register set for the device 6 + - interrupts : Should contain uart interrupt 7 + 8 + Example: 9 + 10 + uart0: serial@40027000 { 11 + compatible = "fsl,vf610-lpuart"; 12 + reg = <0x40027000 0x1000>; 13 + interrupts = <0 61 0x00>; 14 + };
+14
drivers/tty/serial/Kconfig
··· 1483 1483 If multiple cards are present, the default limit of 32 ports may 1484 1484 need to be increased. 1485 1485 1486 + config SERIAL_FSL_LPUART 1487 + tristate "Freescale lpuart serial port support" 1488 + select SERIAL_CORE 1489 + help 1490 + Support for the on-chip lpuart on some Freescale SOCs. 1491 + 1492 + config SERIAL_FSL_LPUART_CONSOLE 1493 + bool "Console on Freescale lpuart serial port" 1494 + depends on SERIAL_FSL_LPUART=y 1495 + select SERIAL_CORE_CONSOLE 1496 + help 1497 + If you have enabled the lpuart serial port on the Freescale SoCs, 1498 + you can make it the console by answering Y to this option. 1499 + 1486 1500 endmenu 1487 1501 1488 1502 endif # TTY
+1
drivers/tty/serial/Makefile
··· 85 85 obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o 86 86 obj-$(CONFIG_SERIAL_ARC) += arc_uart.o 87 87 obj-$(CONFIG_SERIAL_RP2) += rp2.o 88 + obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o
+874
drivers/tty/serial/fsl_lpuart.c
··· 1 + /* 2 + * Freescale lpuart serial port driver 3 + * 4 + * Copyright 2012-2013 Freescale Semiconductor, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + */ 11 + 12 + #if defined(CONFIG_SERIAL_FSL_LPUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 13 + #define SUPPORT_SYSRQ 14 + #endif 15 + 16 + #include <linux/module.h> 17 + #include <linux/io.h> 18 + #include <linux/irq.h> 19 + #include <linux/clk.h> 20 + #include <linux/of.h> 21 + #include <linux/of_device.h> 22 + #include <linux/console.h> 23 + #include <linux/serial_core.h> 24 + #include <linux/tty_flip.h> 25 + 26 + /* All registers are 8-bit width */ 27 + #define UARTBDH 0x00 28 + #define UARTBDL 0x01 29 + #define UARTCR1 0x02 30 + #define UARTCR2 0x03 31 + #define UARTSR1 0x04 32 + #define UARTCR3 0x06 33 + #define UARTDR 0x07 34 + #define UARTCR4 0x0a 35 + #define UARTCR5 0x0b 36 + #define UARTMODEM 0x0d 37 + #define UARTPFIFO 0x10 38 + #define UARTCFIFO 0x11 39 + #define UARTSFIFO 0x12 40 + #define UARTTWFIFO 0x13 41 + #define UARTTCFIFO 0x14 42 + #define UARTRWFIFO 0x15 43 + 44 + #define UARTBDH_LBKDIE 0x80 45 + #define UARTBDH_RXEDGIE 0x40 46 + #define UARTBDH_SBR_MASK 0x1f 47 + 48 + #define UARTCR1_LOOPS 0x80 49 + #define UARTCR1_RSRC 0x20 50 + #define UARTCR1_M 0x10 51 + #define UARTCR1_WAKE 0x08 52 + #define UARTCR1_ILT 0x04 53 + #define UARTCR1_PE 0x02 54 + #define UARTCR1_PT 0x01 55 + 56 + #define UARTCR2_TIE 0x80 57 + #define UARTCR2_TCIE 0x40 58 + #define UARTCR2_RIE 0x20 59 + #define UARTCR2_ILIE 0x10 60 + #define UARTCR2_TE 0x08 61 + #define UARTCR2_RE 0x04 62 + #define UARTCR2_RWU 0x02 63 + #define UARTCR2_SBK 0x01 64 + 65 + #define UARTSR1_TDRE 0x80 66 + #define UARTSR1_TC 0x40 67 + #define UARTSR1_RDRF 0x20 68 + #define UARTSR1_IDLE 0x10 69 + #define UARTSR1_OR 0x08 70 + #define UARTSR1_NF 0x04 71 + #define UARTSR1_FE 0x02 72 + #define UARTSR1_PE 0x01 73 + 74 + #define UARTCR3_R8 0x80 75 + #define UARTCR3_T8 0x40 76 + #define UARTCR3_TXDIR 0x20 77 + #define UARTCR3_TXINV 0x10 78 + #define UARTCR3_ORIE 0x08 79 + #define UARTCR3_NEIE 0x04 80 + #define UARTCR3_FEIE 0x02 81 + #define UARTCR3_PEIE 0x01 82 + 83 + #define UARTCR4_MAEN1 0x80 84 + #define UARTCR4_MAEN2 0x40 85 + #define UARTCR4_M10 0x20 86 + #define UARTCR4_BRFA_MASK 0x1f 87 + #define UARTCR4_BRFA_OFF 0 88 + 89 + #define UARTCR5_TDMAS 0x80 90 + #define UARTCR5_RDMAS 0x20 91 + 92 + #define UARTMODEM_RXRTSE 0x08 93 + #define UARTMODEM_TXRTSPOL 0x04 94 + #define UARTMODEM_TXRTSE 0x02 95 + #define UARTMODEM_TXCTSE 0x01 96 + 97 + #define UARTPFIFO_TXFE 0x80 98 + #define UARTPFIFO_FIFOSIZE_MASK 0x7 99 + #define UARTPFIFO_TXSIZE_OFF 4 100 + #define UARTPFIFO_RXFE 0x08 101 + #define UARTPFIFO_RXSIZE_OFF 0 102 + 103 + #define UARTCFIFO_TXFLUSH 0x80 104 + #define UARTCFIFO_RXFLUSH 0x40 105 + #define UARTCFIFO_RXOFE 0x04 106 + #define UARTCFIFO_TXOFE 0x02 107 + #define UARTCFIFO_RXUFE 0x01 108 + 109 + #define UARTSFIFO_TXEMPT 0x80 110 + #define UARTSFIFO_RXEMPT 0x40 111 + #define UARTSFIFO_RXOF 0x04 112 + #define UARTSFIFO_TXOF 0x02 113 + #define UARTSFIFO_RXUF 0x01 114 + 115 + #define DRIVER_NAME "fsl-lpuart" 116 + #define DEV_NAME "ttyLP" 117 + #define UART_NR 6 118 + 119 + struct lpuart_port { 120 + struct uart_port port; 121 + struct clk *clk; 122 + unsigned int txfifo_size; 123 + unsigned int rxfifo_size; 124 + }; 125 + 126 + static struct of_device_id lpuart_dt_ids[] = { 127 + { 128 + .compatible = "fsl,vf610-lpuart", 129 + }, 130 + { /* sentinel */ } 131 + }; 132 + MODULE_DEVICE_TABLE(of, lpuart_dt_ids); 133 + 134 + static void lpuart_stop_tx(struct uart_port *port) 135 + { 136 + unsigned char temp; 137 + 138 + temp = readb(port->membase + UARTCR2); 139 + temp &= ~(UARTCR2_TIE | UARTCR2_TCIE); 140 + writeb(temp, port->membase + UARTCR2); 141 + } 142 + 143 + static void lpuart_stop_rx(struct uart_port *port) 144 + { 145 + unsigned char temp; 146 + 147 + temp = readb(port->membase + UARTCR2); 148 + writeb(temp & ~UARTCR2_RE, port->membase + UARTCR2); 149 + } 150 + 151 + static void lpuart_enable_ms(struct uart_port *port) 152 + { 153 + } 154 + 155 + static inline void lpuart_transmit_buffer(struct lpuart_port *sport) 156 + { 157 + struct circ_buf *xmit = &sport->port.state->xmit; 158 + 159 + while (!uart_circ_empty(xmit) && 160 + (readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size)) { 161 + writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR); 162 + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 163 + sport->port.icount.tx++; 164 + } 165 + 166 + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 167 + uart_write_wakeup(&sport->port); 168 + 169 + if (uart_circ_empty(xmit)) 170 + lpuart_stop_tx(&sport->port); 171 + } 172 + 173 + static void lpuart_start_tx(struct uart_port *port) 174 + { 175 + struct lpuart_port *sport = container_of(port, struct lpuart_port, port); 176 + unsigned char temp; 177 + 178 + temp = readb(port->membase + UARTCR2); 179 + writeb(temp | UARTCR2_TIE, port->membase + UARTCR2); 180 + 181 + if (readb(port->membase + UARTSR1) & UARTSR1_TDRE) 182 + lpuart_transmit_buffer(sport); 183 + } 184 + 185 + static irqreturn_t lpuart_txint(int irq, void *dev_id) 186 + { 187 + struct lpuart_port *sport = dev_id; 188 + struct circ_buf *xmit = &sport->port.state->xmit; 189 + unsigned long flags; 190 + 191 + spin_lock_irqsave(&sport->port.lock, flags); 192 + if (sport->port.x_char) { 193 + writeb(sport->port.x_char, sport->port.membase + UARTDR); 194 + goto out; 195 + } 196 + 197 + if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { 198 + lpuart_stop_tx(&sport->port); 199 + goto out; 200 + } 201 + 202 + lpuart_transmit_buffer(sport); 203 + 204 + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 205 + uart_write_wakeup(&sport->port); 206 + 207 + out: 208 + spin_unlock_irqrestore(&sport->port.lock, flags); 209 + return IRQ_HANDLED; 210 + } 211 + 212 + static irqreturn_t lpuart_rxint(int irq, void *dev_id) 213 + { 214 + struct lpuart_port *sport = dev_id; 215 + unsigned int flg, ignored = 0; 216 + struct tty_port *port = &sport->port.state->port; 217 + unsigned long flags; 218 + unsigned char rx, sr; 219 + 220 + spin_lock_irqsave(&sport->port.lock, flags); 221 + 222 + while (!(readb(sport->port.membase + UARTSFIFO) & UARTSFIFO_RXEMPT)) { 223 + flg = TTY_NORMAL; 224 + sport->port.icount.rx++; 225 + /* 226 + * to clear the FE, OR, NF, FE, PE flags, 227 + * read SR1 then read DR 228 + */ 229 + sr = readb(sport->port.membase + UARTSR1); 230 + rx = readb(sport->port.membase + UARTDR); 231 + 232 + if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx)) 233 + continue; 234 + 235 + if (sr & (UARTSR1_PE | UARTSR1_OR | UARTSR1_FE)) { 236 + if (sr & UARTSR1_PE) 237 + sport->port.icount.parity++; 238 + else if (sr & UARTSR1_FE) 239 + sport->port.icount.frame++; 240 + 241 + if (sr & UARTSR1_OR) 242 + sport->port.icount.overrun++; 243 + 244 + if (sr & sport->port.ignore_status_mask) { 245 + if (++ignored > 100) 246 + goto out; 247 + continue; 248 + } 249 + 250 + sr &= sport->port.read_status_mask; 251 + 252 + if (sr & UARTSR1_PE) 253 + flg = TTY_PARITY; 254 + else if (sr & UARTSR1_FE) 255 + flg = TTY_FRAME; 256 + 257 + if (sr & UARTSR1_OR) 258 + flg = TTY_OVERRUN; 259 + 260 + #ifdef SUPPORT_SYSRQ 261 + sport->port.sysrq = 0; 262 + #endif 263 + } 264 + 265 + tty_insert_flip_char(port, rx, flg); 266 + } 267 + 268 + out: 269 + spin_unlock_irqrestore(&sport->port.lock, flags); 270 + 271 + tty_flip_buffer_push(port); 272 + return IRQ_HANDLED; 273 + } 274 + 275 + static irqreturn_t lpuart_int(int irq, void *dev_id) 276 + { 277 + struct lpuart_port *sport = dev_id; 278 + unsigned char sts; 279 + 280 + sts = readb(sport->port.membase + UARTSR1); 281 + 282 + if (sts & UARTSR1_RDRF) 283 + lpuart_rxint(irq, dev_id); 284 + 285 + if (sts & UARTSR1_TDRE && 286 + !(readb(sport->port.membase + UARTCR5) & UARTCR5_TDMAS)) 287 + lpuart_txint(irq, dev_id); 288 + 289 + return IRQ_HANDLED; 290 + } 291 + 292 + /* return TIOCSER_TEMT when transmitter is not busy */ 293 + static unsigned int lpuart_tx_empty(struct uart_port *port) 294 + { 295 + return (readb(port->membase + UARTSR1) & UARTSR1_TC) ? 296 + TIOCSER_TEMT : 0; 297 + } 298 + 299 + static unsigned int lpuart_get_mctrl(struct uart_port *port) 300 + { 301 + unsigned int temp = 0; 302 + unsigned char reg; 303 + 304 + reg = readb(port->membase + UARTMODEM); 305 + if (reg & UARTMODEM_TXCTSE) 306 + temp |= TIOCM_CTS; 307 + 308 + if (reg & UARTMODEM_RXRTSE) 309 + temp |= TIOCM_RTS; 310 + 311 + return temp; 312 + } 313 + 314 + static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) 315 + { 316 + unsigned char temp; 317 + 318 + temp = readb(port->membase + UARTMODEM) & 319 + ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); 320 + 321 + if (mctrl & TIOCM_RTS) 322 + temp |= UARTMODEM_RXRTSE; 323 + 324 + if (mctrl & TIOCM_CTS) 325 + temp |= UARTMODEM_TXCTSE; 326 + 327 + writeb(temp, port->membase + UARTMODEM); 328 + } 329 + 330 + static void lpuart_break_ctl(struct uart_port *port, int break_state) 331 + { 332 + unsigned char temp; 333 + 334 + temp = readb(port->membase + UARTCR2) & ~UARTCR2_SBK; 335 + 336 + if (break_state != 0) 337 + temp |= UARTCR2_SBK; 338 + 339 + writeb(temp, port->membase + UARTCR2); 340 + } 341 + 342 + static void lpuart_setup_watermark(struct lpuart_port *sport) 343 + { 344 + unsigned char val, cr2; 345 + 346 + cr2 = readb(sport->port.membase + UARTCR2); 347 + cr2 &= ~(UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_TE | 348 + UARTCR2_RIE | UARTCR2_RE); 349 + writeb(cr2, sport->port.membase + UARTCR2); 350 + 351 + /* determine FIFO size and enable FIFO mode */ 352 + val = readb(sport->port.membase + UARTPFIFO); 353 + 354 + sport->txfifo_size = 0x1 << (((val >> UARTPFIFO_TXSIZE_OFF) & 355 + UARTPFIFO_FIFOSIZE_MASK) + 1); 356 + 357 + sport->rxfifo_size = 0x1 << (((val >> UARTPFIFO_RXSIZE_OFF) & 358 + UARTPFIFO_FIFOSIZE_MASK) + 1); 359 + 360 + writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE, 361 + sport->port.membase + UARTPFIFO); 362 + 363 + /* flush Tx and Rx FIFO */ 364 + writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH, 365 + sport->port.membase + UARTCFIFO); 366 + 367 + writeb(2, sport->port.membase + UARTTWFIFO); 368 + writeb(1, sport->port.membase + UARTRWFIFO); 369 + } 370 + 371 + static int lpuart_startup(struct uart_port *port) 372 + { 373 + struct lpuart_port *sport = container_of(port, struct lpuart_port, port); 374 + int ret; 375 + unsigned long flags; 376 + unsigned char temp; 377 + 378 + ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0, 379 + DRIVER_NAME, sport); 380 + if (ret) 381 + return ret; 382 + 383 + spin_lock_irqsave(&sport->port.lock, flags); 384 + 385 + lpuart_setup_watermark(sport); 386 + 387 + temp = readb(sport->port.membase + UARTCR2); 388 + temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE); 389 + writeb(temp, sport->port.membase + UARTCR2); 390 + 391 + spin_unlock_irqrestore(&sport->port.lock, flags); 392 + return 0; 393 + } 394 + 395 + static void lpuart_shutdown(struct uart_port *port) 396 + { 397 + struct lpuart_port *sport = container_of(port, struct lpuart_port, port); 398 + unsigned char temp; 399 + unsigned long flags; 400 + 401 + spin_lock_irqsave(&port->lock, flags); 402 + 403 + /* disable Rx/Tx and interrupts */ 404 + temp = readb(port->membase + UARTCR2); 405 + temp &= ~(UARTCR2_TE | UARTCR2_RE | 406 + UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE); 407 + writeb(temp, port->membase + UARTCR2); 408 + 409 + spin_unlock_irqrestore(&port->lock, flags); 410 + 411 + devm_free_irq(port->dev, port->irq, sport); 412 + } 413 + 414 + static void 415 + lpuart_set_termios(struct uart_port *port, struct ktermios *termios, 416 + struct ktermios *old) 417 + { 418 + struct lpuart_port *sport = container_of(port, struct lpuart_port, port); 419 + unsigned long flags; 420 + unsigned char cr1, old_cr1, old_cr2, cr4, bdh, modem; 421 + unsigned int baud; 422 + unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; 423 + unsigned int sbr, brfa; 424 + 425 + cr1 = old_cr1 = readb(sport->port.membase + UARTCR1); 426 + old_cr2 = readb(sport->port.membase + UARTCR2); 427 + cr4 = readb(sport->port.membase + UARTCR4); 428 + bdh = readb(sport->port.membase + UARTBDH); 429 + modem = readb(sport->port.membase + UARTMODEM); 430 + /* 431 + * only support CS8 and CS7, and for CS7 must enable PE. 432 + * supported mode: 433 + * - (7,e/o,1) 434 + * - (8,n,1) 435 + * - (8,m/s,1) 436 + * - (8,e/o,1) 437 + */ 438 + while ((termios->c_cflag & CSIZE) != CS8 && 439 + (termios->c_cflag & CSIZE) != CS7) { 440 + termios->c_cflag &= ~CSIZE; 441 + termios->c_cflag |= old_csize; 442 + old_csize = CS8; 443 + } 444 + 445 + if ((termios->c_cflag & CSIZE) == CS8 || 446 + (termios->c_cflag & CSIZE) == CS7) 447 + cr1 = old_cr1 & ~UARTCR1_M; 448 + 449 + if (termios->c_cflag & CMSPAR) { 450 + if ((termios->c_cflag & CSIZE) != CS8) { 451 + termios->c_cflag &= ~CSIZE; 452 + termios->c_cflag |= CS8; 453 + } 454 + cr1 |= UARTCR1_M; 455 + } 456 + 457 + if (termios->c_cflag & CRTSCTS) { 458 + modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); 459 + } else { 460 + termios->c_cflag &= ~CRTSCTS; 461 + modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); 462 + } 463 + 464 + if (termios->c_cflag & CSTOPB) 465 + termios->c_cflag &= ~CSTOPB; 466 + 467 + /* parity must be enabled when CS7 to match 8-bits format */ 468 + if ((termios->c_cflag & CSIZE) == CS7) 469 + termios->c_cflag |= PARENB; 470 + 471 + if ((termios->c_cflag & PARENB)) { 472 + if (termios->c_cflag & CMSPAR) { 473 + cr1 &= ~UARTCR1_PE; 474 + cr1 |= UARTCR1_M; 475 + } else { 476 + cr1 |= UARTCR1_PE; 477 + if ((termios->c_cflag & CSIZE) == CS8) 478 + cr1 |= UARTCR1_M; 479 + if (termios->c_cflag & PARODD) 480 + cr1 |= UARTCR1_PT; 481 + else 482 + cr1 &= ~UARTCR1_PT; 483 + } 484 + } 485 + 486 + /* ask the core to calculate the divisor */ 487 + baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); 488 + 489 + spin_lock_irqsave(&sport->port.lock, flags); 490 + 491 + sport->port.read_status_mask = 0; 492 + if (termios->c_iflag & INPCK) 493 + sport->port.read_status_mask |= (UARTSR1_FE | UARTSR1_PE); 494 + if (termios->c_iflag & (BRKINT | PARMRK)) 495 + sport->port.read_status_mask |= UARTSR1_FE; 496 + 497 + /* characters to ignore */ 498 + sport->port.ignore_status_mask = 0; 499 + if (termios->c_iflag & IGNPAR) 500 + sport->port.ignore_status_mask |= UARTSR1_PE; 501 + if (termios->c_iflag & IGNBRK) { 502 + sport->port.ignore_status_mask |= UARTSR1_FE; 503 + /* 504 + * if we're ignoring parity and break indicators, 505 + * ignore overruns too (for real raw support). 506 + */ 507 + if (termios->c_iflag & IGNPAR) 508 + sport->port.ignore_status_mask |= UARTSR1_OR; 509 + } 510 + 511 + /* update the per-port timeout */ 512 + uart_update_timeout(port, termios->c_cflag, baud); 513 + 514 + /* wait transmit engin complete */ 515 + while (!(readb(sport->port.membase + UARTSR1) & UARTSR1_TC)) 516 + barrier(); 517 + 518 + /* disable transmit and receive */ 519 + writeb(old_cr2 & ~(UARTCR2_TE | UARTCR2_RE), 520 + sport->port.membase + UARTCR2); 521 + 522 + sbr = sport->port.uartclk / (16 * baud); 523 + brfa = ((sport->port.uartclk - (16 * sbr * baud)) * 2) / baud; 524 + bdh &= ~UARTBDH_SBR_MASK; 525 + bdh |= (sbr >> 8) & 0x1F; 526 + cr4 &= ~UARTCR4_BRFA_MASK; 527 + brfa &= UARTCR4_BRFA_MASK; 528 + writeb(cr4 | brfa, sport->port.membase + UARTCR4); 529 + writeb(bdh, sport->port.membase + UARTBDH); 530 + writeb(sbr & 0xFF, sport->port.membase + UARTBDL); 531 + writeb(cr1, sport->port.membase + UARTCR1); 532 + writeb(modem, sport->port.membase + UARTMODEM); 533 + 534 + /* restore control register */ 535 + writeb(old_cr2, sport->port.membase + UARTCR2); 536 + 537 + spin_unlock_irqrestore(&sport->port.lock, flags); 538 + } 539 + 540 + static const char *lpuart_type(struct uart_port *port) 541 + { 542 + return "FSL_LPUART"; 543 + } 544 + 545 + static void lpuart_release_port(struct uart_port *port) 546 + { 547 + /* nothing to do */ 548 + } 549 + 550 + static int lpuart_request_port(struct uart_port *port) 551 + { 552 + return 0; 553 + } 554 + 555 + /* configure/autoconfigure the port */ 556 + static void lpuart_config_port(struct uart_port *port, int flags) 557 + { 558 + if (flags & UART_CONFIG_TYPE) 559 + port->type = PORT_LPUART; 560 + } 561 + 562 + static int lpuart_verify_port(struct uart_port *port, struct serial_struct *ser) 563 + { 564 + int ret = 0; 565 + 566 + if (ser->type != PORT_UNKNOWN && ser->type != PORT_LPUART) 567 + ret = -EINVAL; 568 + if (port->irq != ser->irq) 569 + ret = -EINVAL; 570 + if (ser->io_type != UPIO_MEM) 571 + ret = -EINVAL; 572 + if (port->uartclk / 16 != ser->baud_base) 573 + ret = -EINVAL; 574 + if (port->iobase != ser->port) 575 + ret = -EINVAL; 576 + if (ser->hub6 != 0) 577 + ret = -EINVAL; 578 + return ret; 579 + } 580 + 581 + static struct uart_ops lpuart_pops = { 582 + .tx_empty = lpuart_tx_empty, 583 + .set_mctrl = lpuart_set_mctrl, 584 + .get_mctrl = lpuart_get_mctrl, 585 + .stop_tx = lpuart_stop_tx, 586 + .start_tx = lpuart_start_tx, 587 + .stop_rx = lpuart_stop_rx, 588 + .enable_ms = lpuart_enable_ms, 589 + .break_ctl = lpuart_break_ctl, 590 + .startup = lpuart_startup, 591 + .shutdown = lpuart_shutdown, 592 + .set_termios = lpuart_set_termios, 593 + .type = lpuart_type, 594 + .request_port = lpuart_request_port, 595 + .release_port = lpuart_release_port, 596 + .config_port = lpuart_config_port, 597 + .verify_port = lpuart_verify_port, 598 + }; 599 + 600 + static struct lpuart_port *lpuart_ports[UART_NR]; 601 + 602 + #ifdef CONFIG_SERIAL_FSL_LPUART_CONSOLE 603 + static void lpuart_console_putchar(struct uart_port *port, int ch) 604 + { 605 + while (!(readb(port->membase + UARTSR1) & UARTSR1_TDRE)) 606 + barrier(); 607 + 608 + writeb(ch, port->membase + UARTDR); 609 + } 610 + 611 + static void 612 + lpuart_console_write(struct console *co, const char *s, unsigned int count) 613 + { 614 + struct lpuart_port *sport = lpuart_ports[co->index]; 615 + unsigned char old_cr2, cr2; 616 + 617 + /* first save CR2 and then disable interrupts */ 618 + cr2 = old_cr2 = readb(sport->port.membase + UARTCR2); 619 + cr2 |= (UARTCR2_TE | UARTCR2_RE); 620 + cr2 &= ~(UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE); 621 + writeb(cr2, sport->port.membase + UARTCR2); 622 + 623 + uart_console_write(&sport->port, s, count, lpuart_console_putchar); 624 + 625 + /* wait for transmitter finish complete and restore CR2 */ 626 + while (!(readb(sport->port.membase + UARTSR1) & UARTSR1_TC)) 627 + barrier(); 628 + 629 + writeb(old_cr2, sport->port.membase + UARTCR2); 630 + } 631 + 632 + /* 633 + * if the port was already initialised (eg, by a boot loader), 634 + * try to determine the current setup. 635 + */ 636 + static void __init 637 + lpuart_console_get_options(struct lpuart_port *sport, int *baud, 638 + int *parity, int *bits) 639 + { 640 + unsigned char cr, bdh, bdl, brfa; 641 + unsigned int sbr, uartclk, baud_raw; 642 + 643 + cr = readb(sport->port.membase + UARTCR2); 644 + cr &= UARTCR2_TE | UARTCR2_RE; 645 + if (!cr) 646 + return; 647 + 648 + /* ok, the port was enabled */ 649 + 650 + cr = readb(sport->port.membase + UARTCR1); 651 + 652 + *parity = 'n'; 653 + if (cr & UARTCR1_PE) { 654 + if (cr & UARTCR1_PT) 655 + *parity = 'o'; 656 + else 657 + *parity = 'e'; 658 + } 659 + 660 + if (cr & UARTCR1_M) 661 + *bits = 9; 662 + else 663 + *bits = 8; 664 + 665 + bdh = readb(sport->port.membase + UARTBDH); 666 + bdh &= UARTBDH_SBR_MASK; 667 + bdl = readb(sport->port.membase + UARTBDL); 668 + sbr = bdh; 669 + sbr <<= 8; 670 + sbr |= bdl; 671 + brfa = readb(sport->port.membase + UARTCR4); 672 + brfa &= UARTCR4_BRFA_MASK; 673 + 674 + uartclk = clk_get_rate(sport->clk); 675 + /* 676 + * baud = mod_clk/(16*(sbr[13]+(brfa)/32) 677 + */ 678 + baud_raw = uartclk / (16 * (sbr + brfa / 32)); 679 + 680 + if (*baud != baud_raw) 681 + printk(KERN_INFO "Serial: Console lpuart rounded baud rate" 682 + "from %d to %d\n", baud_raw, *baud); 683 + } 684 + 685 + static int __init lpuart_console_setup(struct console *co, char *options) 686 + { 687 + struct lpuart_port *sport; 688 + int baud = 115200; 689 + int bits = 8; 690 + int parity = 'n'; 691 + int flow = 'n'; 692 + 693 + /* 694 + * check whether an invalid uart number has been specified, and 695 + * if so, search for the first available port that does have 696 + * console support. 697 + */ 698 + if (co->index == -1 || co->index >= ARRAY_SIZE(lpuart_ports)) 699 + co->index = 0; 700 + 701 + sport = lpuart_ports[co->index]; 702 + if (sport == NULL) 703 + return -ENODEV; 704 + 705 + if (options) 706 + uart_parse_options(options, &baud, &parity, &bits, &flow); 707 + else 708 + lpuart_console_get_options(sport, &baud, &parity, &bits); 709 + 710 + lpuart_setup_watermark(sport); 711 + 712 + return uart_set_options(&sport->port, co, baud, parity, bits, flow); 713 + } 714 + 715 + static struct uart_driver lpuart_reg; 716 + static struct console lpuart_console = { 717 + .name = DEV_NAME, 718 + .write = lpuart_console_write, 719 + .device = uart_console_device, 720 + .setup = lpuart_console_setup, 721 + .flags = CON_PRINTBUFFER, 722 + .index = -1, 723 + .data = &lpuart_reg, 724 + }; 725 + 726 + #define LPUART_CONSOLE (&lpuart_console) 727 + #else 728 + #define LPUART_CONSOLE NULL 729 + #endif 730 + 731 + static struct uart_driver lpuart_reg = { 732 + .owner = THIS_MODULE, 733 + .driver_name = DRIVER_NAME, 734 + .dev_name = DEV_NAME, 735 + .nr = ARRAY_SIZE(lpuart_ports), 736 + .cons = LPUART_CONSOLE, 737 + }; 738 + 739 + static int lpuart_probe(struct platform_device *pdev) 740 + { 741 + struct device_node *np = pdev->dev.of_node; 742 + struct lpuart_port *sport; 743 + struct resource *res; 744 + int ret; 745 + 746 + sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); 747 + if (!sport) 748 + return -ENOMEM; 749 + 750 + pdev->dev.coherent_dma_mask = 0; 751 + 752 + ret = of_alias_get_id(np, "serial"); 753 + if (ret < 0) { 754 + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); 755 + return ret; 756 + } 757 + sport->port.line = ret; 758 + 759 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 760 + if (!res) 761 + return -ENODEV; 762 + 763 + sport->port.mapbase = res->start; 764 + sport->port.membase = devm_ioremap_resource(&pdev->dev, res); 765 + if (IS_ERR(sport->port.membase)) 766 + return PTR_ERR(sport->port.membase); 767 + 768 + sport->port.dev = &pdev->dev; 769 + sport->port.type = PORT_LPUART; 770 + sport->port.iotype = UPIO_MEM; 771 + sport->port.irq = platform_get_irq(pdev, 0); 772 + sport->port.ops = &lpuart_pops; 773 + sport->port.flags = UPF_BOOT_AUTOCONF; 774 + 775 + sport->clk = devm_clk_get(&pdev->dev, "ipg"); 776 + if (IS_ERR(sport->clk)) { 777 + ret = PTR_ERR(sport->clk); 778 + dev_err(&pdev->dev, "failed to get uart clk: %d\n", ret); 779 + return ret; 780 + } 781 + 782 + ret = clk_prepare_enable(sport->clk); 783 + if (ret) { 784 + dev_err(&pdev->dev, "failed to enable uart clk: %d\n", ret); 785 + return ret; 786 + } 787 + 788 + sport->port.uartclk = clk_get_rate(sport->clk); 789 + 790 + lpuart_ports[sport->port.line] = sport; 791 + 792 + platform_set_drvdata(pdev, &sport->port); 793 + 794 + ret = uart_add_one_port(&lpuart_reg, &sport->port); 795 + if (ret) { 796 + clk_disable_unprepare(sport->clk); 797 + return ret; 798 + } 799 + 800 + return 0; 801 + } 802 + 803 + static int lpuart_remove(struct platform_device *pdev) 804 + { 805 + struct lpuart_port *sport = platform_get_drvdata(pdev); 806 + 807 + uart_remove_one_port(&lpuart_reg, &sport->port); 808 + 809 + clk_disable_unprepare(sport->clk); 810 + 811 + return 0; 812 + } 813 + 814 + #ifdef CONFIG_PM_SLEEP 815 + static int lpuart_suspend(struct device *dev) 816 + { 817 + struct lpuart_port *sport = dev_get_drvdata(dev); 818 + 819 + uart_suspend_port(&lpuart_reg, &sport->port); 820 + 821 + return 0; 822 + } 823 + 824 + static int lpuart_resume(struct device *dev) 825 + { 826 + struct lpuart_port *sport = dev_get_drvdata(dev); 827 + 828 + uart_resume_port(&lpuart_reg, &sport->port); 829 + 830 + return 0; 831 + } 832 + #endif 833 + 834 + static SIMPLE_DEV_PM_OPS(lpuart_pm_ops, lpuart_suspend, lpuart_resume); 835 + 836 + static struct platform_driver lpuart_driver = { 837 + .probe = lpuart_probe, 838 + .remove = lpuart_remove, 839 + .driver = { 840 + .name = "fsl-lpuart", 841 + .owner = THIS_MODULE, 842 + .of_match_table = lpuart_dt_ids, 843 + .pm = &lpuart_pm_ops, 844 + }, 845 + }; 846 + 847 + static int __init lpuart_serial_init(void) 848 + { 849 + int ret; 850 + 851 + pr_info("serial: Freescale lpuart driver\n"); 852 + 853 + ret = uart_register_driver(&lpuart_reg); 854 + if (ret) 855 + return ret; 856 + 857 + ret = platform_driver_register(&lpuart_driver); 858 + if (ret) 859 + uart_unregister_driver(&lpuart_reg); 860 + 861 + return 0; 862 + } 863 + 864 + static void __exit lpuart_serial_exit(void) 865 + { 866 + platform_driver_unregister(&lpuart_driver); 867 + uart_unregister_driver(&lpuart_reg); 868 + } 869 + 870 + module_init(lpuart_serial_init); 871 + module_exit(lpuart_serial_exit); 872 + 873 + MODULE_DESCRIPTION("Freescale lpuart serial port driver"); 874 + MODULE_LICENSE("GPL v2");
+3
include/uapi/linux/serial_core.h
··· 226 226 /* Rocketport EXPRESS/INFINITY */ 227 227 #define PORT_RP2 102 228 228 229 + /* Freescale lpuart */ 230 + #define PORT_LPUART 103 231 + 229 232 #endif /* _UAPILINUX_SERIAL_CORE_H */