mxs-auart.c revision f4b1f03b826ba22c9835e9e89a1ca03541313e04
1/* 2 * Freescale STMP37XX/STMP378X Application UART driver 3 * 4 * Author: dmitry pervushin <dimka@embeddedalley.com> 5 * 6 * Copyright 2008-2010 Freescale Semiconductor, Inc. 7 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. 8 * 9 * The code contained herein is licensed under the GNU General Public 10 * License. You may obtain a copy of the GNU General Public License 11 * Version 2 or later at the following locations: 12 * 13 * http://www.opensource.org/licenses/gpl-license.html 14 * http://www.gnu.org/copyleft/gpl.html 15 */ 16 17#include <linux/kernel.h> 18#include <linux/errno.h> 19#include <linux/init.h> 20#include <linux/console.h> 21#include <linux/interrupt.h> 22#include <linux/module.h> 23#include <linux/slab.h> 24#include <linux/wait.h> 25#include <linux/tty.h> 26#include <linux/tty_driver.h> 27#include <linux/tty_flip.h> 28#include <linux/serial.h> 29#include <linux/serial_core.h> 30#include <linux/platform_device.h> 31#include <linux/device.h> 32#include <linux/clk.h> 33#include <linux/delay.h> 34#include <linux/io.h> 35#include <linux/pinctrl/consumer.h> 36#include <linux/of_device.h> 37 38#include <asm/cacheflush.h> 39 40#define MXS_AUART_PORTS 5 41 42#define AUART_CTRL0 0x00000000 43#define AUART_CTRL0_SET 0x00000004 44#define AUART_CTRL0_CLR 0x00000008 45#define AUART_CTRL0_TOG 0x0000000c 46#define AUART_CTRL1 0x00000010 47#define AUART_CTRL1_SET 0x00000014 48#define AUART_CTRL1_CLR 0x00000018 49#define AUART_CTRL1_TOG 0x0000001c 50#define AUART_CTRL2 0x00000020 51#define AUART_CTRL2_SET 0x00000024 52#define AUART_CTRL2_CLR 0x00000028 53#define AUART_CTRL2_TOG 0x0000002c 54#define AUART_LINECTRL 0x00000030 55#define AUART_LINECTRL_SET 0x00000034 56#define AUART_LINECTRL_CLR 0x00000038 57#define AUART_LINECTRL_TOG 0x0000003c 58#define AUART_LINECTRL2 0x00000040 59#define AUART_LINECTRL2_SET 0x00000044 60#define AUART_LINECTRL2_CLR 0x00000048 61#define AUART_LINECTRL2_TOG 0x0000004c 62#define AUART_INTR 0x00000050 63#define AUART_INTR_SET 0x00000054 64#define AUART_INTR_CLR 0x00000058 65#define AUART_INTR_TOG 0x0000005c 66#define AUART_DATA 0x00000060 67#define AUART_STAT 0x00000070 68#define AUART_DEBUG 0x00000080 69#define AUART_VERSION 0x00000090 70#define AUART_AUTOBAUD 0x000000a0 71 72#define AUART_CTRL0_SFTRST (1 << 31) 73#define AUART_CTRL0_CLKGATE (1 << 30) 74 75#define AUART_CTRL2_CTSEN (1 << 15) 76#define AUART_CTRL2_RTSEN (1 << 14) 77#define AUART_CTRL2_RTS (1 << 11) 78#define AUART_CTRL2_RXE (1 << 9) 79#define AUART_CTRL2_TXE (1 << 8) 80#define AUART_CTRL2_UARTEN (1 << 0) 81 82#define AUART_LINECTRL_BAUD_DIVINT_SHIFT 16 83#define AUART_LINECTRL_BAUD_DIVINT_MASK 0xffff0000 84#define AUART_LINECTRL_BAUD_DIVINT(v) (((v) & 0xffff) << 16) 85#define AUART_LINECTRL_BAUD_DIVFRAC_SHIFT 8 86#define AUART_LINECTRL_BAUD_DIVFRAC_MASK 0x00003f00 87#define AUART_LINECTRL_BAUD_DIVFRAC(v) (((v) & 0x3f) << 8) 88#define AUART_LINECTRL_WLEN_MASK 0x00000060 89#define AUART_LINECTRL_WLEN(v) (((v) & 0x3) << 5) 90#define AUART_LINECTRL_FEN (1 << 4) 91#define AUART_LINECTRL_STP2 (1 << 3) 92#define AUART_LINECTRL_EPS (1 << 2) 93#define AUART_LINECTRL_PEN (1 << 1) 94#define AUART_LINECTRL_BRK (1 << 0) 95 96#define AUART_INTR_RTIEN (1 << 22) 97#define AUART_INTR_TXIEN (1 << 21) 98#define AUART_INTR_RXIEN (1 << 20) 99#define AUART_INTR_CTSMIEN (1 << 17) 100#define AUART_INTR_RTIS (1 << 6) 101#define AUART_INTR_TXIS (1 << 5) 102#define AUART_INTR_RXIS (1 << 4) 103#define AUART_INTR_CTSMIS (1 << 1) 104 105#define AUART_STAT_BUSY (1 << 29) 106#define AUART_STAT_CTS (1 << 28) 107#define AUART_STAT_TXFE (1 << 27) 108#define AUART_STAT_TXFF (1 << 25) 109#define AUART_STAT_RXFE (1 << 24) 110#define AUART_STAT_OERR (1 << 19) 111#define AUART_STAT_BERR (1 << 18) 112#define AUART_STAT_PERR (1 << 17) 113#define AUART_STAT_FERR (1 << 16) 114 115static struct uart_driver auart_driver; 116 117enum mxs_auart_type { 118 IMX23_AUART, 119 IMX28_AUART, 120}; 121 122struct mxs_auart_port { 123 struct uart_port port; 124 125 unsigned int flags; 126 unsigned int ctrl; 127 enum mxs_auart_type devtype; 128 129 unsigned int irq; 130 131 struct clk *clk; 132 struct device *dev; 133}; 134 135static struct platform_device_id mxs_auart_devtype[] = { 136 { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART }, 137 { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART }, 138 { /* sentinel */ } 139}; 140MODULE_DEVICE_TABLE(platform, mxs_auart_devtype); 141 142static struct of_device_id mxs_auart_dt_ids[] = { 143 { 144 .compatible = "fsl,imx28-auart", 145 .data = &mxs_auart_devtype[IMX28_AUART] 146 }, { 147 .compatible = "fsl,imx23-auart", 148 .data = &mxs_auart_devtype[IMX23_AUART] 149 }, { /* sentinel */ } 150}; 151MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); 152 153static inline int is_imx28_auart(struct mxs_auart_port *s) 154{ 155 return s->devtype == IMX28_AUART; 156} 157 158static void mxs_auart_stop_tx(struct uart_port *u); 159 160#define to_auart_port(u) container_of(u, struct mxs_auart_port, port) 161 162static inline void mxs_auart_tx_chars(struct mxs_auart_port *s) 163{ 164 struct circ_buf *xmit = &s->port.state->xmit; 165 166 while (!(readl(s->port.membase + AUART_STAT) & 167 AUART_STAT_TXFF)) { 168 if (s->port.x_char) { 169 s->port.icount.tx++; 170 writel(s->port.x_char, 171 s->port.membase + AUART_DATA); 172 s->port.x_char = 0; 173 continue; 174 } 175 if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { 176 s->port.icount.tx++; 177 writel(xmit->buf[xmit->tail], 178 s->port.membase + AUART_DATA); 179 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 180 } else 181 break; 182 } 183 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 184 uart_write_wakeup(&s->port); 185 186 if (uart_circ_empty(&(s->port.state->xmit))) 187 writel(AUART_INTR_TXIEN, 188 s->port.membase + AUART_INTR_CLR); 189 else 190 writel(AUART_INTR_TXIEN, 191 s->port.membase + AUART_INTR_SET); 192 193 if (uart_tx_stopped(&s->port)) 194 mxs_auart_stop_tx(&s->port); 195} 196 197static void mxs_auart_rx_char(struct mxs_auart_port *s) 198{ 199 int flag; 200 u32 stat; 201 u8 c; 202 203 c = readl(s->port.membase + AUART_DATA); 204 stat = readl(s->port.membase + AUART_STAT); 205 206 flag = TTY_NORMAL; 207 s->port.icount.rx++; 208 209 if (stat & AUART_STAT_BERR) { 210 s->port.icount.brk++; 211 if (uart_handle_break(&s->port)) 212 goto out; 213 } else if (stat & AUART_STAT_PERR) { 214 s->port.icount.parity++; 215 } else if (stat & AUART_STAT_FERR) { 216 s->port.icount.frame++; 217 } 218 219 /* 220 * Mask off conditions which should be ingored. 221 */ 222 stat &= s->port.read_status_mask; 223 224 if (stat & AUART_STAT_BERR) { 225 flag = TTY_BREAK; 226 } else if (stat & AUART_STAT_PERR) 227 flag = TTY_PARITY; 228 else if (stat & AUART_STAT_FERR) 229 flag = TTY_FRAME; 230 231 if (stat & AUART_STAT_OERR) 232 s->port.icount.overrun++; 233 234 if (uart_handle_sysrq_char(&s->port, c)) 235 goto out; 236 237 uart_insert_char(&s->port, stat, AUART_STAT_OERR, c, flag); 238out: 239 writel(stat, s->port.membase + AUART_STAT); 240} 241 242static void mxs_auart_rx_chars(struct mxs_auart_port *s) 243{ 244 struct tty_struct *tty = s->port.state->port.tty; 245 u32 stat = 0; 246 247 for (;;) { 248 stat = readl(s->port.membase + AUART_STAT); 249 if (stat & AUART_STAT_RXFE) 250 break; 251 mxs_auart_rx_char(s); 252 } 253 254 writel(stat, s->port.membase + AUART_STAT); 255 tty_flip_buffer_push(tty); 256} 257 258static int mxs_auart_request_port(struct uart_port *u) 259{ 260 return 0; 261} 262 263static int mxs_auart_verify_port(struct uart_port *u, 264 struct serial_struct *ser) 265{ 266 if (u->type != PORT_UNKNOWN && u->type != PORT_IMX) 267 return -EINVAL; 268 return 0; 269} 270 271static void mxs_auart_config_port(struct uart_port *u, int flags) 272{ 273} 274 275static const char *mxs_auart_type(struct uart_port *u) 276{ 277 struct mxs_auart_port *s = to_auart_port(u); 278 279 return dev_name(s->dev); 280} 281 282static void mxs_auart_release_port(struct uart_port *u) 283{ 284} 285 286static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) 287{ 288 struct mxs_auart_port *s = to_auart_port(u); 289 290 u32 ctrl = readl(u->membase + AUART_CTRL2); 291 292 ctrl &= ~AUART_CTRL2_RTSEN; 293 if (mctrl & TIOCM_RTS) { 294 if (tty_port_cts_enabled(&u->state->port)) 295 ctrl |= AUART_CTRL2_RTSEN; 296 } 297 298 s->ctrl = mctrl; 299 writel(ctrl, u->membase + AUART_CTRL2); 300} 301 302static u32 mxs_auart_get_mctrl(struct uart_port *u) 303{ 304 struct mxs_auart_port *s = to_auart_port(u); 305 u32 stat = readl(u->membase + AUART_STAT); 306 int ctrl2 = readl(u->membase + AUART_CTRL2); 307 u32 mctrl = s->ctrl; 308 309 mctrl &= ~TIOCM_CTS; 310 if (stat & AUART_STAT_CTS) 311 mctrl |= TIOCM_CTS; 312 313 if (ctrl2 & AUART_CTRL2_RTS) 314 mctrl |= TIOCM_RTS; 315 316 return mctrl; 317} 318 319static void mxs_auart_settermios(struct uart_port *u, 320 struct ktermios *termios, 321 struct ktermios *old) 322{ 323 u32 bm, ctrl, ctrl2, div; 324 unsigned int cflag, baud; 325 326 cflag = termios->c_cflag; 327 328 ctrl = AUART_LINECTRL_FEN; 329 ctrl2 = readl(u->membase + AUART_CTRL2); 330 331 /* byte size */ 332 switch (cflag & CSIZE) { 333 case CS5: 334 bm = 0; 335 break; 336 case CS6: 337 bm = 1; 338 break; 339 case CS7: 340 bm = 2; 341 break; 342 case CS8: 343 bm = 3; 344 break; 345 default: 346 return; 347 } 348 349 ctrl |= AUART_LINECTRL_WLEN(bm); 350 351 /* parity */ 352 if (cflag & PARENB) { 353 ctrl |= AUART_LINECTRL_PEN; 354 if ((cflag & PARODD) == 0) 355 ctrl |= AUART_LINECTRL_EPS; 356 } 357 358 u->read_status_mask = 0; 359 360 if (termios->c_iflag & INPCK) 361 u->read_status_mask |= AUART_STAT_PERR; 362 if (termios->c_iflag & (BRKINT | PARMRK)) 363 u->read_status_mask |= AUART_STAT_BERR; 364 365 /* 366 * Characters to ignore 367 */ 368 u->ignore_status_mask = 0; 369 if (termios->c_iflag & IGNPAR) 370 u->ignore_status_mask |= AUART_STAT_PERR; 371 if (termios->c_iflag & IGNBRK) { 372 u->ignore_status_mask |= AUART_STAT_BERR; 373 /* 374 * If we're ignoring parity and break indicators, 375 * ignore overruns too (for real raw support). 376 */ 377 if (termios->c_iflag & IGNPAR) 378 u->ignore_status_mask |= AUART_STAT_OERR; 379 } 380 381 /* 382 * ignore all characters if CREAD is not set 383 */ 384 if (cflag & CREAD) 385 ctrl2 |= AUART_CTRL2_RXE; 386 else 387 ctrl2 &= ~AUART_CTRL2_RXE; 388 389 /* figure out the stop bits requested */ 390 if (cflag & CSTOPB) 391 ctrl |= AUART_LINECTRL_STP2; 392 393 /* figure out the hardware flow control settings */ 394 if (cflag & CRTSCTS) 395 ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; 396 else 397 ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); 398 399 /* set baud rate */ 400 baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); 401 div = u->uartclk * 32 / baud; 402 ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F); 403 ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6); 404 405 writel(ctrl, u->membase + AUART_LINECTRL); 406 writel(ctrl2, u->membase + AUART_CTRL2); 407 408 uart_update_timeout(u, termios->c_cflag, baud); 409} 410 411static irqreturn_t mxs_auart_irq_handle(int irq, void *context) 412{ 413 u32 istatus, istat; 414 struct mxs_auart_port *s = context; 415 u32 stat = readl(s->port.membase + AUART_STAT); 416 417 istatus = istat = readl(s->port.membase + AUART_INTR); 418 419 if (istat & AUART_INTR_CTSMIS) { 420 uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); 421 writel(AUART_INTR_CTSMIS, 422 s->port.membase + AUART_INTR_CLR); 423 istat &= ~AUART_INTR_CTSMIS; 424 } 425 426 if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) { 427 mxs_auart_rx_chars(s); 428 istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS); 429 } 430 431 if (istat & AUART_INTR_TXIS) { 432 mxs_auart_tx_chars(s); 433 istat &= ~AUART_INTR_TXIS; 434 } 435 436 writel(istatus & (AUART_INTR_RTIS 437 | AUART_INTR_TXIS 438 | AUART_INTR_RXIS 439 | AUART_INTR_CTSMIS), 440 s->port.membase + AUART_INTR_CLR); 441 442 return IRQ_HANDLED; 443} 444 445static void mxs_auart_reset(struct uart_port *u) 446{ 447 int i; 448 unsigned int reg; 449 450 writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_CLR); 451 452 for (i = 0; i < 10000; i++) { 453 reg = readl(u->membase + AUART_CTRL0); 454 if (!(reg & AUART_CTRL0_SFTRST)) 455 break; 456 udelay(3); 457 } 458 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); 459} 460 461static int mxs_auart_startup(struct uart_port *u) 462{ 463 struct mxs_auart_port *s = to_auart_port(u); 464 465 clk_prepare_enable(s->clk); 466 467 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); 468 469 writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET); 470 471 writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, 472 u->membase + AUART_INTR); 473 474 /* 475 * Enable fifo so all four bytes of a DMA word are written to 476 * output (otherwise, only the LSB is written, ie. 1 in 4 bytes) 477 */ 478 writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET); 479 480 return 0; 481} 482 483static void mxs_auart_shutdown(struct uart_port *u) 484{ 485 struct mxs_auart_port *s = to_auart_port(u); 486 487 writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); 488 489 writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, 490 u->membase + AUART_INTR_CLR); 491 492 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); 493 494 clk_disable_unprepare(s->clk); 495} 496 497static unsigned int mxs_auart_tx_empty(struct uart_port *u) 498{ 499 if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE) 500 return TIOCSER_TEMT; 501 else 502 return 0; 503} 504 505static void mxs_auart_start_tx(struct uart_port *u) 506{ 507 struct mxs_auart_port *s = to_auart_port(u); 508 509 /* enable transmitter */ 510 writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_SET); 511 512 mxs_auart_tx_chars(s); 513} 514 515static void mxs_auart_stop_tx(struct uart_port *u) 516{ 517 writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_CLR); 518} 519 520static void mxs_auart_stop_rx(struct uart_port *u) 521{ 522 writel(AUART_CTRL2_RXE, u->membase + AUART_CTRL2_CLR); 523} 524 525static void mxs_auart_break_ctl(struct uart_port *u, int ctl) 526{ 527 if (ctl) 528 writel(AUART_LINECTRL_BRK, 529 u->membase + AUART_LINECTRL_SET); 530 else 531 writel(AUART_LINECTRL_BRK, 532 u->membase + AUART_LINECTRL_CLR); 533} 534 535static void mxs_auart_enable_ms(struct uart_port *port) 536{ 537 /* just empty */ 538} 539 540static struct uart_ops mxs_auart_ops = { 541 .tx_empty = mxs_auart_tx_empty, 542 .start_tx = mxs_auart_start_tx, 543 .stop_tx = mxs_auart_stop_tx, 544 .stop_rx = mxs_auart_stop_rx, 545 .enable_ms = mxs_auart_enable_ms, 546 .break_ctl = mxs_auart_break_ctl, 547 .set_mctrl = mxs_auart_set_mctrl, 548 .get_mctrl = mxs_auart_get_mctrl, 549 .startup = mxs_auart_startup, 550 .shutdown = mxs_auart_shutdown, 551 .set_termios = mxs_auart_settermios, 552 .type = mxs_auart_type, 553 .release_port = mxs_auart_release_port, 554 .request_port = mxs_auart_request_port, 555 .config_port = mxs_auart_config_port, 556 .verify_port = mxs_auart_verify_port, 557}; 558 559static struct mxs_auart_port *auart_port[MXS_AUART_PORTS]; 560 561#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE 562static void mxs_auart_console_putchar(struct uart_port *port, int ch) 563{ 564 unsigned int to = 1000; 565 566 while (readl(port->membase + AUART_STAT) & AUART_STAT_TXFF) { 567 if (!to--) 568 break; 569 udelay(1); 570 } 571 572 writel(ch, port->membase + AUART_DATA); 573} 574 575static void 576auart_console_write(struct console *co, const char *str, unsigned int count) 577{ 578 struct mxs_auart_port *s; 579 struct uart_port *port; 580 unsigned int old_ctrl0, old_ctrl2; 581 unsigned int to = 1000; 582 583 if (co->index > MXS_AUART_PORTS || co->index < 0) 584 return; 585 586 s = auart_port[co->index]; 587 port = &s->port; 588 589 clk_enable(s->clk); 590 591 /* First save the CR then disable the interrupts */ 592 old_ctrl2 = readl(port->membase + AUART_CTRL2); 593 old_ctrl0 = readl(port->membase + AUART_CTRL0); 594 595 writel(AUART_CTRL0_CLKGATE, 596 port->membase + AUART_CTRL0_CLR); 597 writel(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE, 598 port->membase + AUART_CTRL2_SET); 599 600 uart_console_write(port, str, count, mxs_auart_console_putchar); 601 602 /* 603 * Finally, wait for transmitter to become empty 604 * and restore the TCR 605 */ 606 while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { 607 if (!to--) 608 break; 609 udelay(1); 610 } 611 612 writel(old_ctrl0, port->membase + AUART_CTRL0); 613 writel(old_ctrl2, port->membase + AUART_CTRL2); 614 615 clk_disable(s->clk); 616} 617 618static void __init 619auart_console_get_options(struct uart_port *port, int *baud, 620 int *parity, int *bits) 621{ 622 unsigned int lcr_h, quot; 623 624 if (!(readl(port->membase + AUART_CTRL2) & AUART_CTRL2_UARTEN)) 625 return; 626 627 lcr_h = readl(port->membase + AUART_LINECTRL); 628 629 *parity = 'n'; 630 if (lcr_h & AUART_LINECTRL_PEN) { 631 if (lcr_h & AUART_LINECTRL_EPS) 632 *parity = 'e'; 633 else 634 *parity = 'o'; 635 } 636 637 if ((lcr_h & AUART_LINECTRL_WLEN_MASK) == AUART_LINECTRL_WLEN(2)) 638 *bits = 7; 639 else 640 *bits = 8; 641 642 quot = ((readl(port->membase + AUART_LINECTRL) 643 & AUART_LINECTRL_BAUD_DIVINT_MASK)) 644 >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6); 645 quot |= ((readl(port->membase + AUART_LINECTRL) 646 & AUART_LINECTRL_BAUD_DIVFRAC_MASK)) 647 >> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT; 648 if (quot == 0) 649 quot = 1; 650 651 *baud = (port->uartclk << 2) / quot; 652} 653 654static int __init 655auart_console_setup(struct console *co, char *options) 656{ 657 struct mxs_auart_port *s; 658 int baud = 9600; 659 int bits = 8; 660 int parity = 'n'; 661 int flow = 'n'; 662 int ret; 663 664 /* 665 * Check whether an invalid uart number has been specified, and 666 * if so, search for the first available port that does have 667 * console support. 668 */ 669 if (co->index == -1 || co->index >= ARRAY_SIZE(auart_port)) 670 co->index = 0; 671 s = auart_port[co->index]; 672 if (!s) 673 return -ENODEV; 674 675 clk_prepare_enable(s->clk); 676 677 if (options) 678 uart_parse_options(options, &baud, &parity, &bits, &flow); 679 else 680 auart_console_get_options(&s->port, &baud, &parity, &bits); 681 682 ret = uart_set_options(&s->port, co, baud, parity, bits, flow); 683 684 clk_disable_unprepare(s->clk); 685 686 return ret; 687} 688 689static struct console auart_console = { 690 .name = "ttyAPP", 691 .write = auart_console_write, 692 .device = uart_console_device, 693 .setup = auart_console_setup, 694 .flags = CON_PRINTBUFFER, 695 .index = -1, 696 .data = &auart_driver, 697}; 698#endif 699 700static struct uart_driver auart_driver = { 701 .owner = THIS_MODULE, 702 .driver_name = "ttyAPP", 703 .dev_name = "ttyAPP", 704 .major = 0, 705 .minor = 0, 706 .nr = MXS_AUART_PORTS, 707#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE 708 .cons = &auart_console, 709#endif 710}; 711 712/* 713 * This function returns 1 if pdev isn't a device instatiated by dt, 0 if it 714 * could successfully get all information from dt or a negative errno. 715 */ 716static int serial_mxs_probe_dt(struct mxs_auart_port *s, 717 struct platform_device *pdev) 718{ 719 struct device_node *np = pdev->dev.of_node; 720 int ret; 721 722 if (!np) 723 /* no device tree device */ 724 return 1; 725 726 ret = of_alias_get_id(np, "serial"); 727 if (ret < 0) { 728 dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); 729 return ret; 730 } 731 s->port.line = ret; 732 733 return 0; 734} 735 736static int __devinit mxs_auart_probe(struct platform_device *pdev) 737{ 738 const struct of_device_id *of_id = 739 of_match_device(mxs_auart_dt_ids, &pdev->dev); 740 struct mxs_auart_port *s; 741 u32 version; 742 int ret = 0; 743 struct resource *r; 744 struct pinctrl *pinctrl; 745 746 s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL); 747 if (!s) { 748 ret = -ENOMEM; 749 goto out; 750 } 751 752 ret = serial_mxs_probe_dt(s, pdev); 753 if (ret > 0) 754 s->port.line = pdev->id < 0 ? 0 : pdev->id; 755 else if (ret < 0) 756 goto out_free; 757 758 pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 759 if (IS_ERR(pinctrl)) { 760 ret = PTR_ERR(pinctrl); 761 goto out_free; 762 } 763 764 if (of_id) { 765 pdev->id_entry = of_id->data; 766 s->devtype = pdev->id_entry->driver_data; 767 } 768 769 s->clk = clk_get(&pdev->dev, NULL); 770 if (IS_ERR(s->clk)) { 771 ret = PTR_ERR(s->clk); 772 goto out_free; 773 } 774 775 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 776 if (!r) { 777 ret = -ENXIO; 778 goto out_free_clk; 779 } 780 781 s->port.mapbase = r->start; 782 s->port.membase = ioremap(r->start, resource_size(r)); 783 s->port.ops = &mxs_auart_ops; 784 s->port.iotype = UPIO_MEM; 785 s->port.fifosize = 16; 786 s->port.uartclk = clk_get_rate(s->clk); 787 s->port.type = PORT_IMX; 788 s->port.dev = s->dev = get_device(&pdev->dev); 789 790 s->flags = 0; 791 s->ctrl = 0; 792 793 s->irq = platform_get_irq(pdev, 0); 794 s->port.irq = s->irq; 795 ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s); 796 if (ret) 797 goto out_free_clk; 798 799 platform_set_drvdata(pdev, s); 800 801 auart_port[s->port.line] = s; 802 803 mxs_auart_reset(&s->port); 804 805 ret = uart_add_one_port(&auart_driver, &s->port); 806 if (ret) 807 goto out_free_irq; 808 809 version = readl(s->port.membase + AUART_VERSION); 810 dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n", 811 (version >> 24) & 0xff, 812 (version >> 16) & 0xff, version & 0xffff); 813 814 return 0; 815 816out_free_irq: 817 auart_port[pdev->id] = NULL; 818 free_irq(s->irq, s); 819out_free_clk: 820 put_device(s->dev); 821 clk_put(s->clk); 822out_free: 823 kfree(s); 824out: 825 return ret; 826} 827 828static int __devexit mxs_auart_remove(struct platform_device *pdev) 829{ 830 struct mxs_auart_port *s = platform_get_drvdata(pdev); 831 832 uart_remove_one_port(&auart_driver, &s->port); 833 834 auart_port[pdev->id] = NULL; 835 836 put_device(s->dev); 837 clk_put(s->clk); 838 free_irq(s->irq, s); 839 kfree(s); 840 841 return 0; 842} 843 844static struct platform_driver mxs_auart_driver = { 845 .probe = mxs_auart_probe, 846 .remove = __devexit_p(mxs_auart_remove), 847 .driver = { 848 .name = "mxs-auart", 849 .owner = THIS_MODULE, 850 .of_match_table = mxs_auart_dt_ids, 851 }, 852}; 853 854static int __init mxs_auart_init(void) 855{ 856 int r; 857 858 r = uart_register_driver(&auart_driver); 859 if (r) 860 goto out; 861 862 r = platform_driver_register(&mxs_auart_driver); 863 if (r) 864 goto out_err; 865 866 return 0; 867out_err: 868 uart_unregister_driver(&auart_driver); 869out: 870 return r; 871} 872 873static void __exit mxs_auart_exit(void) 874{ 875 platform_driver_unregister(&mxs_auart_driver); 876 uart_unregister_driver(&auart_driver); 877} 878 879module_init(mxs_auart_init); 880module_exit(mxs_auart_exit); 881MODULE_LICENSE("GPL"); 882MODULE_DESCRIPTION("Freescale MXS application uart driver"); 883MODULE_ALIAS("platform:mxs-auart"); 884