xref: /openbmc/linux/drivers/tty/serial/altera_uart.c (revision d2168146)
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