at v2.6.24-rc2 653 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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 unsigned char mr1, mr2; 216 217 baud = uart_get_baud_rate(port, termios, old, 0, 230400); 218 baudclk = ((MCF_BUSCLK / baud) + 16) / 32; 219 220 mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR; 221 mr2 = 0; 222 223 switch (termios->c_cflag & CSIZE) { 224 case CS5: mr1 |= MCFUART_MR1_CS5; break; 225 case CS6: mr1 |= MCFUART_MR1_CS6; break; 226 case CS7: mr1 |= MCFUART_MR1_CS7; break; 227 case CS8: 228 default: mr1 |= MCFUART_MR1_CS8; break; 229 } 230 231 if (termios->c_cflag & PARENB) { 232 if (termios->c_cflag & CMSPAR) { 233 if (termios->c_cflag & PARODD) 234 mr1 |= MCFUART_MR1_PARITYMARK; 235 else 236 mr1 |= MCFUART_MR1_PARITYSPACE; 237 } else { 238 if (termios->c_cflag & PARODD) 239 mr1 |= MCFUART_MR1_PARITYODD; 240 else 241 mr1 |= MCFUART_MR1_PARITYEVEN; 242 } 243 } else { 244 mr1 |= MCFUART_MR1_PARITYNONE; 245 } 246 247 if (termios->c_cflag & CSTOPB) 248 mr2 |= MCFUART_MR2_STOP2; 249 else 250 mr2 |= MCFUART_MR2_STOP1; 251 252 if (termios->c_cflag & CRTSCTS) { 253 mr1 |= MCFUART_MR1_RXRTS; 254 mr2 |= MCFUART_MR2_TXCTS; 255 } 256 257 spin_lock_irqsave(&port->lock, flags); 258 writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); 259 writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); 260 writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); 261 writeb(mr1, port->membase + MCFUART_UMR); 262 writeb(mr2, port->membase + MCFUART_UMR); 263 writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1); 264 writeb((baudclk & 0xff), port->membase + MCFUART_UBG2); 265 writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER, 266 port->membase + MCFUART_UCSR); 267 writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, 268 port->membase + MCFUART_UCR); 269 spin_unlock_irqrestore(&port->lock, flags); 270} 271 272/****************************************************************************/ 273 274static void mcf_rx_chars(struct mcf_uart *pp) 275{ 276 struct uart_port *port = (struct uart_port *) pp; 277 unsigned char status, ch, flag; 278 279 while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) { 280 ch = readb(port->membase + MCFUART_URB); 281 flag = TTY_NORMAL; 282 port->icount.rx++; 283 284 if (status & MCFUART_USR_RXERR) { 285 writeb(MCFUART_UCR_CMDRESETERR, 286 port->membase + MCFUART_UCR); 287 288 if (status & MCFUART_USR_RXBREAK) { 289 port->icount.brk++; 290 if (uart_handle_break(port)) 291 continue; 292 } else if (status & MCFUART_USR_RXPARITY) { 293 port->icount.parity++; 294 } else if (status & MCFUART_USR_RXOVERRUN) { 295 port->icount.overrun++; 296 } else if (status & MCFUART_USR_RXFRAMING) { 297 port->icount.frame++; 298 } 299 300 status &= port->read_status_mask; 301 302 if (status & MCFUART_USR_RXBREAK) 303 flag = TTY_BREAK; 304 else if (status & MCFUART_USR_RXPARITY) 305 flag = TTY_PARITY; 306 else if (status & MCFUART_USR_RXFRAMING) 307 flag = TTY_FRAME; 308 } 309 310 if (uart_handle_sysrq_char(port, ch)) 311 continue; 312 uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); 313 } 314 315 tty_flip_buffer_push(port->info->tty); 316} 317 318/****************************************************************************/ 319 320static void mcf_tx_chars(struct mcf_uart *pp) 321{ 322 struct uart_port *port = (struct uart_port *) pp; 323 struct circ_buf *xmit = &port->info->xmit; 324 325 if (port->x_char) { 326 /* Send special char - probably flow control */ 327 writeb(port->x_char, port->membase + MCFUART_UTB); 328 port->x_char = 0; 329 port->icount.tx++; 330 return; 331 } 332 333 while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) { 334 if (xmit->head == xmit->tail) 335 break; 336 writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB); 337 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1); 338 port->icount.tx++; 339 } 340 341 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 342 uart_write_wakeup(port); 343 344 if (xmit->head == xmit->tail) { 345 pp->imr &= ~MCFUART_UIR_TXREADY; 346 writeb(pp->imr, port->membase + MCFUART_UIMR); 347 } 348} 349 350/****************************************************************************/ 351 352static irqreturn_t mcf_interrupt(int irq, void *data) 353{ 354 struct uart_port *port = data; 355 struct mcf_uart *pp = (struct mcf_uart *) port; 356 unsigned int isr; 357 358 isr = readb(port->membase + MCFUART_UISR) & pp->imr; 359 if (isr & MCFUART_UIR_RXREADY) 360 mcf_rx_chars(pp); 361 if (isr & MCFUART_UIR_TXREADY) 362 mcf_tx_chars(pp); 363 return IRQ_HANDLED; 364} 365 366/****************************************************************************/ 367 368static void mcf_config_port(struct uart_port *port, int flags) 369{ 370 port->type = PORT_MCF; 371 372 /* Clear mask, so no surprise interrupts. */ 373 writeb(0, port->membase + MCFUART_UIMR); 374 375 if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port)) 376 printk(KERN_ERR "MCF: unable to attach ColdFire UART %d " 377 "interrupt vector=%d\n", port->line, port->irq); 378} 379 380/****************************************************************************/ 381 382static const char *mcf_type(struct uart_port *port) 383{ 384 return (port->type == PORT_MCF) ? "ColdFire UART" : NULL; 385} 386 387/****************************************************************************/ 388 389static int mcf_request_port(struct uart_port *port) 390{ 391 /* UARTs always present */ 392 return 0; 393} 394 395/****************************************************************************/ 396 397static void mcf_release_port(struct uart_port *port) 398{ 399 /* Nothing to release... */ 400} 401 402/****************************************************************************/ 403 404static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) 405{ 406 if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF)) 407 return -EINVAL; 408 return 0; 409} 410 411/****************************************************************************/ 412 413/* 414 * Define the basic serial functions we support. 415 */ 416static struct uart_ops mcf_uart_ops = { 417 .tx_empty = mcf_tx_empty, 418 .get_mctrl = mcf_get_mctrl, 419 .set_mctrl = mcf_set_mctrl, 420 .start_tx = mcf_start_tx, 421 .stop_tx = mcf_stop_tx, 422 .stop_rx = mcf_stop_rx, 423 .enable_ms = mcf_enable_ms, 424 .break_ctl = mcf_break_ctl, 425 .startup = mcf_startup, 426 .shutdown = mcf_shutdown, 427 .set_termios = mcf_set_termios, 428 .type = mcf_type, 429 .request_port = mcf_request_port, 430 .release_port = mcf_release_port, 431 .config_port = mcf_config_port, 432 .verify_port = mcf_verify_port, 433}; 434 435static struct mcf_uart mcf_ports[3]; 436 437#define MCF_MAXPORTS (sizeof(mcf_ports) / sizeof(struct mcf_uart)) 438 439/****************************************************************************/ 440#if defined(CONFIG_SERIAL_MCF_CONSOLE) 441/****************************************************************************/ 442 443int __init early_mcf_setup(struct mcf_platform_uart *platp) 444{ 445 struct uart_port *port; 446 int i; 447 448 for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) { 449 port = &mcf_ports[i].port; 450 451 port->line = i; 452 port->type = PORT_MCF; 453 port->mapbase = platp[i].mapbase; 454 port->membase = (platp[i].membase) ? platp[i].membase : 455 (unsigned char __iomem *) port->mapbase; 456 port->iotype = SERIAL_IO_MEM; 457 port->irq = platp[i].irq; 458 port->uartclk = MCF_BUSCLK; 459 port->flags = ASYNC_BOOT_AUTOCONF; 460 port->ops = &mcf_uart_ops; 461 } 462 463 return 0; 464} 465 466/****************************************************************************/ 467 468static void mcf_console_putc(struct console *co, const char c) 469{ 470 struct uart_port *port = &(mcf_ports + co->index)->port; 471 int i; 472 473 for (i = 0; (i < 0x10000); i++) { 474 if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) 475 break; 476 } 477 writeb(c, port->membase + MCFUART_UTB); 478 for (i = 0; (i < 0x10000); i++) { 479 if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) 480 break; 481 } 482} 483 484/****************************************************************************/ 485 486static void mcf_console_write(struct console *co, const char *s, unsigned int count) 487{ 488 for (; (count); count--, s++) { 489 mcf_console_putc(co, *s); 490 if (*s == '\n') 491 mcf_console_putc(co, '\r'); 492 } 493} 494 495/****************************************************************************/ 496 497static int __init mcf_console_setup(struct console *co, char *options) 498{ 499 struct uart_port *port; 500 int baud = CONFIG_SERIAL_MCF_BAUDRATE; 501 int bits = 8; 502 int parity = 'n'; 503 int flow = 'n'; 504 505 if ((co->index >= 0) && (co->index <= MCF_MAXPORTS)) 506 co->index = 0; 507 port = &mcf_ports[co->index].port; 508 if (port->membase == 0) 509 return -ENODEV; 510 511 if (options) 512 uart_parse_options(options, &baud, &parity, &bits, &flow); 513 514 return uart_set_options(port, co, baud, parity, bits, flow); 515} 516 517/****************************************************************************/ 518 519static struct uart_driver mcf_driver; 520 521static struct console mcf_console = { 522 .name = "ttyS", 523 .write = mcf_console_write, 524 .device = uart_console_device, 525 .setup = mcf_console_setup, 526 .flags = CON_PRINTBUFFER, 527 .index = -1, 528 .data = &mcf_driver, 529}; 530 531static int __init mcf_console_init(void) 532{ 533 register_console(&mcf_console); 534 return 0; 535} 536 537console_initcall(mcf_console_init); 538 539#define MCF_CONSOLE &mcf_console 540 541/****************************************************************************/ 542#else 543/****************************************************************************/ 544 545#define MCF_CONSOLE NULL 546 547/****************************************************************************/ 548#endif /* CONFIG_MCF_CONSOLE */ 549/****************************************************************************/ 550 551/* 552 * Define the mcf UART driver structure. 553 */ 554static struct uart_driver mcf_driver = { 555 .owner = THIS_MODULE, 556 .driver_name = "mcf", 557 .dev_name = "ttyS", 558 .major = TTY_MAJOR, 559 .minor = 64, 560 .nr = MCF_MAXPORTS, 561 .cons = MCF_CONSOLE, 562}; 563 564/****************************************************************************/ 565 566static int __devinit mcf_probe(struct platform_device *pdev) 567{ 568 struct mcf_platform_uart *platp = pdev->dev.platform_data; 569 struct uart_port *port; 570 int i; 571 572 for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) { 573 port = &mcf_ports[i].port; 574 575 port->line = i; 576 port->type = PORT_MCF; 577 port->mapbase = platp[i].mapbase; 578 port->membase = (platp[i].membase) ? platp[i].membase : 579 (unsigned char __iomem *) platp[i].mapbase; 580 port->iotype = SERIAL_IO_MEM; 581 port->irq = platp[i].irq; 582 port->uartclk = MCF_BUSCLK; 583 port->ops = &mcf_uart_ops; 584 port->flags = ASYNC_BOOT_AUTOCONF; 585 586 uart_add_one_port(&mcf_driver, port); 587 } 588 589 return 0; 590} 591 592/****************************************************************************/ 593 594static int mcf_remove(struct platform_device *pdev) 595{ 596 struct uart_port *port; 597 int i; 598 599 for (i = 0; (i < MCF_MAXPORTS); i++) { 600 port = &mcf_ports[i].port; 601 if (port) 602 uart_remove_one_port(&mcf_driver, port); 603 } 604 605 return 0; 606} 607 608/****************************************************************************/ 609 610static struct platform_driver mcf_platform_driver = { 611 .probe = mcf_probe, 612 .remove = __devexit_p(mcf_remove), 613 .driver = { 614 .name = "mcfuart", 615 .owner = THIS_MODULE, 616 }, 617}; 618 619/****************************************************************************/ 620 621static int __init mcf_init(void) 622{ 623 int rc; 624 625 printk("ColdFire internal UART serial driver\n"); 626 627 rc = uart_register_driver(&mcf_driver); 628 if (rc) 629 return rc; 630 rc = platform_driver_register(&mcf_platform_driver); 631 if (rc) 632 return rc; 633 return 0; 634} 635 636/****************************************************************************/ 637 638static void __exit mcf_exit(void) 639{ 640 platform_driver_unregister(&mcf_platform_driver); 641 uart_unregister_driver(&mcf_driver); 642} 643 644/****************************************************************************/ 645 646module_init(mcf_init); 647module_exit(mcf_exit); 648 649MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>"); 650MODULE_DESCRIPTION("Freescale ColdFire UART driver"); 651MODULE_LICENSE("GPL"); 652 653/****************************************************************************/