Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /****************************************************************************/
0003 
0004 /*
0005  *  mcf.c -- Freescale ColdFire UART driver
0006  *
0007  *  (C) Copyright 2003-2007, Greg Ungerer <gerg@uclinux.org>
0008  */
0009 
0010 /****************************************************************************/
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/init.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/module.h>
0016 #include <linux/console.h>
0017 #include <linux/tty.h>
0018 #include <linux/tty_flip.h>
0019 #include <linux/serial.h>
0020 #include <linux/serial_core.h>
0021 #include <linux/io.h>
0022 #include <linux/uaccess.h>
0023 #include <linux/platform_device.h>
0024 #include <asm/coldfire.h>
0025 #include <asm/mcfsim.h>
0026 #include <asm/mcfuart.h>
0027 #include <asm/nettel.h>
0028 
0029 /****************************************************************************/
0030 
0031 /*
0032  *  Some boards implement the DTR/DCD lines using GPIO lines, most
0033  *  don't. Dummy out the access macros for those that don't. Those
0034  *  that do should define these macros somewhere in there board
0035  *  specific inlude files.
0036  */
0037 #if !defined(mcf_getppdcd)
0038 #define mcf_getppdcd(p)     (1)
0039 #endif
0040 #if !defined(mcf_getppdtr)
0041 #define mcf_getppdtr(p)     (1)
0042 #endif
0043 #if !defined(mcf_setppdtr)
0044 #define mcf_setppdtr(p, v)  do { } while (0)
0045 #endif
0046 
0047 /****************************************************************************/
0048 
0049 /*
0050  *  Local per-uart structure.
0051  */
0052 struct mcf_uart {
0053     struct uart_port    port;
0054     unsigned int        sigs;       /* Local copy of line sigs */
0055     unsigned char       imr;        /* Local IMR mirror */
0056 };
0057 
0058 /****************************************************************************/
0059 
0060 static unsigned int mcf_tx_empty(struct uart_port *port)
0061 {
0062     return (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXEMPTY) ?
0063         TIOCSER_TEMT : 0;
0064 }
0065 
0066 /****************************************************************************/
0067 
0068 static unsigned int mcf_get_mctrl(struct uart_port *port)
0069 {
0070     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0071     unsigned int sigs;
0072 
0073     sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ?
0074         0 : TIOCM_CTS;
0075     sigs |= (pp->sigs & TIOCM_RTS);
0076     sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0);
0077     sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0);
0078 
0079     return sigs;
0080 }
0081 
0082 /****************************************************************************/
0083 
0084 static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
0085 {
0086     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0087 
0088     pp->sigs = sigs;
0089     mcf_setppdtr(port->line, (sigs & TIOCM_DTR));
0090     if (sigs & TIOCM_RTS)
0091         writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1);
0092     else
0093         writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0);
0094 }
0095 
0096 /****************************************************************************/
0097 
0098 static void mcf_start_tx(struct uart_port *port)
0099 {
0100     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0101 
0102     if (port->rs485.flags & SER_RS485_ENABLED) {
0103         /* Enable Transmitter */
0104         writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR);
0105         /* Manually assert RTS */
0106         writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1);
0107     }
0108     pp->imr |= MCFUART_UIR_TXREADY;
0109     writeb(pp->imr, port->membase + MCFUART_UIMR);
0110 }
0111 
0112 /****************************************************************************/
0113 
0114 static void mcf_stop_tx(struct uart_port *port)
0115 {
0116     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0117 
0118     pp->imr &= ~MCFUART_UIR_TXREADY;
0119     writeb(pp->imr, port->membase + MCFUART_UIMR);
0120 }
0121 
0122 /****************************************************************************/
0123 
0124 static void mcf_stop_rx(struct uart_port *port)
0125 {
0126     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0127 
0128     pp->imr &= ~MCFUART_UIR_RXREADY;
0129     writeb(pp->imr, port->membase + MCFUART_UIMR);
0130 }
0131 
0132 /****************************************************************************/
0133 
0134 static void mcf_break_ctl(struct uart_port *port, int break_state)
0135 {
0136     unsigned long flags;
0137 
0138     spin_lock_irqsave(&port->lock, flags);
0139     if (break_state == -1)
0140         writeb(MCFUART_UCR_CMDBREAKSTART, port->membase + MCFUART_UCR);
0141     else
0142         writeb(MCFUART_UCR_CMDBREAKSTOP, port->membase + MCFUART_UCR);
0143     spin_unlock_irqrestore(&port->lock, flags);
0144 }
0145 
0146 /****************************************************************************/
0147 
0148 static int mcf_startup(struct uart_port *port)
0149 {
0150     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0151     unsigned long flags;
0152 
0153     spin_lock_irqsave(&port->lock, flags);
0154 
0155     /* Reset UART, get it into known state... */
0156     writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
0157     writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
0158 
0159     /* Enable the UART transmitter and receiver */
0160     writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
0161         port->membase + MCFUART_UCR);
0162 
0163     /* Enable RX interrupts now */
0164     pp->imr = MCFUART_UIR_RXREADY;
0165     writeb(pp->imr, port->membase + MCFUART_UIMR);
0166 
0167     spin_unlock_irqrestore(&port->lock, flags);
0168 
0169     return 0;
0170 }
0171 
0172 /****************************************************************************/
0173 
0174 static void mcf_shutdown(struct uart_port *port)
0175 {
0176     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0177     unsigned long flags;
0178 
0179     spin_lock_irqsave(&port->lock, flags);
0180 
0181     /* Disable all interrupts now */
0182     pp->imr = 0;
0183     writeb(pp->imr, port->membase + MCFUART_UIMR);
0184 
0185     /* Disable UART transmitter and receiver */
0186     writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
0187     writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
0188 
0189     spin_unlock_irqrestore(&port->lock, flags);
0190 }
0191 
0192 /****************************************************************************/
0193 
0194 static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
0195     struct ktermios *old)
0196 {
0197     unsigned long flags;
0198     unsigned int baud, baudclk;
0199 #if defined(CONFIG_M5272)
0200     unsigned int baudfr;
0201 #endif
0202     unsigned char mr1, mr2;
0203 
0204     baud = uart_get_baud_rate(port, termios, old, 0, 230400);
0205 #if defined(CONFIG_M5272)
0206     baudclk = (MCF_BUSCLK / baud) / 32;
0207     baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16;
0208 #else
0209     baudclk = ((MCF_BUSCLK / baud) + 16) / 32;
0210 #endif
0211 
0212     mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
0213     mr2 = 0;
0214 
0215     switch (termios->c_cflag & CSIZE) {
0216     case CS5: mr1 |= MCFUART_MR1_CS5; break;
0217     case CS6: mr1 |= MCFUART_MR1_CS6; break;
0218     case CS7: mr1 |= MCFUART_MR1_CS7; break;
0219     case CS8:
0220     default:  mr1 |= MCFUART_MR1_CS8; break;
0221     }
0222 
0223     if (termios->c_cflag & PARENB) {
0224         if (termios->c_cflag & CMSPAR) {
0225             if (termios->c_cflag & PARODD)
0226                 mr1 |= MCFUART_MR1_PARITYMARK;
0227             else
0228                 mr1 |= MCFUART_MR1_PARITYSPACE;
0229         } else {
0230             if (termios->c_cflag & PARODD)
0231                 mr1 |= MCFUART_MR1_PARITYODD;
0232             else
0233                 mr1 |= MCFUART_MR1_PARITYEVEN;
0234         }
0235     } else {
0236         mr1 |= MCFUART_MR1_PARITYNONE;
0237     }
0238 
0239     /*
0240      * FIXME: port->read_status_mask and port->ignore_status_mask
0241      * need to be initialized based on termios settings for
0242      * INPCK, IGNBRK, IGNPAR, PARMRK, BRKINT
0243      */
0244 
0245     if (termios->c_cflag & CSTOPB)
0246         mr2 |= MCFUART_MR2_STOP2;
0247     else
0248         mr2 |= MCFUART_MR2_STOP1;
0249 
0250     if (termios->c_cflag & CRTSCTS) {
0251         mr1 |= MCFUART_MR1_RXRTS;
0252         mr2 |= MCFUART_MR2_TXCTS;
0253     }
0254 
0255     spin_lock_irqsave(&port->lock, flags);
0256     if (port->rs485.flags & SER_RS485_ENABLED) {
0257         dev_dbg(port->dev, "Setting UART to RS485\n");
0258         mr2 |= MCFUART_MR2_TXRTS;
0259     }
0260 
0261     uart_update_timeout(port, termios->c_cflag, baud);
0262     writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
0263     writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
0264     writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
0265     writeb(mr1, port->membase + MCFUART_UMR);
0266     writeb(mr2, port->membase + MCFUART_UMR);
0267     writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1);
0268     writeb((baudclk & 0xff), port->membase + MCFUART_UBG2);
0269 #if defined(CONFIG_M5272)
0270     writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD);
0271 #endif
0272     writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER,
0273         port->membase + MCFUART_UCSR);
0274     writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
0275         port->membase + MCFUART_UCR);
0276     spin_unlock_irqrestore(&port->lock, flags);
0277 }
0278 
0279 /****************************************************************************/
0280 
0281 static void mcf_rx_chars(struct mcf_uart *pp)
0282 {
0283     struct uart_port *port = &pp->port;
0284     unsigned char status, ch, flag;
0285 
0286     while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) {
0287         ch = readb(port->membase + MCFUART_URB);
0288         flag = TTY_NORMAL;
0289         port->icount.rx++;
0290 
0291         if (status & MCFUART_USR_RXERR) {
0292             writeb(MCFUART_UCR_CMDRESETERR,
0293                 port->membase + MCFUART_UCR);
0294 
0295             if (status & MCFUART_USR_RXBREAK) {
0296                 port->icount.brk++;
0297                 if (uart_handle_break(port))
0298                     continue;
0299             } else if (status & MCFUART_USR_RXPARITY) {
0300                 port->icount.parity++;
0301             } else if (status & MCFUART_USR_RXOVERRUN) {
0302                 port->icount.overrun++;
0303             } else if (status & MCFUART_USR_RXFRAMING) {
0304                 port->icount.frame++;
0305             }
0306 
0307             status &= port->read_status_mask;
0308 
0309             if (status & MCFUART_USR_RXBREAK)
0310                 flag = TTY_BREAK;
0311             else if (status & MCFUART_USR_RXPARITY)
0312                 flag = TTY_PARITY;
0313             else if (status & MCFUART_USR_RXFRAMING)
0314                 flag = TTY_FRAME;
0315         }
0316 
0317         if (uart_handle_sysrq_char(port, ch))
0318             continue;
0319         uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
0320     }
0321 
0322     tty_flip_buffer_push(&port->state->port);
0323 }
0324 
0325 /****************************************************************************/
0326 
0327 static void mcf_tx_chars(struct mcf_uart *pp)
0328 {
0329     struct uart_port *port = &pp->port;
0330     struct circ_buf *xmit = &port->state->xmit;
0331 
0332     if (port->x_char) {
0333         /* Send special char - probably flow control */
0334         writeb(port->x_char, port->membase + MCFUART_UTB);
0335         port->x_char = 0;
0336         port->icount.tx++;
0337         return;
0338     }
0339 
0340     while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) {
0341         if (uart_circ_empty(xmit))
0342             break;
0343         writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB);
0344         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
0345         port->icount.tx++;
0346     }
0347 
0348     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0349         uart_write_wakeup(port);
0350 
0351     if (uart_circ_empty(xmit)) {
0352         mcf_stop_tx(port);
0353         /* Disable TX to negate RTS automatically */
0354         if (port->rs485.flags & SER_RS485_ENABLED)
0355             writeb(MCFUART_UCR_TXDISABLE,
0356                 port->membase + MCFUART_UCR);
0357     }
0358 }
0359 
0360 /****************************************************************************/
0361 
0362 static irqreturn_t mcf_interrupt(int irq, void *data)
0363 {
0364     struct uart_port *port = data;
0365     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
0366     unsigned int isr;
0367     irqreturn_t ret = IRQ_NONE;
0368 
0369     isr = readb(port->membase + MCFUART_UISR) & pp->imr;
0370 
0371     spin_lock(&port->lock);
0372     if (isr & MCFUART_UIR_RXREADY) {
0373         mcf_rx_chars(pp);
0374         ret = IRQ_HANDLED;
0375     }
0376     if (isr & MCFUART_UIR_TXREADY) {
0377         mcf_tx_chars(pp);
0378         ret = IRQ_HANDLED;
0379     }
0380     spin_unlock(&port->lock);
0381 
0382     return ret;
0383 }
0384 
0385 /****************************************************************************/
0386 
0387 static void mcf_config_port(struct uart_port *port, int flags)
0388 {
0389     port->type = PORT_MCF;
0390     port->fifosize = MCFUART_TXFIFOSIZE;
0391 
0392     /* Clear mask, so no surprise interrupts. */
0393     writeb(0, port->membase + MCFUART_UIMR);
0394 
0395     if (request_irq(port->irq, mcf_interrupt, 0, "UART", port))
0396         printk(KERN_ERR "MCF: unable to attach ColdFire UART %d "
0397             "interrupt vector=%d\n", port->line, port->irq);
0398 }
0399 
0400 /****************************************************************************/
0401 
0402 static const char *mcf_type(struct uart_port *port)
0403 {
0404     return (port->type == PORT_MCF) ? "ColdFire UART" : NULL;
0405 }
0406 
0407 /****************************************************************************/
0408 
0409 static int mcf_request_port(struct uart_port *port)
0410 {
0411     /* UARTs always present */
0412     return 0;
0413 }
0414 
0415 /****************************************************************************/
0416 
0417 static void mcf_release_port(struct uart_port *port)
0418 {
0419     /* Nothing to release... */
0420 }
0421 
0422 /****************************************************************************/
0423 
0424 static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
0425 {
0426     if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF))
0427         return -EINVAL;
0428     return 0;
0429 }
0430 
0431 /****************************************************************************/
0432 
0433 /* Enable or disable the RS485 support */
0434 static int mcf_config_rs485(struct uart_port *port, struct ktermios *termios,
0435                 struct serial_rs485 *rs485)
0436 {
0437     unsigned char mr1, mr2;
0438 
0439     /* Get mode registers */
0440     mr1 = readb(port->membase + MCFUART_UMR);
0441     mr2 = readb(port->membase + MCFUART_UMR);
0442     if (rs485->flags & SER_RS485_ENABLED) {
0443         dev_dbg(port->dev, "Setting UART to RS485\n");
0444         /* Automatically negate RTS after TX completes */
0445         mr2 |= MCFUART_MR2_TXRTS;
0446     } else {
0447         dev_dbg(port->dev, "Setting UART to RS232\n");
0448         mr2 &= ~MCFUART_MR2_TXRTS;
0449     }
0450     writeb(mr1, port->membase + MCFUART_UMR);
0451     writeb(mr2, port->membase + MCFUART_UMR);
0452 
0453     return 0;
0454 }
0455 
0456 static const struct serial_rs485 mcf_rs485_supported = {
0457     .flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND,
0458 };
0459 
0460 /****************************************************************************/
0461 
0462 /*
0463  *  Define the basic serial functions we support.
0464  */
0465 static const struct uart_ops mcf_uart_ops = {
0466     .tx_empty   = mcf_tx_empty,
0467     .get_mctrl  = mcf_get_mctrl,
0468     .set_mctrl  = mcf_set_mctrl,
0469     .start_tx   = mcf_start_tx,
0470     .stop_tx    = mcf_stop_tx,
0471     .stop_rx    = mcf_stop_rx,
0472     .break_ctl  = mcf_break_ctl,
0473     .startup    = mcf_startup,
0474     .shutdown   = mcf_shutdown,
0475     .set_termios    = mcf_set_termios,
0476     .type       = mcf_type,
0477     .request_port   = mcf_request_port,
0478     .release_port   = mcf_release_port,
0479     .config_port    = mcf_config_port,
0480     .verify_port    = mcf_verify_port,
0481 };
0482 
0483 static struct mcf_uart mcf_ports[4];
0484 
0485 #define MCF_MAXPORTS    ARRAY_SIZE(mcf_ports)
0486 
0487 /****************************************************************************/
0488 #if defined(CONFIG_SERIAL_MCF_CONSOLE)
0489 /****************************************************************************/
0490 
0491 int __init early_mcf_setup(struct mcf_platform_uart *platp)
0492 {
0493     struct uart_port *port;
0494     int i;
0495 
0496     for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
0497         port = &mcf_ports[i].port;
0498 
0499         port->line = i;
0500         port->type = PORT_MCF;
0501         port->mapbase = platp[i].mapbase;
0502         port->membase = (platp[i].membase) ? platp[i].membase :
0503             (unsigned char __iomem *) port->mapbase;
0504         port->iotype = SERIAL_IO_MEM;
0505         port->irq = platp[i].irq;
0506         port->uartclk = MCF_BUSCLK;
0507         port->flags = UPF_BOOT_AUTOCONF;
0508         port->rs485_config = mcf_config_rs485;
0509         port->rs485_supported = mcf_rs485_supported;
0510         port->ops = &mcf_uart_ops;
0511     }
0512 
0513     return 0;
0514 }
0515 
0516 /****************************************************************************/
0517 
0518 static void mcf_console_putc(struct console *co, const char c)
0519 {
0520     struct uart_port *port = &(mcf_ports + co->index)->port;
0521     int i;
0522 
0523     for (i = 0; (i < 0x10000); i++) {
0524         if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
0525             break;
0526     }
0527     writeb(c, port->membase + MCFUART_UTB);
0528     for (i = 0; (i < 0x10000); i++) {
0529         if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
0530             break;
0531     }
0532 }
0533 
0534 /****************************************************************************/
0535 
0536 static void mcf_console_write(struct console *co, const char *s, unsigned int count)
0537 {
0538     for (; (count); count--, s++) {
0539         mcf_console_putc(co, *s);
0540         if (*s == '\n')
0541             mcf_console_putc(co, '\r');
0542     }
0543 }
0544 
0545 /****************************************************************************/
0546 
0547 static int __init mcf_console_setup(struct console *co, char *options)
0548 {
0549     struct uart_port *port;
0550     int baud = CONFIG_SERIAL_MCF_BAUDRATE;
0551     int bits = 8;
0552     int parity = 'n';
0553     int flow = 'n';
0554 
0555     if ((co->index < 0) || (co->index >= MCF_MAXPORTS))
0556         co->index = 0;
0557     port = &mcf_ports[co->index].port;
0558     if (port->membase == 0)
0559         return -ENODEV;
0560 
0561     if (options)
0562         uart_parse_options(options, &baud, &parity, &bits, &flow);
0563 
0564     return uart_set_options(port, co, baud, parity, bits, flow);
0565 }
0566 
0567 /****************************************************************************/
0568 
0569 static struct uart_driver mcf_driver;
0570 
0571 static struct console mcf_console = {
0572     .name       = "ttyS",
0573     .write      = mcf_console_write,
0574     .device     = uart_console_device,
0575     .setup      = mcf_console_setup,
0576     .flags      = CON_PRINTBUFFER,
0577     .index      = -1,
0578     .data       = &mcf_driver,
0579 };
0580 
0581 static int __init mcf_console_init(void)
0582 {
0583     register_console(&mcf_console);
0584     return 0;
0585 }
0586 
0587 console_initcall(mcf_console_init);
0588 
0589 #define MCF_CONSOLE &mcf_console
0590 
0591 /****************************************************************************/
0592 #else
0593 /****************************************************************************/
0594 
0595 #define MCF_CONSOLE NULL
0596 
0597 /****************************************************************************/
0598 #endif /* CONFIG_SERIAL_MCF_CONSOLE */
0599 /****************************************************************************/
0600 
0601 /*
0602  *  Define the mcf UART driver structure.
0603  */
0604 static struct uart_driver mcf_driver = {
0605     .owner      = THIS_MODULE,
0606     .driver_name    = "mcf",
0607     .dev_name   = "ttyS",
0608     .major      = TTY_MAJOR,
0609     .minor      = 64,
0610     .nr     = MCF_MAXPORTS,
0611     .cons       = MCF_CONSOLE,
0612 };
0613 
0614 /****************************************************************************/
0615 
0616 static int mcf_probe(struct platform_device *pdev)
0617 {
0618     struct mcf_platform_uart *platp = dev_get_platdata(&pdev->dev);
0619     struct uart_port *port;
0620     int i;
0621 
0622     for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
0623         port = &mcf_ports[i].port;
0624 
0625         port->line = i;
0626         port->type = PORT_MCF;
0627         port->mapbase = platp[i].mapbase;
0628         port->membase = (platp[i].membase) ? platp[i].membase :
0629             (unsigned char __iomem *) platp[i].mapbase;
0630         port->dev = &pdev->dev;
0631         port->iotype = SERIAL_IO_MEM;
0632         port->irq = platp[i].irq;
0633         port->uartclk = MCF_BUSCLK;
0634         port->ops = &mcf_uart_ops;
0635         port->flags = UPF_BOOT_AUTOCONF;
0636         port->rs485_config = mcf_config_rs485;
0637         port->rs485_supported = mcf_rs485_supported;
0638         port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MCF_CONSOLE);
0639 
0640         uart_add_one_port(&mcf_driver, port);
0641     }
0642 
0643     return 0;
0644 }
0645 
0646 /****************************************************************************/
0647 
0648 static int mcf_remove(struct platform_device *pdev)
0649 {
0650     struct uart_port *port;
0651     int i;
0652 
0653     for (i = 0; (i < MCF_MAXPORTS); i++) {
0654         port = &mcf_ports[i].port;
0655         if (port)
0656             uart_remove_one_port(&mcf_driver, port);
0657     }
0658 
0659     return 0;
0660 }
0661 
0662 /****************************************************************************/
0663 
0664 static struct platform_driver mcf_platform_driver = {
0665     .probe      = mcf_probe,
0666     .remove     = mcf_remove,
0667     .driver     = {
0668         .name   = "mcfuart",
0669     },
0670 };
0671 
0672 /****************************************************************************/
0673 
0674 static int __init mcf_init(void)
0675 {
0676     int rc;
0677 
0678     printk("ColdFire internal UART serial driver\n");
0679 
0680     rc = uart_register_driver(&mcf_driver);
0681     if (rc)
0682         return rc;
0683     rc = platform_driver_register(&mcf_platform_driver);
0684     if (rc) {
0685         uart_unregister_driver(&mcf_driver);
0686         return rc;
0687     }
0688     return 0;
0689 }
0690 
0691 /****************************************************************************/
0692 
0693 static void __exit mcf_exit(void)
0694 {
0695     platform_driver_unregister(&mcf_platform_driver);
0696     uart_unregister_driver(&mcf_driver);
0697 }
0698 
0699 /****************************************************************************/
0700 
0701 module_init(mcf_init);
0702 module_exit(mcf_exit);
0703 
0704 MODULE_AUTHOR("Greg Ungerer <gerg@uclinux.org>");
0705 MODULE_DESCRIPTION("Freescale ColdFire UART driver");
0706 MODULE_LICENSE("GPL");
0707 MODULE_ALIAS("platform:mcfuart");
0708 
0709 /****************************************************************************/