Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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