Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/tty/serial/altera_uart.c

  1 /*
  2  * altera_uart.c -- Altera UART driver
  3  *
  4  * Based on mcf.c -- Freescale ColdFire UART driver
  5  *
  6  * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
  7  * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw>
  8  * (C) Copyright 2010, Tobias Klauser <tklauser@distanz.ch>
  9  *
 10  * This program is free software; you can redistribute it and/or modify
 11  * it under the terms of the GNU General Public License as published by
 12  * the Free Software Foundation; either version 2 of the License, or
 13  * (at your option) any later version.
 14  */
 15 
 16 #include <linux/kernel.h>
 17 #include <linux/init.h>
 18 #include <linux/timer.h>
 19 #include <linux/interrupt.h>
 20 #include <linux/module.h>
 21 #include <linux/console.h>
 22 #include <linux/tty.h>
 23 #include <linux/tty_flip.h>
 24 #include <linux/serial.h>
 25 #include <linux/serial_core.h>
 26 #include <linux/platform_device.h>
 27 #include <linux/of.h>
 28 #include <linux/io.h>
 29 #include <linux/altera_uart.h>
 30 
 31 #define DRV_NAME "altera_uart"
 32 #define SERIAL_ALTERA_MAJOR 204
 33 #define SERIAL_ALTERA_MINOR 213
 34 
 35 /*
 36  * Altera UART register definitions according to the Nios UART datasheet:
 37  * http://www.altera.com/literature/ds/ds_nios_uart.pdf
 38  */
 39 
 40 #define ALTERA_UART_SIZE                32
 41 
 42 #define ALTERA_UART_RXDATA_REG          0
 43 #define ALTERA_UART_TXDATA_REG          4
 44 #define ALTERA_UART_STATUS_REG          8
 45 #define ALTERA_UART_CONTROL_REG         12
 46 #define ALTERA_UART_DIVISOR_REG         16
 47 #define ALTERA_UART_EOP_REG             20
 48 
 49 #define ALTERA_UART_STATUS_PE_MSK       0x0001  /* parity error */
 50 #define ALTERA_UART_STATUS_FE_MSK       0x0002  /* framing error */
 51 #define ALTERA_UART_STATUS_BRK_MSK      0x0004  /* break */
 52 #define ALTERA_UART_STATUS_ROE_MSK      0x0008  /* RX overrun error */
 53 #define ALTERA_UART_STATUS_TOE_MSK      0x0010  /* TX overrun error */
 54 #define ALTERA_UART_STATUS_TMT_MSK      0x0020  /* TX shift register state */
 55 #define ALTERA_UART_STATUS_TRDY_MSK     0x0040  /* TX ready */
 56 #define ALTERA_UART_STATUS_RRDY_MSK     0x0080  /* RX ready */
 57 #define ALTERA_UART_STATUS_E_MSK        0x0100  /* exception condition */
 58 #define ALTERA_UART_STATUS_DCTS_MSK     0x0400  /* CTS logic-level change */
 59 #define ALTERA_UART_STATUS_CTS_MSK      0x0800  /* CTS logic state */
 60 #define ALTERA_UART_STATUS_EOP_MSK      0x1000  /* EOP written/read */
 61 
 62                                                 /* Enable interrupt on... */
 63 #define ALTERA_UART_CONTROL_PE_MSK      0x0001  /* ...parity error */
 64 #define ALTERA_UART_CONTROL_FE_MSK      0x0002  /* ...framing error */
 65 #define ALTERA_UART_CONTROL_BRK_MSK     0x0004  /* ...break */
 66 #define ALTERA_UART_CONTROL_ROE_MSK     0x0008  /* ...RX overrun */
 67 #define ALTERA_UART_CONTROL_TOE_MSK     0x0010  /* ...TX overrun */
 68 #define ALTERA_UART_CONTROL_TMT_MSK     0x0020  /* ...TX shift register empty */
 69 #define ALTERA_UART_CONTROL_TRDY_MSK    0x0040  /* ...TX ready */
 70 #define ALTERA_UART_CONTROL_RRDY_MSK    0x0080  /* ...RX ready */
 71 #define ALTERA_UART_CONTROL_E_MSK       0x0100  /* ...exception*/
 72 
 73 #define ALTERA_UART_CONTROL_TRBK_MSK    0x0200  /* TX break */
 74 #define ALTERA_UART_CONTROL_DCTS_MSK    0x0400  /* Interrupt on CTS change */
 75 #define ALTERA_UART_CONTROL_RTS_MSK     0x0800  /* RTS signal */
 76 #define ALTERA_UART_CONTROL_EOP_MSK     0x1000  /* Interrupt on EOP */
 77 
 78 /*
 79  * Local per-uart structure.
 80  */
 81 struct altera_uart {
 82         struct uart_port port;
 83         struct timer_list tmr;
 84         unsigned int sigs;      /* Local copy of line sigs */
 85         unsigned short imr;     /* Local IMR mirror */
 86 };
 87 
 88 static u32 altera_uart_readl(struct uart_port *port, int reg)
 89 {
 90         return readl(port->membase + (reg << port->regshift));
 91 }
 92 
 93 static void altera_uart_writel(struct uart_port *port, u32 dat, int reg)
 94 {
 95         writel(dat, port->membase + (reg << port->regshift));
 96 }
 97 
 98 static unsigned int altera_uart_tx_empty(struct uart_port *port)
 99 {
100         return (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
101                 ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0;
102 }
103 
104 static unsigned int altera_uart_get_mctrl(struct uart_port *port)
105 {
106         struct altera_uart *pp = container_of(port, struct altera_uart, port);
107         unsigned int sigs;
108 
109         sigs = (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
110              ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0;
111         sigs |= (pp->sigs & TIOCM_RTS);
112 
113         return sigs;
114 }
115 
116 static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs)
117 {
118         struct altera_uart *pp = container_of(port, struct altera_uart, port);
119 
120         pp->sigs = sigs;
121         if (sigs & TIOCM_RTS)
122                 pp->imr |= ALTERA_UART_CONTROL_RTS_MSK;
123         else
124                 pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK;
125         altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
126 }
127 
128 static void altera_uart_start_tx(struct uart_port *port)
129 {
130         struct altera_uart *pp = container_of(port, struct altera_uart, port);
131 
132         pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK;
133         altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
134 }
135 
136 static void altera_uart_stop_tx(struct uart_port *port)
137 {
138         struct altera_uart *pp = container_of(port, struct altera_uart, port);
139 
140         pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
141         altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
142 }
143 
144 static void altera_uart_stop_rx(struct uart_port *port)
145 {
146         struct altera_uart *pp = container_of(port, struct altera_uart, port);
147 
148         pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK;
149         altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
150 }
151 
152 static void altera_uart_break_ctl(struct uart_port *port, int break_state)
153 {
154         struct altera_uart *pp = container_of(port, struct altera_uart, port);
155         unsigned long flags;
156 
157         spin_lock_irqsave(&port->lock, flags);
158         if (break_state == -1)
159                 pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK;
160         else
161                 pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK;
162         altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
163         spin_unlock_irqrestore(&port->lock, flags);
164 }
165 
166 static void altera_uart_enable_ms(struct uart_port *port)
167 {
168 }
169 
170 static void altera_uart_set_termios(struct uart_port *port,
171                                     struct ktermios *termios,
172                                     struct ktermios *old)
173 {
174         unsigned long flags;
175         unsigned int baud, baudclk;
176 
177         baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
178         baudclk = port->uartclk / baud;
179 
180         if (old)
181                 tty_termios_copy_hw(termios, old);
182         tty_termios_encode_baud_rate(termios, baud, baud);
183 
184         spin_lock_irqsave(&port->lock, flags);
185         uart_update_timeout(port, termios->c_cflag, baud);
186         altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG);
187         spin_unlock_irqrestore(&port->lock, flags);
188 
189         /*
190          * FIXME: port->read_status_mask and port->ignore_status_mask
191          * need to be initialized based on termios settings for
192          * INPCK, IGNBRK, IGNPAR, PARMRK, BRKINT
193          */
194 }
195 
196 static void altera_uart_rx_chars(struct altera_uart *pp)
197 {
198         struct uart_port *port = &pp->port;
199         unsigned char ch, flag;
200         unsigned short status;
201 
202         while ((status = altera_uart_readl(port, ALTERA_UART_STATUS_REG)) &
203                ALTERA_UART_STATUS_RRDY_MSK) {
204                 ch = altera_uart_readl(port, ALTERA_UART_RXDATA_REG);
205                 flag = TTY_NORMAL;
206                 port->icount.rx++;
207 
208                 if (status & ALTERA_UART_STATUS_E_MSK) {
209                         altera_uart_writel(port, status,
210                                            ALTERA_UART_STATUS_REG);
211 
212                         if (status & ALTERA_UART_STATUS_BRK_MSK) {
213                                 port->icount.brk++;
214                                 if (uart_handle_break(port))
215                                         continue;
216                         } else if (status & ALTERA_UART_STATUS_PE_MSK) {
217                                 port->icount.parity++;
218                         } else if (status & ALTERA_UART_STATUS_ROE_MSK) {
219                                 port->icount.overrun++;
220                         } else if (status & ALTERA_UART_STATUS_FE_MSK) {
221                                 port->icount.frame++;
222                         }
223 
224                         status &= port->read_status_mask;
225 
226                         if (status & ALTERA_UART_STATUS_BRK_MSK)
227                                 flag = TTY_BREAK;
228                         else if (status & ALTERA_UART_STATUS_PE_MSK)
229                                 flag = TTY_PARITY;
230                         else if (status & ALTERA_UART_STATUS_FE_MSK)
231                                 flag = TTY_FRAME;
232                 }
233 
234                 if (uart_handle_sysrq_char(port, ch))
235                         continue;
236                 uart_insert_char(port, status, ALTERA_UART_STATUS_ROE_MSK, ch,
237                                  flag);
238         }
239 
240         spin_unlock(&port->lock);
241         tty_flip_buffer_push(&port->state->port);
242         spin_lock(&port->lock);
243 }
244 
245 static void altera_uart_tx_chars(struct altera_uart *pp)
246 {
247         struct uart_port *port = &pp->port;
248         struct circ_buf *xmit = &port->state->xmit;
249 
250         if (port->x_char) {
251                 /* Send special char - probably flow control */
252                 altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG);
253                 port->x_char = 0;
254                 port->icount.tx++;
255                 return;
256         }
257 
258         while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
259                ALTERA_UART_STATUS_TRDY_MSK) {
260                 if (xmit->head == xmit->tail)
261                         break;
262                 altera_uart_writel(port, xmit->buf[xmit->tail],
263                        ALTERA_UART_TXDATA_REG);
264                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
265                 port->icount.tx++;
266         }
267 
268         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
269                 uart_write_wakeup(port);
270 
271         if (xmit->head == xmit->tail) {
272                 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
273                 altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
274         }
275 }
276 
277 static irqreturn_t altera_uart_interrupt(int irq, void *data)
278 {
279         struct uart_port *port = data;
280         struct altera_uart *pp = container_of(port, struct altera_uart, port);
281         unsigned int isr;
282 
283         isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr;
284 
285         spin_lock(&port->lock);
286         if (isr & ALTERA_UART_STATUS_RRDY_MSK)
287                 altera_uart_rx_chars(pp);
288         if (isr & ALTERA_UART_STATUS_TRDY_MSK)
289                 altera_uart_tx_chars(pp);
290         spin_unlock(&port->lock);
291 
292         return IRQ_RETVAL(isr);
293 }
294 
295 static void altera_uart_timer(unsigned long data)
296 {
297         struct uart_port *port = (void *)data;
298         struct altera_uart *pp = container_of(port, struct altera_uart, port);
299 
300         altera_uart_interrupt(0, port);
301         mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port));
302 }
303 
304 static void altera_uart_config_port(struct uart_port *port, int flags)
305 {
306         port->type = PORT_ALTERA_UART;
307 
308         /* Clear mask, so no surprise interrupts. */
309         altera_uart_writel(port, 0, ALTERA_UART_CONTROL_REG);
310         /* Clear status register */
311         altera_uart_writel(port, 0, ALTERA_UART_STATUS_REG);
312 }
313 
314 static int altera_uart_startup(struct uart_port *port)
315 {
316         struct altera_uart *pp = container_of(port, struct altera_uart, port);
317         unsigned long flags;
318         int ret;
319 
320         if (!port->irq) {
321                 setup_timer(&pp->tmr, altera_uart_timer, (unsigned long)port);
322                 mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port));
323                 return 0;
324         }
325 
326         ret = request_irq(port->irq, altera_uart_interrupt, 0,
327                         DRV_NAME, port);
328         if (ret) {
329                 pr_err(DRV_NAME ": unable to attach Altera UART %d "
330                        "interrupt vector=%d\n", port->line, port->irq);
331                 return ret;
332         }
333 
334         spin_lock_irqsave(&port->lock, flags);
335 
336         /* Enable RX interrupts now */
337         pp->imr = ALTERA_UART_CONTROL_RRDY_MSK;
338         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
339 
340         spin_unlock_irqrestore(&port->lock, flags);
341 
342         return 0;
343 }
344 
345 static void altera_uart_shutdown(struct uart_port *port)
346 {
347         struct altera_uart *pp = container_of(port, struct altera_uart, port);
348         unsigned long flags;
349 
350         spin_lock_irqsave(&port->lock, flags);
351 
352         /* Disable all interrupts now */
353         pp->imr = 0;
354         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
355 
356         spin_unlock_irqrestore(&port->lock, flags);
357 
358         if (port->irq)
359                 free_irq(port->irq, port);
360         else
361                 del_timer_sync(&pp->tmr);
362 }
363 
364 static const char *altera_uart_type(struct uart_port *port)
365 {
366         return (port->type == PORT_ALTERA_UART) ? "Altera UART" : NULL;
367 }
368 
369 static int altera_uart_request_port(struct uart_port *port)
370 {
371         /* UARTs always present */
372         return 0;
373 }
374 
375 static void altera_uart_release_port(struct uart_port *port)
376 {
377         /* Nothing to release... */
378 }
379 
380 static int altera_uart_verify_port(struct uart_port *port,
381                                    struct serial_struct *ser)
382 {
383         if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_ALTERA_UART))
384                 return -EINVAL;
385         return 0;
386 }
387 
388 #ifdef CONFIG_CONSOLE_POLL
389 static int altera_uart_poll_get_char(struct uart_port *port)
390 {
391         while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
392                  ALTERA_UART_STATUS_RRDY_MSK))
393                 cpu_relax();
394 
395         return altera_uart_readl(port, ALTERA_UART_RXDATA_REG);
396 }
397 
398 static void altera_uart_poll_put_char(struct uart_port *port, unsigned char c)
399 {
400         while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
401                  ALTERA_UART_STATUS_TRDY_MSK))
402                 cpu_relax();
403 
404         altera_uart_writel(port, c, ALTERA_UART_TXDATA_REG);
405 }
406 #endif
407 
408 /*
409  *      Define the basic serial functions we support.
410  */
411 static struct uart_ops altera_uart_ops = {
412         .tx_empty       = altera_uart_tx_empty,
413         .get_mctrl      = altera_uart_get_mctrl,
414         .set_mctrl      = altera_uart_set_mctrl,
415         .start_tx       = altera_uart_start_tx,
416         .stop_tx        = altera_uart_stop_tx,
417         .stop_rx        = altera_uart_stop_rx,
418         .enable_ms      = altera_uart_enable_ms,
419         .break_ctl      = altera_uart_break_ctl,
420         .startup        = altera_uart_startup,
421         .shutdown       = altera_uart_shutdown,
422         .set_termios    = altera_uart_set_termios,
423         .type           = altera_uart_type,
424         .request_port   = altera_uart_request_port,
425         .release_port   = altera_uart_release_port,
426         .config_port    = altera_uart_config_port,
427         .verify_port    = altera_uart_verify_port,
428 #ifdef CONFIG_CONSOLE_POLL
429         .poll_get_char  = altera_uart_poll_get_char,
430         .poll_put_char  = altera_uart_poll_put_char,
431 #endif
432 };
433 
434 static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS];
435 
436 #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
437 
438 static void altera_uart_console_putc(struct uart_port *port, const char c)
439 {
440         while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
441                  ALTERA_UART_STATUS_TRDY_MSK))
442                 cpu_relax();
443 
444         writel(c, port->membase + ALTERA_UART_TXDATA_REG);
445 }
446 
447 static void altera_uart_console_write(struct console *co, const char *s,
448                                       unsigned int count)
449 {
450         struct uart_port *port = &(altera_uart_ports + co->index)->port;
451 
452         for (; count; count--, s++) {
453                 altera_uart_console_putc(port, *s);
454                 if (*s == '\n')
455                         altera_uart_console_putc(port, '\r');
456         }
457 }
458 
459 static int __init altera_uart_console_setup(struct console *co, char *options)
460 {
461         struct uart_port *port;
462         int baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
463         int bits = 8;
464         int parity = 'n';
465         int flow = 'n';
466 
467         if (co->index < 0 || co->index >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
468                 return -EINVAL;
469         port = &altera_uart_ports[co->index].port;
470         if (!port->membase)
471                 return -ENODEV;
472 
473         if (options)
474                 uart_parse_options(options, &baud, &parity, &bits, &flow);
475 
476         return uart_set_options(port, co, baud, parity, bits, flow);
477 }
478 
479 static struct uart_driver altera_uart_driver;
480 
481 static struct console altera_uart_console = {
482         .name   = "ttyAL",
483         .write  = altera_uart_console_write,
484         .device = uart_console_device,
485         .setup  = altera_uart_console_setup,
486         .flags  = CON_PRINTBUFFER,
487         .index  = -1,
488         .data   = &altera_uart_driver,
489 };
490 
491 static int __init altera_uart_console_init(void)
492 {
493         register_console(&altera_uart_console);
494         return 0;
495 }
496 
497 console_initcall(altera_uart_console_init);
498 
499 #define ALTERA_UART_CONSOLE     (&altera_uart_console)
500 
501 #else
502 
503 #define ALTERA_UART_CONSOLE     NULL
504 
505 #endif /* CONFIG_ALTERA_UART_CONSOLE */
506 
507 /*
508  *      Define the altera_uart UART driver structure.
509  */
510 static struct uart_driver altera_uart_driver = {
511         .owner          = THIS_MODULE,
512         .driver_name    = DRV_NAME,
513         .dev_name       = "ttyAL",
514         .major          = SERIAL_ALTERA_MAJOR,
515         .minor          = SERIAL_ALTERA_MINOR,
516         .nr             = CONFIG_SERIAL_ALTERA_UART_MAXPORTS,
517         .cons           = ALTERA_UART_CONSOLE,
518 };
519 
520 #ifdef CONFIG_OF
521 static int altera_uart_get_of_uartclk(struct platform_device *pdev,
522                                       struct uart_port *port)
523 {
524         int len;
525         const __be32 *clk;
526 
527         clk = of_get_property(pdev->dev.of_node, "clock-frequency", &len);
528         if (!clk || len < sizeof(__be32))
529                 return -ENODEV;
530 
531         port->uartclk = be32_to_cpup(clk);
532 
533         return 0;
534 }
535 #else
536 static int altera_uart_get_of_uartclk(struct platform_device *pdev,
537                                       struct uart_port *port)
538 {
539         return -ENODEV;
540 }
541 #endif /* CONFIG_OF */
542 
543 static int altera_uart_probe(struct platform_device *pdev)
544 {
545         struct altera_uart_platform_uart *platp = dev_get_platdata(&pdev->dev);
546         struct uart_port *port;
547         struct resource *res_mem;
548         struct resource *res_irq;
549         int i = pdev->id;
550         int ret;
551 
552         /* if id is -1 scan for a free id and use that one */
553         if (i == -1) {
554                 for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++)
555                         if (altera_uart_ports[i].port.mapbase == 0)
556                                 break;
557         }
558 
559         if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
560                 return -EINVAL;
561 
562         port = &altera_uart_ports[i].port;
563 
564         res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
565         if (res_mem)
566                 port->mapbase = res_mem->start;
567         else if (platp)
568                 port->mapbase = platp->mapbase;
569         else
570                 return -EINVAL;
571 
572         res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
573         if (res_irq)
574                 port->irq = res_irq->start;
575         else if (platp)
576                 port->irq = platp->irq;
577 
578         /* Check platform data first so we can override device node data */
579         if (platp)
580                 port->uartclk = platp->uartclk;
581         else {
582                 ret = altera_uart_get_of_uartclk(pdev, port);
583                 if (ret)
584                         return ret;
585         }
586 
587         port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
588         if (!port->membase)
589                 return -ENOMEM;
590 
591         if (platp)
592                 port->regshift = platp->bus_shift;
593         else
594                 port->regshift = 0;
595 
596         port->line = i;
597         port->type = PORT_ALTERA_UART;
598         port->iotype = SERIAL_IO_MEM;
599         port->ops = &altera_uart_ops;
600         port->flags = UPF_BOOT_AUTOCONF;
601 
602         platform_set_drvdata(pdev, port);
603 
604         uart_add_one_port(&altera_uart_driver, port);
605 
606         return 0;
607 }
608 
609 static int altera_uart_remove(struct platform_device *pdev)
610 {
611         struct uart_port *port = platform_get_drvdata(pdev);
612 
613         if (port) {
614                 uart_remove_one_port(&altera_uart_driver, port);
615                 port->mapbase = 0;
616         }
617 
618         return 0;
619 }
620 
621 #ifdef CONFIG_OF
622 static struct of_device_id altera_uart_match[] = {
623         { .compatible = "ALTR,uart-1.0", },
624         { .compatible = "altr,uart-1.0", },
625         {},
626 };
627 MODULE_DEVICE_TABLE(of, altera_uart_match);
628 #endif /* CONFIG_OF */
629 
630 static struct platform_driver altera_uart_platform_driver = {
631         .probe  = altera_uart_probe,
632         .remove = altera_uart_remove,
633         .driver = {
634                 .name           = DRV_NAME,
635                 .owner          = THIS_MODULE,
636                 .of_match_table = of_match_ptr(altera_uart_match),
637         },
638 };
639 
640 static int __init altera_uart_init(void)
641 {
642         int rc;
643 
644         rc = uart_register_driver(&altera_uart_driver);
645         if (rc)
646                 return rc;
647         rc = platform_driver_register(&altera_uart_platform_driver);
648         if (rc)
649                 uart_unregister_driver(&altera_uart_driver);
650         return rc;
651 }
652 
653 static void __exit altera_uart_exit(void)
654 {
655         platform_driver_unregister(&altera_uart_platform_driver);
656         uart_unregister_driver(&altera_uart_driver);
657 }
658 
659 module_init(altera_uart_init);
660 module_exit(altera_uart_exit);
661 
662 MODULE_DESCRIPTION("Altera UART driver");
663 MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
664 MODULE_LICENSE("GPL");
665 MODULE_ALIAS("platform:" DRV_NAME);
666 MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_ALTERA_MAJOR);
667 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us