linux/drivers/tty/serial/mcf.c
<<
>>
Prefs
   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 */
  52struct 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
  60static 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
  68static 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
  84static 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
  98static 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
 114static 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
 124static 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
 134static 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
 148static 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
 174static 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
 194static 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
 281static 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        tty_flip_buffer_push(&port->state->port);
 323}
 324
 325/****************************************************************************/
 326
 327static void mcf_tx_chars(struct mcf_uart *pp)
 328{
 329        struct uart_port *port = &pp->port;
 330        struct circ_buf *xmit = &port->state->xmit;
 331
 332        if (port->x_char) {
 333                /* Send special char - probably flow control */
 334                writeb(port->x_char, port->membase + MCFUART_UTB);
 335                port->x_char = 0;
 336                port->icount.tx++;
 337                return;
 338        }
 339
 340        while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) {
 341                if (xmit->head == xmit->tail)
 342                        break;
 343                writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB);
 344                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
 345                port->icount.tx++;
 346        }
 347
 348        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 349                uart_write_wakeup(port);
 350
 351        if (xmit->head == xmit->tail) {
 352                pp->imr &= ~MCFUART_UIR_TXREADY;
 353                writeb(pp->imr, port->membase + MCFUART_UIMR);
 354                /* Disable TX to negate RTS automatically */
 355                if (port->rs485.flags & SER_RS485_ENABLED)
 356                        writeb(MCFUART_UCR_TXDISABLE,
 357                                port->membase + MCFUART_UCR);
 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        irqreturn_t ret = IRQ_NONE;
 369
 370        isr = readb(port->membase + MCFUART_UISR) & pp->imr;
 371
 372        spin_lock(&port->lock);
 373        if (isr & MCFUART_UIR_RXREADY) {
 374                mcf_rx_chars(pp);
 375                ret = IRQ_HANDLED;
 376        }
 377        if (isr & MCFUART_UIR_TXREADY) {
 378                mcf_tx_chars(pp);
 379                ret = IRQ_HANDLED;
 380        }
 381        spin_unlock(&port->lock);
 382
 383        return ret;
 384}
 385
 386/****************************************************************************/
 387
 388static void mcf_config_port(struct uart_port *port, int flags)
 389{
 390        port->type = PORT_MCF;
 391        port->fifosize = MCFUART_TXFIFOSIZE;
 392
 393        /* Clear mask, so no surprise interrupts. */
 394        writeb(0, port->membase + MCFUART_UIMR);
 395
 396        if (request_irq(port->irq, mcf_interrupt, 0, "UART", port))
 397                printk(KERN_ERR "MCF: unable to attach ColdFire UART %d "
 398                        "interrupt vector=%d\n", port->line, port->irq);
 399}
 400
 401/****************************************************************************/
 402
 403static const char *mcf_type(struct uart_port *port)
 404{
 405        return (port->type == PORT_MCF) ? "ColdFire UART" : NULL;
 406}
 407
 408/****************************************************************************/
 409
 410static int mcf_request_port(struct uart_port *port)
 411{
 412        /* UARTs always present */
 413        return 0;
 414}
 415
 416/****************************************************************************/
 417
 418static void mcf_release_port(struct uart_port *port)
 419{
 420        /* Nothing to release... */
 421}
 422
 423/****************************************************************************/
 424
 425static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
 426{
 427        if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF))
 428                return -EINVAL;
 429        return 0;
 430}
 431
 432/****************************************************************************/
 433
 434/* Enable or disable the RS485 support */
 435static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485)
 436{
 437        unsigned char mr1, mr2;
 438
 439        /* Get mode registers */
 440        mr1 = readb(port->membase + MCFUART_UMR);
 441        mr2 = readb(port->membase + MCFUART_UMR);
 442        if (rs485->flags & SER_RS485_ENABLED) {
 443                dev_dbg(port->dev, "Setting UART to RS485\n");
 444                /* Automatically negate RTS after TX completes */
 445                mr2 |= MCFUART_MR2_TXRTS;
 446        } else {
 447                dev_dbg(port->dev, "Setting UART to RS232\n");
 448                mr2 &= ~MCFUART_MR2_TXRTS;
 449        }
 450        writeb(mr1, port->membase + MCFUART_UMR);
 451        writeb(mr2, port->membase + MCFUART_UMR);
 452        port->rs485 = *rs485;
 453
 454        return 0;
 455}
 456
 457/****************************************************************************/
 458
 459/*
 460 *      Define the basic serial functions we support.
 461 */
 462static const struct uart_ops mcf_uart_ops = {
 463        .tx_empty       = mcf_tx_empty,
 464        .get_mctrl      = mcf_get_mctrl,
 465        .set_mctrl      = mcf_set_mctrl,
 466        .start_tx       = mcf_start_tx,
 467        .stop_tx        = mcf_stop_tx,
 468        .stop_rx        = mcf_stop_rx,
 469        .break_ctl      = mcf_break_ctl,
 470        .startup        = mcf_startup,
 471        .shutdown       = mcf_shutdown,
 472        .set_termios    = mcf_set_termios,
 473        .type           = mcf_type,
 474        .request_port   = mcf_request_port,
 475        .release_port   = mcf_release_port,
 476        .config_port    = mcf_config_port,
 477        .verify_port    = mcf_verify_port,
 478};
 479
 480static struct mcf_uart mcf_ports[4];
 481
 482#define MCF_MAXPORTS    ARRAY_SIZE(mcf_ports)
 483
 484/****************************************************************************/
 485#if defined(CONFIG_SERIAL_MCF_CONSOLE)
 486/****************************************************************************/
 487
 488int __init early_mcf_setup(struct mcf_platform_uart *platp)
 489{
 490        struct uart_port *port;
 491        int i;
 492
 493        for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
 494                port = &mcf_ports[i].port;
 495
 496                port->line = i;
 497                port->type = PORT_MCF;
 498                port->mapbase = platp[i].mapbase;
 499                port->membase = (platp[i].membase) ? platp[i].membase :
 500                        (unsigned char __iomem *) port->mapbase;
 501                port->iotype = SERIAL_IO_MEM;
 502                port->irq = platp[i].irq;
 503                port->uartclk = MCF_BUSCLK;
 504                port->flags = UPF_BOOT_AUTOCONF;
 505                port->rs485_config = mcf_config_rs485;
 506                port->ops = &mcf_uart_ops;
 507        }
 508
 509        return 0;
 510}
 511
 512/****************************************************************************/
 513
 514static void mcf_console_putc(struct console *co, const char c)
 515{
 516        struct uart_port *port = &(mcf_ports + co->index)->port;
 517        int i;
 518
 519        for (i = 0; (i < 0x10000); i++) {
 520                if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
 521                        break;
 522        }
 523        writeb(c, port->membase + MCFUART_UTB);
 524        for (i = 0; (i < 0x10000); i++) {
 525                if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
 526                        break;
 527        }
 528}
 529
 530/****************************************************************************/
 531
 532static void mcf_console_write(struct console *co, const char *s, unsigned int count)
 533{
 534        for (; (count); count--, s++) {
 535                mcf_console_putc(co, *s);
 536                if (*s == '\n')
 537                        mcf_console_putc(co, '\r');
 538        }
 539}
 540
 541/****************************************************************************/
 542
 543static int __init mcf_console_setup(struct console *co, char *options)
 544{
 545        struct uart_port *port;
 546        int baud = CONFIG_SERIAL_MCF_BAUDRATE;
 547        int bits = 8;
 548        int parity = 'n';
 549        int flow = 'n';
 550
 551        if ((co->index < 0) || (co->index >= MCF_MAXPORTS))
 552                co->index = 0;
 553        port = &mcf_ports[co->index].port;
 554        if (port->membase == 0)
 555                return -ENODEV;
 556
 557        if (options)
 558                uart_parse_options(options, &baud, &parity, &bits, &flow);
 559
 560        return uart_set_options(port, co, baud, parity, bits, flow);
 561}
 562
 563/****************************************************************************/
 564
 565static struct uart_driver mcf_driver;
 566
 567static struct console mcf_console = {
 568        .name           = "ttyS",
 569        .write          = mcf_console_write,
 570        .device         = uart_console_device,
 571        .setup          = mcf_console_setup,
 572        .flags          = CON_PRINTBUFFER,
 573        .index          = -1,
 574        .data           = &mcf_driver,
 575};
 576
 577static int __init mcf_console_init(void)
 578{
 579        register_console(&mcf_console);
 580        return 0;
 581}
 582
 583console_initcall(mcf_console_init);
 584
 585#define MCF_CONSOLE     &mcf_console
 586
 587/****************************************************************************/
 588#else
 589/****************************************************************************/
 590
 591#define MCF_CONSOLE     NULL
 592
 593/****************************************************************************/
 594#endif /* CONFIG_SERIAL_MCF_CONSOLE */
 595/****************************************************************************/
 596
 597/*
 598 *      Define the mcf UART driver structure.
 599 */
 600static struct uart_driver mcf_driver = {
 601        .owner          = THIS_MODULE,
 602        .driver_name    = "mcf",
 603        .dev_name       = "ttyS",
 604        .major          = TTY_MAJOR,
 605        .minor          = 64,
 606        .nr             = MCF_MAXPORTS,
 607        .cons           = MCF_CONSOLE,
 608};
 609
 610/****************************************************************************/
 611
 612static int mcf_probe(struct platform_device *pdev)
 613{
 614        struct mcf_platform_uart *platp = dev_get_platdata(&pdev->dev);
 615        struct uart_port *port;
 616        int i;
 617
 618        for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
 619                port = &mcf_ports[i].port;
 620
 621                port->line = i;
 622                port->type = PORT_MCF;
 623                port->mapbase = platp[i].mapbase;
 624                port->membase = (platp[i].membase) ? platp[i].membase :
 625                        (unsigned char __iomem *) platp[i].mapbase;
 626                port->dev = &pdev->dev;
 627                port->iotype = SERIAL_IO_MEM;
 628                port->irq = platp[i].irq;
 629                port->uartclk = MCF_BUSCLK;
 630                port->ops = &mcf_uart_ops;
 631                port->flags = UPF_BOOT_AUTOCONF;
 632                port->rs485_config = mcf_config_rs485;
 633                port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MCF_CONSOLE);
 634
 635                uart_add_one_port(&mcf_driver, port);
 636        }
 637
 638        return 0;
 639}
 640
 641/****************************************************************************/
 642
 643static int mcf_remove(struct platform_device *pdev)
 644{
 645        struct uart_port *port;
 646        int i;
 647
 648        for (i = 0; (i < MCF_MAXPORTS); i++) {
 649                port = &mcf_ports[i].port;
 650                if (port)
 651                        uart_remove_one_port(&mcf_driver, port);
 652        }
 653
 654        return 0;
 655}
 656
 657/****************************************************************************/
 658
 659static struct platform_driver mcf_platform_driver = {
 660        .probe          = mcf_probe,
 661        .remove         = mcf_remove,
 662        .driver         = {
 663                .name   = "mcfuart",
 664        },
 665};
 666
 667/****************************************************************************/
 668
 669static int __init mcf_init(void)
 670{
 671        int rc;
 672
 673        printk("ColdFire internal UART serial driver\n");
 674
 675        rc = uart_register_driver(&mcf_driver);
 676        if (rc)
 677                return rc;
 678        rc = platform_driver_register(&mcf_platform_driver);
 679        if (rc) {
 680                uart_unregister_driver(&mcf_driver);
 681                return rc;
 682        }
 683        return 0;
 684}
 685
 686/****************************************************************************/
 687
 688static void __exit mcf_exit(void)
 689{
 690        platform_driver_unregister(&mcf_platform_driver);
 691        uart_unregister_driver(&mcf_driver);
 692}
 693
 694/****************************************************************************/
 695
 696module_init(mcf_init);
 697module_exit(mcf_exit);
 698
 699MODULE_AUTHOR("Greg Ungerer <gerg@uclinux.org>");
 700MODULE_DESCRIPTION("Freescale ColdFire UART driver");
 701MODULE_LICENSE("GPL");
 702MODULE_ALIAS("platform:mcfuart");
 703
 704/****************************************************************************/
 705