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 112static struct uart_driver auart_driver; 113 114struct 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 126static 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 130static 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 165static 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); 206out: 207 writel(stat, s->port.membase + AUART_STAT); 208} 209 210static 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 226static int mxs_auart_request_port(struct uart_port *u) 227{ 228 return 0; 229} 230 231static 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 239static void mxs_auart_config_port(struct uart_port *u, int flags) 240{ 241} 242 243static 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 250static void mxs_auart_release_port(struct uart_port *u) 251{ 252} 253 254static 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 267static 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 284static 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 uart_update_timeout(u, termios->c_cflag, baud); 374} 375 376static irqreturn_t mxs_auart_irq_handle(int irq, void *context) 377{ 378 u32 istatus, istat; 379 struct mxs_auart_port *s = context; 380 u32 stat = readl(s->port.membase + AUART_STAT); 381 382 istatus = istat = readl(s->port.membase + AUART_INTR); 383 384 if (istat & AUART_INTR_CTSMIS) { 385 uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); 386 writel(AUART_INTR_CTSMIS, 387 s->port.membase + AUART_INTR_CLR); 388 istat &= ~AUART_INTR_CTSMIS; 389 } 390 391 if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) { 392 mxs_auart_rx_chars(s); 393 istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS); 394 } 395 396 if (istat & AUART_INTR_TXIS) { 397 mxs_auart_tx_chars(s); 398 istat &= ~AUART_INTR_TXIS; 399 } 400 401 writel(istatus & (AUART_INTR_RTIS 402 | AUART_INTR_TXIS 403 | AUART_INTR_RXIS 404 | AUART_INTR_CTSMIS), 405 s->port.membase + AUART_INTR_CLR); 406 407 return IRQ_HANDLED; 408} 409 410static void mxs_auart_reset(struct uart_port *u) 411{ 412 int i; 413 unsigned int reg; 414 415 writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_CLR); 416 417 for (i = 0; i < 10000; i++) { 418 reg = readl(u->membase + AUART_CTRL0); 419 if (!(reg & AUART_CTRL0_SFTRST)) 420 break; 421 udelay(3); 422 } 423 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); 424} 425 426static int mxs_auart_startup(struct uart_port *u) 427{ 428 struct mxs_auart_port *s = to_auart_port(u); 429 430 clk_prepare_enable(s->clk); 431 432 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); 433 434 writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET); 435 436 writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, 437 u->membase + AUART_INTR); 438 439 /* 440 * Enable fifo so all four bytes of a DMA word are written to 441 * output (otherwise, only the LSB is written, ie. 1 in 4 bytes) 442 */ 443 writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET); 444 445 return 0; 446} 447 448static void mxs_auart_shutdown(struct uart_port *u) 449{ 450 struct mxs_auart_port *s = to_auart_port(u); 451 452 writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); 453 454 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); 455 456 writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, 457 u->membase + AUART_INTR_CLR); 458 459 clk_disable_unprepare(s->clk); 460} 461 462static unsigned int mxs_auart_tx_empty(struct uart_port *u) 463{ 464 if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE) 465 return TIOCSER_TEMT; 466 else 467 return 0; 468} 469 470static void mxs_auart_start_tx(struct uart_port *u) 471{ 472 struct mxs_auart_port *s = to_auart_port(u); 473 474 /* enable transmitter */ 475 writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_SET); 476 477 mxs_auart_tx_chars(s); 478} 479 480static void mxs_auart_stop_tx(struct uart_port *u) 481{ 482 writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_CLR); 483} 484 485static void mxs_auart_stop_rx(struct uart_port *u) 486{ 487 writel(AUART_CTRL2_RXE, u->membase + AUART_CTRL2_CLR); 488} 489 490static void mxs_auart_break_ctl(struct uart_port *u, int ctl) 491{ 492 if (ctl) 493 writel(AUART_LINECTRL_BRK, 494 u->membase + AUART_LINECTRL_SET); 495 else 496 writel(AUART_LINECTRL_BRK, 497 u->membase + AUART_LINECTRL_CLR); 498} 499 500static void mxs_auart_enable_ms(struct uart_port *port) 501{ 502 /* just empty */ 503} 504 505static struct uart_ops mxs_auart_ops = { 506 .tx_empty = mxs_auart_tx_empty, 507 .start_tx = mxs_auart_start_tx, 508 .stop_tx = mxs_auart_stop_tx, 509 .stop_rx = mxs_auart_stop_rx, 510 .enable_ms = mxs_auart_enable_ms, 511 .break_ctl = mxs_auart_break_ctl, 512 .set_mctrl = mxs_auart_set_mctrl, 513 .get_mctrl = mxs_auart_get_mctrl, 514 .startup = mxs_auart_startup, 515 .shutdown = mxs_auart_shutdown, 516 .set_termios = mxs_auart_settermios, 517 .type = mxs_auart_type, 518 .release_port = mxs_auart_release_port, 519 .request_port = mxs_auart_request_port, 520 .config_port = mxs_auart_config_port, 521 .verify_port = mxs_auart_verify_port, 522}; 523 524static struct mxs_auart_port *auart_port[MXS_AUART_PORTS]; 525 526#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE 527static void mxs_auart_console_putchar(struct uart_port *port, int ch) 528{ 529 unsigned int to = 1000; 530 531 while (readl(port->membase + AUART_STAT) & AUART_STAT_TXFF) { 532 if (!to--) 533 break; 534 udelay(1); 535 } 536 537 writel(ch, port->membase + AUART_DATA); 538} 539 540static void 541auart_console_write(struct console *co, const char *str, unsigned int count) 542{ 543 struct mxs_auart_port *s; 544 struct uart_port *port; 545 unsigned int old_ctrl0, old_ctrl2; 546 unsigned int to = 1000; 547 548 if (co->index > MXS_AUART_PORTS || co->index < 0) 549 return; 550 551 s = auart_port[co->index]; 552 port = &s->port; 553 554 clk_enable(s->clk); 555 556 /* First save the CR then disable the interrupts */ 557 old_ctrl2 = readl(port->membase + AUART_CTRL2); 558 old_ctrl0 = readl(port->membase + AUART_CTRL0); 559 560 writel(AUART_CTRL0_CLKGATE, 561 port->membase + AUART_CTRL0_CLR); 562 writel(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE, 563 port->membase + AUART_CTRL2_SET); 564 565 uart_console_write(port, str, count, mxs_auart_console_putchar); 566 567 /* 568 * Finally, wait for transmitter to become empty 569 * and restore the TCR 570 */ 571 while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { 572 if (!to--) 573 break; 574 udelay(1); 575 } 576 577 writel(old_ctrl0, port->membase + AUART_CTRL0); 578 writel(old_ctrl2, port->membase + AUART_CTRL2); 579 580 clk_disable(s->clk); 581} 582 583static void __init 584auart_console_get_options(struct uart_port *port, int *baud, 585 int *parity, int *bits) 586{ 587 unsigned int lcr_h, quot; 588 589 if (!(readl(port->membase + AUART_CTRL2) & AUART_CTRL2_UARTEN)) 590 return; 591 592 lcr_h = readl(port->membase + AUART_LINECTRL); 593 594 *parity = 'n'; 595 if (lcr_h & AUART_LINECTRL_PEN) { 596 if (lcr_h & AUART_LINECTRL_EPS) 597 *parity = 'e'; 598 else 599 *parity = 'o'; 600 } 601 602 if ((lcr_h & AUART_LINECTRL_WLEN_MASK) == AUART_LINECTRL_WLEN(2)) 603 *bits = 7; 604 else 605 *bits = 8; 606 607 quot = ((readl(port->membase + AUART_LINECTRL) 608 & AUART_LINECTRL_BAUD_DIVINT_MASK)) 609 >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6); 610 quot |= ((readl(port->membase + AUART_LINECTRL) 611 & AUART_LINECTRL_BAUD_DIVFRAC_MASK)) 612 >> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT; 613 if (quot == 0) 614 quot = 1; 615 616 *baud = (port->uartclk << 2) / quot; 617} 618 619static int __init 620auart_console_setup(struct console *co, char *options) 621{ 622 struct mxs_auart_port *s; 623 int baud = 9600; 624 int bits = 8; 625 int parity = 'n'; 626 int flow = 'n'; 627 int ret; 628 629 /* 630 * Check whether an invalid uart number has been specified, and 631 * if so, search for the first available port that does have 632 * console support. 633 */ 634 if (co->index == -1 || co->index >= ARRAY_SIZE(auart_port)) 635 co->index = 0; 636 s = auart_port[co->index]; 637 if (!s) 638 return -ENODEV; 639 640 clk_prepare_enable(s->clk); 641 642 if (options) 643 uart_parse_options(options, &baud, &parity, &bits, &flow); 644 else 645 auart_console_get_options(&s->port, &baud, &parity, &bits); 646 647 ret = uart_set_options(&s->port, co, baud, parity, bits, flow); 648 649 clk_disable_unprepare(s->clk); 650 651 return ret; 652} 653 654static struct console auart_console = { 655 .name = "ttyAPP", 656 .write = auart_console_write, 657 .device = uart_console_device, 658 .setup = auart_console_setup, 659 .flags = CON_PRINTBUFFER, 660 .index = -1, 661 .data = &auart_driver, 662}; 663#endif 664 665static struct uart_driver auart_driver = { 666 .owner = THIS_MODULE, 667 .driver_name = "ttyAPP", 668 .dev_name = "ttyAPP", 669 .major = 0, 670 .minor = 0, 671 .nr = MXS_AUART_PORTS, 672#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE 673 .cons = &auart_console, 674#endif 675}; 676 677static int __devinit mxs_auart_probe(struct platform_device *pdev) 678{ 679 struct mxs_auart_port *s; 680 u32 version; 681 int ret = 0; 682 struct resource *r; 683 684 s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL); 685 if (!s) { 686 ret = -ENOMEM; 687 goto out; 688 } 689 690 s->clk = clk_get(&pdev->dev, NULL); 691 if (IS_ERR(s->clk)) { 692 ret = PTR_ERR(s->clk); 693 goto out_free; 694 } 695 696 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 697 if (!r) { 698 ret = -ENXIO; 699 goto out_free_clk; 700 } 701 702 s->port.mapbase = r->start; 703 s->port.membase = ioremap(r->start, resource_size(r)); 704 s->port.ops = &mxs_auart_ops; 705 s->port.iotype = UPIO_MEM; 706 s->port.line = pdev->id < 0 ? 0 : pdev->id; 707 s->port.fifosize = 16; 708 s->port.uartclk = clk_get_rate(s->clk); 709 s->port.type = PORT_IMX; 710 s->port.dev = s->dev = get_device(&pdev->dev); 711 712 s->flags = 0; 713 s->ctrl = 0; 714 715 s->irq = platform_get_irq(pdev, 0); 716 s->port.irq = s->irq; 717 ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s); 718 if (ret) 719 goto out_free_clk; 720 721 platform_set_drvdata(pdev, s); 722 723 auart_port[pdev->id] = s; 724 725 mxs_auart_reset(&s->port); 726 727 ret = uart_add_one_port(&auart_driver, &s->port); 728 if (ret) 729 goto out_free_irq; 730 731 version = readl(s->port.membase + AUART_VERSION); 732 dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n", 733 (version >> 24) & 0xff, 734 (version >> 16) & 0xff, version & 0xffff); 735 736 return 0; 737 738out_free_irq: 739 auart_port[pdev->id] = NULL; 740 free_irq(s->irq, s); 741out_free_clk: 742 clk_put(s->clk); 743out_free: 744 kfree(s); 745out: 746 return ret; 747} 748 749static int __devexit mxs_auart_remove(struct platform_device *pdev) 750{ 751 struct mxs_auart_port *s = platform_get_drvdata(pdev); 752 753 uart_remove_one_port(&auart_driver, &s->port); 754 755 auart_port[pdev->id] = NULL; 756 757 clk_put(s->clk); 758 free_irq(s->irq, s); 759 kfree(s); 760 761 return 0; 762} 763 764static struct platform_driver mxs_auart_driver = { 765 .probe = mxs_auart_probe, 766 .remove = __devexit_p(mxs_auart_remove), 767 .driver = { 768 .name = "mxs-auart", 769 .owner = THIS_MODULE, 770 }, 771}; 772 773static int __init mxs_auart_init(void) 774{ 775 int r; 776 777 r = uart_register_driver(&auart_driver); 778 if (r) 779 goto out; 780 781 r = platform_driver_register(&mxs_auart_driver); 782 if (r) 783 goto out_err; 784 785 return 0; 786out_err: 787 uart_unregister_driver(&auart_driver); 788out: 789 return r; 790} 791 792static void __exit mxs_auart_exit(void) 793{ 794 platform_driver_unregister(&mxs_auart_driver); 795 uart_unregister_driver(&auart_driver); 796} 797 798module_init(mxs_auart_init); 799module_exit(mxs_auart_exit); 800MODULE_LICENSE("GPL"); 801MODULE_DESCRIPTION("Freescale MXS application uart driver"); 802