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