at v2.6.30-rc2 665 lines 18 kB view raw
1/****************************************************************************/ 2 3/* 4 * mcf.c -- Freescale ColdFire UART driver 5 * 6 * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14/****************************************************************************/ 15 16#include <linux/kernel.h> 17#include <linux/init.h> 18#include <linux/interrupt.h> 19#include <linux/module.h> 20#include <linux/console.h> 21#include <linux/tty.h> 22#include <linux/tty_flip.h> 23#include <linux/serial.h> 24#include <linux/serial_core.h> 25#include <linux/io.h> 26#include <asm/coldfire.h> 27#include <asm/mcfsim.h> 28#include <asm/mcfuart.h> 29#include <asm/nettel.h> 30 31/****************************************************************************/ 32 33/* 34 * Some boards implement the DTR/DCD lines using GPIO lines, most 35 * don't. Dummy out the access macros for those that don't. Those 36 * that do should define these macros somewhere in there board 37 * specific inlude files. 38 */ 39#if !defined(mcf_getppdcd) 40#define mcf_getppdcd(p) (1) 41#endif 42#if !defined(mcf_getppdtr) 43#define mcf_getppdtr(p) (1) 44#endif 45#if !defined(mcf_setppdtr) 46#define mcf_setppdtr(p, v) do { } while (0) 47#endif 48 49/****************************************************************************/ 50 51/* 52 * Local per-uart structure. 53 */ 54struct mcf_uart { 55 struct uart_port port; 56 unsigned int sigs; /* Local copy of line sigs */ 57 unsigned char imr; /* Local IMR mirror */ 58}; 59 60/****************************************************************************/ 61 62static unsigned int mcf_tx_empty(struct uart_port *port) 63{ 64 return (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXEMPTY) ? 65 TIOCSER_TEMT : 0; 66} 67 68/****************************************************************************/ 69 70static unsigned int mcf_get_mctrl(struct uart_port *port) 71{ 72 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 73 unsigned long flags; 74 unsigned int sigs; 75 76 spin_lock_irqsave(&port->lock, flags); 77 sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ? 78 0 : TIOCM_CTS; 79 sigs |= (pp->sigs & TIOCM_RTS); 80 sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0); 81 sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0); 82 spin_unlock_irqrestore(&port->lock, flags); 83 return sigs; 84} 85 86/****************************************************************************/ 87 88static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) 89{ 90 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 91 unsigned long flags; 92 93 spin_lock_irqsave(&port->lock, flags); 94 pp->sigs = sigs; 95 mcf_setppdtr(port->line, (sigs & TIOCM_DTR)); 96 if (sigs & TIOCM_RTS) 97 writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); 98 else 99 writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0); 100 spin_unlock_irqrestore(&port->lock, flags); 101} 102 103/****************************************************************************/ 104 105static void mcf_start_tx(struct uart_port *port) 106{ 107 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 108 unsigned long flags; 109 110 spin_lock_irqsave(&port->lock, flags); 111 pp->imr |= MCFUART_UIR_TXREADY; 112 writeb(pp->imr, port->membase + MCFUART_UIMR); 113 spin_unlock_irqrestore(&port->lock, flags); 114} 115 116/****************************************************************************/ 117 118static void mcf_stop_tx(struct uart_port *port) 119{ 120 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 121 unsigned long flags; 122 123 spin_lock_irqsave(&port->lock, flags); 124 pp->imr &= ~MCFUART_UIR_TXREADY; 125 writeb(pp->imr, port->membase + MCFUART_UIMR); 126 spin_unlock_irqrestore(&port->lock, flags); 127} 128 129/****************************************************************************/ 130 131static void mcf_stop_rx(struct uart_port *port) 132{ 133 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 134 unsigned long flags; 135 136 spin_lock_irqsave(&port->lock, flags); 137 pp->imr &= ~MCFUART_UIR_RXREADY; 138 writeb(pp->imr, port->membase + MCFUART_UIMR); 139 spin_unlock_irqrestore(&port->lock, flags); 140} 141 142/****************************************************************************/ 143 144static void mcf_break_ctl(struct uart_port *port, int break_state) 145{ 146 unsigned long flags; 147 148 spin_lock_irqsave(&port->lock, flags); 149 if (break_state == -1) 150 writeb(MCFUART_UCR_CMDBREAKSTART, port->membase + MCFUART_UCR); 151 else 152 writeb(MCFUART_UCR_CMDBREAKSTOP, port->membase + MCFUART_UCR); 153 spin_unlock_irqrestore(&port->lock, flags); 154} 155 156/****************************************************************************/ 157 158static void mcf_enable_ms(struct uart_port *port) 159{ 160} 161 162/****************************************************************************/ 163 164static int mcf_startup(struct uart_port *port) 165{ 166 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 167 unsigned long flags; 168 169 spin_lock_irqsave(&port->lock, flags); 170 171 /* Reset UART, get it into known state... */ 172 writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); 173 writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); 174 175 /* Enable the UART transmitter and receiver */ 176 writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, 177 port->membase + MCFUART_UCR); 178 179 /* Enable RX interrupts now */ 180 pp->imr = MCFUART_UIR_RXREADY; 181 writeb(pp->imr, port->membase + MCFUART_UIMR); 182 183 spin_unlock_irqrestore(&port->lock, flags); 184 185 return 0; 186} 187 188/****************************************************************************/ 189 190static void mcf_shutdown(struct uart_port *port) 191{ 192 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 193 unsigned long flags; 194 195 spin_lock_irqsave(&port->lock, flags); 196 197 /* Disable all interrupts now */ 198 pp->imr = 0; 199 writeb(pp->imr, port->membase + MCFUART_UIMR); 200 201 /* Disable UART transmitter and receiver */ 202 writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); 203 writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); 204 205 spin_unlock_irqrestore(&port->lock, flags); 206} 207 208/****************************************************************************/ 209 210static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, 211 struct ktermios *old) 212{ 213 unsigned long flags; 214 unsigned int baud, baudclk; 215#if defined(CONFIG_M5272) 216 unsigned int baudfr; 217#endif 218 unsigned char mr1, mr2; 219 220 baud = uart_get_baud_rate(port, termios, old, 0, 230400); 221#if defined(CONFIG_M5272) 222 baudclk = (MCF_BUSCLK / baud) / 32; 223 baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16; 224#else 225 baudclk = ((MCF_BUSCLK / baud) + 16) / 32; 226#endif 227 228 mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR; 229 mr2 = 0; 230 231 switch (termios->c_cflag & CSIZE) { 232 case CS5: mr1 |= MCFUART_MR1_CS5; break; 233 case CS6: mr1 |= MCFUART_MR1_CS6; break; 234 case CS7: mr1 |= MCFUART_MR1_CS7; break; 235 case CS8: 236 default: mr1 |= MCFUART_MR1_CS8; break; 237 } 238 239 if (termios->c_cflag & PARENB) { 240 if (termios->c_cflag & CMSPAR) { 241 if (termios->c_cflag & PARODD) 242 mr1 |= MCFUART_MR1_PARITYMARK; 243 else 244 mr1 |= MCFUART_MR1_PARITYSPACE; 245 } else { 246 if (termios->c_cflag & PARODD) 247 mr1 |= MCFUART_MR1_PARITYODD; 248 else 249 mr1 |= MCFUART_MR1_PARITYEVEN; 250 } 251 } else { 252 mr1 |= MCFUART_MR1_PARITYNONE; 253 } 254 255 if (termios->c_cflag & CSTOPB) 256 mr2 |= MCFUART_MR2_STOP2; 257 else 258 mr2 |= MCFUART_MR2_STOP1; 259 260 if (termios->c_cflag & CRTSCTS) { 261 mr1 |= MCFUART_MR1_RXRTS; 262 mr2 |= MCFUART_MR2_TXCTS; 263 } 264 265 spin_lock_irqsave(&port->lock, flags); 266 writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); 267 writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); 268 writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); 269 writeb(mr1, port->membase + MCFUART_UMR); 270 writeb(mr2, port->membase + MCFUART_UMR); 271 writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1); 272 writeb((baudclk & 0xff), port->membase + MCFUART_UBG2); 273#if defined(CONFIG_M5272) 274 writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD); 275#endif 276 writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER, 277 port->membase + MCFUART_UCSR); 278 writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, 279 port->membase + MCFUART_UCR); 280 spin_unlock_irqrestore(&port->lock, flags); 281} 282 283/****************************************************************************/ 284 285static void mcf_rx_chars(struct mcf_uart *pp) 286{ 287 struct uart_port *port = &pp->port; 288 unsigned char status, ch, flag; 289 290 while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) { 291 ch = readb(port->membase + MCFUART_URB); 292 flag = TTY_NORMAL; 293 port->icount.rx++; 294 295 if (status & MCFUART_USR_RXERR) { 296 writeb(MCFUART_UCR_CMDRESETERR, 297 port->membase + MCFUART_UCR); 298 299 if (status & MCFUART_USR_RXBREAK) { 300 port->icount.brk++; 301 if (uart_handle_break(port)) 302 continue; 303 } else if (status & MCFUART_USR_RXPARITY) { 304 port->icount.parity++; 305 } else if (status & MCFUART_USR_RXOVERRUN) { 306 port->icount.overrun++; 307 } else if (status & MCFUART_USR_RXFRAMING) { 308 port->icount.frame++; 309 } 310 311 status &= port->read_status_mask; 312 313 if (status & MCFUART_USR_RXBREAK) 314 flag = TTY_BREAK; 315 else if (status & MCFUART_USR_RXPARITY) 316 flag = TTY_PARITY; 317 else if (status & MCFUART_USR_RXFRAMING) 318 flag = TTY_FRAME; 319 } 320 321 if (uart_handle_sysrq_char(port, ch)) 322 continue; 323 uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); 324 } 325 326 tty_flip_buffer_push(port->info->port.tty); 327} 328 329/****************************************************************************/ 330 331static void mcf_tx_chars(struct mcf_uart *pp) 332{ 333 struct uart_port *port = &pp->port; 334 struct circ_buf *xmit = &port->info->xmit; 335 336 if (port->x_char) { 337 /* Send special char - probably flow control */ 338 writeb(port->x_char, port->membase + MCFUART_UTB); 339 port->x_char = 0; 340 port->icount.tx++; 341 return; 342 } 343 344 while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) { 345 if (xmit->head == xmit->tail) 346 break; 347 writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB); 348 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1); 349 port->icount.tx++; 350 } 351 352 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 353 uart_write_wakeup(port); 354 355 if (xmit->head == xmit->tail) { 356 pp->imr &= ~MCFUART_UIR_TXREADY; 357 writeb(pp->imr, port->membase + MCFUART_UIMR); 358 } 359} 360 361/****************************************************************************/ 362 363static irqreturn_t mcf_interrupt(int irq, void *data) 364{ 365 struct uart_port *port = data; 366 struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 367 unsigned int isr; 368 369 isr = readb(port->membase + MCFUART_UISR) & pp->imr; 370 if (isr & MCFUART_UIR_RXREADY) 371 mcf_rx_chars(pp); 372 if (isr & MCFUART_UIR_TXREADY) 373 mcf_tx_chars(pp); 374 return IRQ_HANDLED; 375} 376 377/****************************************************************************/ 378 379static void mcf_config_port(struct uart_port *port, int flags) 380{ 381 port->type = PORT_MCF; 382 383 /* Clear mask, so no surprise interrupts. */ 384 writeb(0, port->membase + MCFUART_UIMR); 385 386 if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port)) 387 printk(KERN_ERR "MCF: unable to attach ColdFire UART %d " 388 "interrupt vector=%d\n", port->line, port->irq); 389} 390 391/****************************************************************************/ 392 393static const char *mcf_type(struct uart_port *port) 394{ 395 return (port->type == PORT_MCF) ? "ColdFire UART" : NULL; 396} 397 398/****************************************************************************/ 399 400static int mcf_request_port(struct uart_port *port) 401{ 402 /* UARTs always present */ 403 return 0; 404} 405 406/****************************************************************************/ 407 408static void mcf_release_port(struct uart_port *port) 409{ 410 /* Nothing to release... */ 411} 412 413/****************************************************************************/ 414 415static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) 416{ 417 if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF)) 418 return -EINVAL; 419 return 0; 420} 421 422/****************************************************************************/ 423 424/* 425 * Define the basic serial functions we support. 426 */ 427static struct uart_ops mcf_uart_ops = { 428 .tx_empty = mcf_tx_empty, 429 .get_mctrl = mcf_get_mctrl, 430 .set_mctrl = mcf_set_mctrl, 431 .start_tx = mcf_start_tx, 432 .stop_tx = mcf_stop_tx, 433 .stop_rx = mcf_stop_rx, 434 .enable_ms = mcf_enable_ms, 435 .break_ctl = mcf_break_ctl, 436 .startup = mcf_startup, 437 .shutdown = mcf_shutdown, 438 .set_termios = mcf_set_termios, 439 .type = mcf_type, 440 .request_port = mcf_request_port, 441 .release_port = mcf_release_port, 442 .config_port = mcf_config_port, 443 .verify_port = mcf_verify_port, 444}; 445 446static struct mcf_uart mcf_ports[3]; 447 448#define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) 449 450/****************************************************************************/ 451#if defined(CONFIG_SERIAL_MCF_CONSOLE) 452/****************************************************************************/ 453 454int __init early_mcf_setup(struct mcf_platform_uart *platp) 455{ 456 struct uart_port *port; 457 int i; 458 459 for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) { 460 port = &mcf_ports[i].port; 461 462 port->line = i; 463 port->type = PORT_MCF; 464 port->mapbase = platp[i].mapbase; 465 port->membase = (platp[i].membase) ? platp[i].membase : 466 (unsigned char __iomem *) port->mapbase; 467 port->iotype = SERIAL_IO_MEM; 468 port->irq = platp[i].irq; 469 port->uartclk = MCF_BUSCLK; 470 port->flags = ASYNC_BOOT_AUTOCONF; 471 port->ops = &mcf_uart_ops; 472 } 473 474 return 0; 475} 476 477/****************************************************************************/ 478 479static void mcf_console_putc(struct console *co, const char c) 480{ 481 struct uart_port *port = &(mcf_ports + co->index)->port; 482 int i; 483 484 for (i = 0; (i < 0x10000); i++) { 485 if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) 486 break; 487 } 488 writeb(c, port->membase + MCFUART_UTB); 489 for (i = 0; (i < 0x10000); i++) { 490 if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) 491 break; 492 } 493} 494 495/****************************************************************************/ 496 497static void mcf_console_write(struct console *co, const char *s, unsigned int count) 498{ 499 for (; (count); count--, s++) { 500 mcf_console_putc(co, *s); 501 if (*s == '\n') 502 mcf_console_putc(co, '\r'); 503 } 504} 505 506/****************************************************************************/ 507 508static int __init mcf_console_setup(struct console *co, char *options) 509{ 510 struct uart_port *port; 511 int baud = CONFIG_SERIAL_MCF_BAUDRATE; 512 int bits = 8; 513 int parity = 'n'; 514 int flow = 'n'; 515 516 if ((co->index < 0) || (co->index >= MCF_MAXPORTS)) 517 co->index = 0; 518 port = &mcf_ports[co->index].port; 519 if (port->membase == 0) 520 return -ENODEV; 521 522 if (options) 523 uart_parse_options(options, &baud, &parity, &bits, &flow); 524 525 return uart_set_options(port, co, baud, parity, bits, flow); 526} 527 528/****************************************************************************/ 529 530static struct uart_driver mcf_driver; 531 532static struct console mcf_console = { 533 .name = "ttyS", 534 .write = mcf_console_write, 535 .device = uart_console_device, 536 .setup = mcf_console_setup, 537 .flags = CON_PRINTBUFFER, 538 .index = -1, 539 .data = &mcf_driver, 540}; 541 542static int __init mcf_console_init(void) 543{ 544 register_console(&mcf_console); 545 return 0; 546} 547 548console_initcall(mcf_console_init); 549 550#define MCF_CONSOLE &mcf_console 551 552/****************************************************************************/ 553#else 554/****************************************************************************/ 555 556#define MCF_CONSOLE NULL 557 558/****************************************************************************/ 559#endif /* CONFIG_MCF_CONSOLE */ 560/****************************************************************************/ 561 562/* 563 * Define the mcf UART driver structure. 564 */ 565static struct uart_driver mcf_driver = { 566 .owner = THIS_MODULE, 567 .driver_name = "mcf", 568 .dev_name = "ttyS", 569 .major = TTY_MAJOR, 570 .minor = 64, 571 .nr = MCF_MAXPORTS, 572 .cons = MCF_CONSOLE, 573}; 574 575/****************************************************************************/ 576 577static int __devinit mcf_probe(struct platform_device *pdev) 578{ 579 struct mcf_platform_uart *platp = pdev->dev.platform_data; 580 struct uart_port *port; 581 int i; 582 583 for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) { 584 port = &mcf_ports[i].port; 585 586 port->line = i; 587 port->type = PORT_MCF; 588 port->mapbase = platp[i].mapbase; 589 port->membase = (platp[i].membase) ? platp[i].membase : 590 (unsigned char __iomem *) platp[i].mapbase; 591 port->iotype = SERIAL_IO_MEM; 592 port->irq = platp[i].irq; 593 port->uartclk = MCF_BUSCLK; 594 port->ops = &mcf_uart_ops; 595 port->flags = ASYNC_BOOT_AUTOCONF; 596 597 uart_add_one_port(&mcf_driver, port); 598 } 599 600 return 0; 601} 602 603/****************************************************************************/ 604 605static int mcf_remove(struct platform_device *pdev) 606{ 607 struct uart_port *port; 608 int i; 609 610 for (i = 0; (i < MCF_MAXPORTS); i++) { 611 port = &mcf_ports[i].port; 612 if (port) 613 uart_remove_one_port(&mcf_driver, port); 614 } 615 616 return 0; 617} 618 619/****************************************************************************/ 620 621static struct platform_driver mcf_platform_driver = { 622 .probe = mcf_probe, 623 .remove = __devexit_p(mcf_remove), 624 .driver = { 625 .name = "mcfuart", 626 .owner = THIS_MODULE, 627 }, 628}; 629 630/****************************************************************************/ 631 632static int __init mcf_init(void) 633{ 634 int rc; 635 636 printk("ColdFire internal UART serial driver\n"); 637 638 rc = uart_register_driver(&mcf_driver); 639 if (rc) 640 return rc; 641 rc = platform_driver_register(&mcf_platform_driver); 642 if (rc) 643 return rc; 644 return 0; 645} 646 647/****************************************************************************/ 648 649static void __exit mcf_exit(void) 650{ 651 platform_driver_unregister(&mcf_platform_driver); 652 uart_unregister_driver(&mcf_driver); 653} 654 655/****************************************************************************/ 656 657module_init(mcf_init); 658module_exit(mcf_exit); 659 660MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>"); 661MODULE_DESCRIPTION("Freescale ColdFire UART driver"); 662MODULE_LICENSE("GPL"); 663MODULE_ALIAS("platform:mcfuart"); 664 665/****************************************************************************/