percpu: kill legacy percpu allocator
[linux/fpc-iii.git] / drivers / serial / mcf.c
blobb44382442bf113f9a2b8769619991805a24f376b
1 /****************************************************************************/
3 /*
4 * mcf.c -- Freescale ColdFire UART driver
6 * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
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.
14 /****************************************************************************/
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>
31 /****************************************************************************/
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.
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
49 /****************************************************************************/
52 * Local per-uart structure.
54 struct mcf_uart {
55 struct uart_port port;
56 unsigned int sigs; /* Local copy of line sigs */
57 unsigned char imr; /* Local IMR mirror */
60 /****************************************************************************/
62 static unsigned int mcf_tx_empty(struct uart_port *port)
64 return (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXEMPTY) ?
65 TIOCSER_TEMT : 0;
68 /****************************************************************************/
70 static unsigned int mcf_get_mctrl(struct uart_port *port)
72 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
73 unsigned long flags;
74 unsigned int sigs;
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;
86 /****************************************************************************/
88 static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
90 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
91 unsigned long flags;
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);
103 /****************************************************************************/
105 static void mcf_start_tx(struct uart_port *port)
107 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
108 unsigned long flags;
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);
116 /****************************************************************************/
118 static void mcf_stop_tx(struct uart_port *port)
120 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
121 unsigned long flags;
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);
129 /****************************************************************************/
131 static void mcf_stop_rx(struct uart_port *port)
133 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
134 unsigned long flags;
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);
142 /****************************************************************************/
144 static void mcf_break_ctl(struct uart_port *port, int break_state)
146 unsigned long flags;
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);
156 /****************************************************************************/
158 static void mcf_enable_ms(struct uart_port *port)
162 /****************************************************************************/
164 static int mcf_startup(struct uart_port *port)
166 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
167 unsigned long flags;
169 spin_lock_irqsave(&port->lock, flags);
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);
175 /* Enable the UART transmitter and receiver */
176 writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
177 port->membase + MCFUART_UCR);
179 /* Enable RX interrupts now */
180 pp->imr = MCFUART_UIR_RXREADY;
181 writeb(pp->imr, port->membase + MCFUART_UIMR);
183 spin_unlock_irqrestore(&port->lock, flags);
185 return 0;
188 /****************************************************************************/
190 static void mcf_shutdown(struct uart_port *port)
192 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
193 unsigned long flags;
195 spin_lock_irqsave(&port->lock, flags);
197 /* Disable all interrupts now */
198 pp->imr = 0;
199 writeb(pp->imr, port->membase + MCFUART_UIMR);
201 /* Disable UART transmitter and receiver */
202 writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
203 writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
205 spin_unlock_irqrestore(&port->lock, flags);
208 /****************************************************************************/
210 static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
211 struct ktermios *old)
213 unsigned long flags;
214 unsigned int baud, baudclk;
215 #if defined(CONFIG_M5272)
216 unsigned int baudfr;
217 #endif
218 unsigned char mr1, mr2;
220 baud = uart_get_baud_rate(port, termios, old, 0, 230400);
221 #if defined(CONFIG_M5272)
222 baudclk = (MCF_BUSCLK / baud) / 32;
223 baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16;
224 #else
225 baudclk = ((MCF_BUSCLK / baud) + 16) / 32;
226 #endif
228 mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
229 mr2 = 0;
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;
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;
251 } else {
252 mr1 |= MCFUART_MR1_PARITYNONE;
255 if (termios->c_cflag & CSTOPB)
256 mr2 |= MCFUART_MR2_STOP2;
257 else
258 mr2 |= MCFUART_MR2_STOP1;
260 if (termios->c_cflag & CRTSCTS) {
261 mr1 |= MCFUART_MR1_RXRTS;
262 mr2 |= MCFUART_MR2_TXCTS;
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);
273 #if defined(CONFIG_M5272)
274 writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD);
275 #endif
276 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);
283 /****************************************************************************/
285 static void mcf_rx_chars(struct mcf_uart *pp)
287 struct uart_port *port = &pp->port;
288 unsigned char status, ch, flag;
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++;
295 if (status & MCFUART_USR_RXERR) {
296 writeb(MCFUART_UCR_CMDRESETERR,
297 port->membase + MCFUART_UCR);
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++;
311 status &= port->read_status_mask;
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;
321 if (uart_handle_sysrq_char(port, ch))
322 continue;
323 uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
326 tty_flip_buffer_push(port->state->port.tty);
329 /****************************************************************************/
331 static void mcf_tx_chars(struct mcf_uart *pp)
333 struct uart_port *port = &pp->port;
334 struct circ_buf *xmit = &port->state->xmit;
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;
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++;
352 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
353 uart_write_wakeup(port);
355 if (xmit->head == xmit->tail) {
356 pp->imr &= ~MCFUART_UIR_TXREADY;
357 writeb(pp->imr, port->membase + MCFUART_UIMR);
361 /****************************************************************************/
363 static irqreturn_t mcf_interrupt(int irq, void *data)
365 struct uart_port *port = data;
366 struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
367 unsigned int isr;
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;
377 /****************************************************************************/
379 static void mcf_config_port(struct uart_port *port, int flags)
381 port->type = PORT_MCF;
383 /* Clear mask, so no surprise interrupts. */
384 writeb(0, port->membase + MCFUART_UIMR);
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);
391 /****************************************************************************/
393 static const char *mcf_type(struct uart_port *port)
395 return (port->type == PORT_MCF) ? "ColdFire UART" : NULL;
398 /****************************************************************************/
400 static int mcf_request_port(struct uart_port *port)
402 /* UARTs always present */
403 return 0;
406 /****************************************************************************/
408 static void mcf_release_port(struct uart_port *port)
410 /* Nothing to release... */
413 /****************************************************************************/
415 static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
417 if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF))
418 return -EINVAL;
419 return 0;
422 /****************************************************************************/
425 * Define the basic serial functions we support.
427 static 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,
446 static struct mcf_uart mcf_ports[3];
448 #define MCF_MAXPORTS ARRAY_SIZE(mcf_ports)
450 /****************************************************************************/
451 #if defined(CONFIG_SERIAL_MCF_CONSOLE)
452 /****************************************************************************/
454 int __init early_mcf_setup(struct mcf_platform_uart *platp)
456 struct uart_port *port;
457 int i;
459 for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
460 port = &mcf_ports[i].port;
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;
474 return 0;
477 /****************************************************************************/
479 static void mcf_console_putc(struct console *co, const char c)
481 struct uart_port *port = &(mcf_ports + co->index)->port;
482 int i;
484 for (i = 0; (i < 0x10000); i++) {
485 if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
486 break;
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;
495 /****************************************************************************/
497 static void mcf_console_write(struct console *co, const char *s, unsigned int count)
499 for (; (count); count--, s++) {
500 mcf_console_putc(co, *s);
501 if (*s == '\n')
502 mcf_console_putc(co, '\r');
506 /****************************************************************************/
508 static int __init mcf_console_setup(struct console *co, char *options)
510 struct uart_port *port;
511 int baud = CONFIG_SERIAL_MCF_BAUDRATE;
512 int bits = 8;
513 int parity = 'n';
514 int flow = 'n';
516 if ((co->index < 0) || (co->index >= MCF_MAXPORTS))
517 co->index = 0;
518 port = &mcf_ports[co->index].port;
519 if (port->membase == 0)
520 return -ENODEV;
522 if (options)
523 uart_parse_options(options, &baud, &parity, &bits, &flow);
525 return uart_set_options(port, co, baud, parity, bits, flow);
528 /****************************************************************************/
530 static struct uart_driver mcf_driver;
532 static 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,
542 static int __init mcf_console_init(void)
544 register_console(&mcf_console);
545 return 0;
548 console_initcall(mcf_console_init);
550 #define MCF_CONSOLE &mcf_console
552 /****************************************************************************/
553 #else
554 /****************************************************************************/
556 #define MCF_CONSOLE NULL
558 /****************************************************************************/
559 #endif /* CONFIG_MCF_CONSOLE */
560 /****************************************************************************/
563 * Define the mcf UART driver structure.
565 static 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,
575 /****************************************************************************/
577 static int __devinit mcf_probe(struct platform_device *pdev)
579 struct mcf_platform_uart *platp = pdev->dev.platform_data;
580 struct uart_port *port;
581 int i;
583 for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
584 port = &mcf_ports[i].port;
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;
597 uart_add_one_port(&mcf_driver, port);
600 return 0;
603 /****************************************************************************/
605 static int mcf_remove(struct platform_device *pdev)
607 struct uart_port *port;
608 int i;
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);
616 return 0;
619 /****************************************************************************/
621 static 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,
630 /****************************************************************************/
632 static int __init mcf_init(void)
634 int rc;
636 printk("ColdFire internal UART serial driver\n");
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;
647 /****************************************************************************/
649 static void __exit mcf_exit(void)
651 platform_driver_unregister(&mcf_platform_driver);
652 uart_unregister_driver(&mcf_driver);
655 /****************************************************************************/
657 module_init(mcf_init);
658 module_exit(mcf_exit);
660 MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
661 MODULE_DESCRIPTION("Freescale ColdFire UART driver");
662 MODULE_LICENSE("GPL");
663 MODULE_ALIAS("platform:mcfuart");
665 /****************************************************************************/