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