root/drivers/tty/serial/mcf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mcf_tx_empty
  2. mcf_get_mctrl
  3. mcf_set_mctrl
  4. mcf_start_tx
  5. mcf_stop_tx
  6. mcf_stop_rx
  7. mcf_break_ctl
  8. mcf_startup
  9. mcf_shutdown
  10. mcf_set_termios
  11. mcf_rx_chars
  12. mcf_tx_chars
  13. mcf_interrupt
  14. mcf_config_port
  15. mcf_type
  16. mcf_request_port
  17. mcf_release_port
  18. mcf_verify_port
  19. mcf_config_rs485
  20. early_mcf_setup
  21. mcf_console_putc
  22. mcf_console_write
  23. mcf_console_setup
  24. mcf_console_init
  25. mcf_probe
  26. mcf_remove
  27. mcf_init
  28. mcf_exit

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

/* [<][>][^][v][top][bottom][index][help] */