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