2 * Serial driver for ADM5120 SoC
4 * Derived from drivers/serial/uart00.c
5 * Copyright 2001 Altera Corporation
7 * Some pieces are derived from the ADMtek 2.4 serial driver.
8 * Copyright (C) ADMtek Incorporated, 2003
9 * daniell@admtek.com.tw
10 * Which again was derived from drivers/char/serial.c
11 * Copyright (C) Linus Torvalds et al.
13 * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005
16 #include <linux/autoconf.h>
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/ioport.h>
21 #include <linux/serial.h>
22 #include <linux/serial_core.h>
23 #include <linux/tty.h>
24 #include <linux/tty_flip.h>
25 #include <linux/console.h>
27 #define ADM5120_UART_BASE0 0x12600000
28 #define ADM5120_UART_BASE1 0x12800000
29 #define ADM5120_UART_SIZE 0x20
31 #define ADM5120_UART_IRQ0 1
32 #define ADM5120_UART_IRQ1 2
34 #define ADM5120_UART_REG(base, reg) \
35 (*(volatile u32 *)KSEG1ADDR((base)+(reg)))
37 #define ADM5120_UARTCLK_FREQ 62500000
38 #define ADM5120_UART_BAUDDIV(rate) ((unsigned long)(ADM5120_UARTCLK_FREQ/(16*(_rate)) - 1))
40 #define ADM5120_UART_BAUD115200 ADM5120_UART_BAUDDIV(115200)
42 #define ADM5120_UART_DATA 0x00
43 #define ADM5120_UART_RS 0x04
44 #define ADM5120_UART_LCR_H 0x08
45 #define ADM5120_UART_LCR_M 0x0c
46 #define ADM5120_UART_LCR_L 0x10
47 #define ADM5120_UART_CR 0x14
48 #define ADM5120_UART_FR 0x18
49 #define ADM5120_UART_IR 0x1c
51 #define ADM5120_UART_FE 0x01
52 #define ADM5120_UART_PE 0x02
53 #define ADM5120_UART_BE 0x04
54 #define ADM5120_UART_OE 0x08
55 #define ADM5120_UART_ERR 0x0f
56 #define ADM5120_UART_FIFO_EN 0x10
57 #define ADM5120_UART_EN 0x01
58 #define ADM5120_UART_TIE 0x20
59 #define ADM5120_UART_RIE 0x50
60 #define ADM5120_UART_IE 0x78
61 #define ADM5120_UART_CTS 0x01
62 #define ADM5120_UART_DSR 0x02
63 #define ADM5120_UART_DCD 0x04
64 #define ADM5120_UART_TXFF 0x20
65 #define ADM5120_UART_TXFE 0x80
66 #define ADM5120_UART_RXFE 0x10
67 #define ADM5120_UART_BRK 0x01
68 #define ADM5120_UART_PEN 0x02
69 #define ADM5120_UART_EPS 0x04
70 #define ADM5120_UART_STP2 0x08
71 #define ADM5120_UART_W5 0x00
72 #define ADM5120_UART_W6 0x20
73 #define ADM5120_UART_W7 0x40
74 #define ADM5120_UART_W8 0x60
75 #define ADM5120_UART_MIS 0x01
76 #define ADM5120_UART_RIS 0x02
77 #define ADM5120_UART_TIS 0x04
78 #define ADM5120_UART_RTIS 0x08
80 static void adm5120ser_stop_tx(struct uart_port *port)
82 ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) &= ~ADM5120_UART_TIE;
85 static void adm5120ser_irq_rx(struct uart_port *port)
87 struct tty_struct *tty = port->info->tty;
88 unsigned int status, ch, rds, flg, ignored = 0;
90 status = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR);
91 while (!(status & ADM5120_UART_RXFE)) {
93 * We need to read rds before reading the
94 * character from the fifo
96 rds = ADM5120_UART_REG(port->iobase, ADM5120_UART_RS);
97 ch = ADM5120_UART_REG(port->iobase, ADM5120_UART_DATA);
100 if (tty->low_latency)
101 tty_flip_buffer_push(tty);
106 * Note that the error handling code is
107 * out of the main execution path
109 if (rds & ADM5120_UART_ERR)
111 if (uart_handle_sysrq_char(port, ch))
115 tty_insert_flip_char(tty, ch, flg);
118 status = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR);
121 tty_flip_buffer_push(tty);
125 ADM5120_UART_REG(port->iobase, ADM5120_UART_RS) = 0xff;
126 if (rds & ADM5120_UART_BE) {
128 if (uart_handle_break(port))
130 } else if (rds & ADM5120_UART_PE)
131 port->icount.parity++;
132 else if (rds & ADM5120_UART_FE)
133 port->icount.frame++;
134 if (rds & ADM5120_UART_OE)
135 port->icount.overrun++;
137 if (rds & port->ignore_status_mask) {
142 rds &= port->read_status_mask;
144 if (rds & ADM5120_UART_BE)
146 else if (rds & ADM5120_UART_PE)
148 else if (rds & ADM5120_UART_FE)
151 if (rds & ADM5120_UART_OE) {
153 * CHECK: does overrun affect the current character?
154 * ASSUMPTION: it does not.
156 tty_insert_flip_char(tty, ch, flg);
160 #ifdef CONFIG_MAGIC_SYSRQ
166 static void adm5120ser_irq_tx(struct uart_port *port)
168 struct circ_buf *xmit = &port->info->xmit;
172 ADM5120_UART_REG(port->iobase, ADM5120_UART_DATA) =
178 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
179 adm5120ser_stop_tx(port);
183 count = port->fifosize >> 1;
185 ADM5120_UART_REG(port->iobase, ADM5120_UART_DATA) =
186 xmit->buf[xmit->tail];
187 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
189 if (uart_circ_empty(xmit))
191 } while (--count > 0);
193 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
194 uart_write_wakeup(port);
196 if (uart_circ_empty(xmit))
197 adm5120ser_stop_tx(port);
200 static void adm5120ser_irq_modem(struct uart_port *port)
204 status = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR);
206 if (status & ADM5120_UART_DCD)
207 uart_handle_dcd_change(port, status & ADM5120_UART_DCD);
209 if (status & ADM5120_UART_DSR)
212 if (status & ADM5120_UART_CTS)
213 uart_handle_cts_change(port, status & ADM5120_UART_CTS);
215 wake_up_interruptible(&port->info->delta_msr_wait);
218 static irqreturn_t adm5120ser_irq(int irq, void *dev_id)
220 struct uart_port *port = dev_id;
221 unsigned long ir = ADM5120_UART_REG(port->iobase, ADM5120_UART_IR);
223 if (ir & (ADM5120_UART_RIS | ADM5120_UART_RTIS))
224 adm5120ser_irq_rx(port);
225 if (ir & ADM5120_UART_TIS)
226 adm5120ser_irq_tx(port);
227 if (ir & ADM5120_UART_MIS) {
228 adm5120ser_irq_modem(port);
229 ADM5120_UART_REG(port->iobase, ADM5120_UART_IR) = 0xff;
235 static unsigned int adm5120ser_tx_empty(struct uart_port *port)
237 unsigned int fr = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR);
238 return (fr & ADM5120_UART_TXFE) ? TIOCSER_TEMT : 0;
241 static void adm5120ser_set_mctrl(struct uart_port *port, unsigned int mctrl)
245 static unsigned int adm5120ser_get_mctrl(struct uart_port *port)
247 unsigned int result = 0;
248 unsigned int fr = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR);
250 if (fr & ADM5120_UART_CTS)
252 if (fr & ADM5120_UART_DSR)
254 if (fr & ADM5120_UART_DCD)
259 static void adm5120ser_start_tx(struct uart_port *port)
261 ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) |= ADM5120_UART_TIE;
264 static void adm5120ser_stop_rx(struct uart_port *port)
266 ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) &= ~ADM5120_UART_RIE;
269 static void adm5120ser_enable_ms(struct uart_port *port)
273 static void adm5120ser_break_ctl(struct uart_port *port, int break_state)
278 spin_lock_irqsave(&port->lock, flags);
279 lcrh = ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H);
280 if (break_state == -1)
281 lcrh |= ADM5120_UART_BRK;
283 lcrh &= ~ADM5120_UART_BRK;
284 ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H) = lcrh;
285 spin_unlock_irqrestore(&port->lock, flags);
288 static int adm5120ser_startup(struct uart_port *port)
292 ret = request_irq(port->irq, adm5120ser_irq, 0, "ADM5120 UART", port);
294 printk(KERN_ERR "Couldn't get irq %d\n", port->irq);
297 ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H) |=
298 ADM5120_UART_FIFO_EN;
299 ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) |=
300 ADM5120_UART_EN | ADM5120_UART_IE;
304 static void adm5120ser_shutdown(struct uart_port *port)
306 ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) &= ~ADM5120_UART_IE;
307 free_irq(port->irq, port);
310 static void adm5120ser_set_termios(struct uart_port *port,
311 struct termios *termios, struct termios *old)
313 unsigned int baud, quot, lcrh;
316 termios->c_cflag |= CREAD;
318 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
319 quot = uart_get_divisor(port, baud);
321 lcrh = ADM5120_UART_FIFO_EN;
322 switch (termios->c_cflag & CSIZE) {
324 lcrh |= ADM5120_UART_W5;
327 lcrh |= ADM5120_UART_W6;
330 lcrh |= ADM5120_UART_W7;
333 lcrh |= ADM5120_UART_W8;
336 if (termios->c_cflag & CSTOPB)
337 lcrh |= ADM5120_UART_STP2;
338 if (termios->c_cflag & PARENB) {
339 lcrh |= ADM5120_UART_PEN;
340 if (!(termios->c_cflag & PARODD))
341 lcrh |= ADM5120_UART_EPS;
344 spin_lock_irqsave(port->lock, flags);
346 ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H) = lcrh;
349 * Update the per-port timeout.
351 uart_update_timeout(port, termios->c_cflag, baud);
353 port->read_status_mask = ADM5120_UART_OE;
354 if (termios->c_iflag & INPCK)
355 port->read_status_mask |= ADM5120_UART_FE | ADM5120_UART_PE;
356 if (termios->c_iflag & (BRKINT | PARMRK))
357 port->read_status_mask |= ADM5120_UART_BE;
360 * Characters to ignore
362 port->ignore_status_mask = 0;
363 if (termios->c_iflag & IGNPAR)
364 port->ignore_status_mask |= ADM5120_UART_FE | ADM5120_UART_PE;
365 if (termios->c_iflag & IGNBRK) {
366 port->ignore_status_mask |= ADM5120_UART_BE;
368 * If we're ignoring parity and break indicators,
369 * ignore overruns to (for real raw support).
371 if (termios->c_iflag & IGNPAR)
372 port->ignore_status_mask |= ADM5120_UART_OE;
375 quot = ADM5120_UART_BAUD115200;
376 ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_L) = quot & 0xff;
377 ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_M) = quot >> 8;
379 spin_unlock_irqrestore(&port->lock, flags);
382 static const char *adm5120ser_type(struct uart_port *port)
384 return port->type == PORT_ADM5120 ? "ADM5120" : NULL;
387 static void adm5120ser_config_port(struct uart_port *port, int flags)
389 if (flags & UART_CONFIG_TYPE)
390 port->type = PORT_ADM5120;
393 static void adm5120ser_release_port(struct uart_port *port)
395 release_mem_region(port->iobase, ADM5120_UART_SIZE);
398 static int adm5120ser_request_port(struct uart_port *port)
400 return request_mem_region(port->iobase, ADM5120_UART_SIZE,
401 "adm5120-uart") != NULL ? 0 : -EBUSY;
404 static struct uart_ops adm5120ser_ops = {
405 .tx_empty = adm5120ser_tx_empty,
406 .set_mctrl = adm5120ser_set_mctrl,
407 .get_mctrl = adm5120ser_get_mctrl,
408 .stop_tx = adm5120ser_stop_tx,
409 .start_tx = adm5120ser_start_tx,
410 .stop_rx = adm5120ser_stop_rx,
411 .enable_ms = adm5120ser_enable_ms,
412 .break_ctl = adm5120ser_break_ctl,
413 .startup = adm5120ser_startup,
414 .shutdown = adm5120ser_shutdown,
415 .set_termios = adm5120ser_set_termios,
416 .type = adm5120ser_type,
417 .config_port = adm5120ser_config_port,
418 .release_port = adm5120ser_release_port,
419 .request_port = adm5120ser_request_port,
422 static void adm5120console_put(const char c)
424 while ((ADM5120_UART_REG(ADM5120_UART_BASE0, ADM5120_UART_FR) &
425 ADM5120_UART_TXFF) != 0);
426 ADM5120_UART_REG(ADM5120_UART_BASE0, ADM5120_UART_DATA) = c;
429 static void adm5120console_write(struct console *con, const char *s,
434 adm5120console_put('\r');
435 adm5120console_put(*s);
440 static int __init adm5120console_setup(struct console *con, char *options)
442 /* Set to 115200 baud, 8N1 and enable FIFO */
443 ADM5120_UART_REG(ADM5120_UART_BASE0, ADM5120_UART_LCR_L) =
444 ADM5120_UART_BAUD115200 & 0xff;
445 ADM5120_UART_REG(ADM5120_UART_BASE0, ADM5120_UART_LCR_M) =
446 ADM5120_UART_BAUD115200 >> 8;
447 ADM5120_UART_REG(ADM5120_UART_BASE0, ADM5120_UART_LCR_H) =
448 ADM5120_UART_W8 | ADM5120_UART_FIFO_EN;
450 ADM5120_UART_REG(ADM5120_UART_BASE0, ADM5120_UART_CR) =
456 static struct uart_driver adm5120ser_reg;
458 static struct console adm5120_serconsole = {
460 .write = adm5120console_write,
461 .device = uart_console_device,
462 .setup = adm5120console_setup,
463 .flags = CON_PRINTBUFFER,
464 .cflag = B115200 | CS8 | CREAD,
466 .data = &adm5120ser_reg,
469 static int __init adm5120console_init(void)
471 register_console(&adm5120_serconsole);
475 console_initcall(adm5120console_init);
478 static struct uart_port adm5120ser_ports[] = {
480 .iobase = ADM5120_UART_BASE0,
481 .irq = ADM5120_UART_IRQ0,
482 .uartclk = ADM5120_UARTCLK_FREQ,
484 .ops = &adm5120ser_ops,
486 .flags = ASYNC_BOOT_AUTOCONF,
488 #if (CONFIG_ADM5120_NR_UARTS > 1)
490 .iobase = ADM5120_UART_BASE1,
491 .irq = ADM5120_UART_IRQ1,
492 .uartclk = ADM5120_UARTCLK_FREQ,
494 .ops = &adm5120ser_ops,
496 .flags = ASYNC_BOOT_AUTOCONF,
501 static struct uart_driver adm5120ser_reg = {
502 .owner = THIS_MODULE,
503 .driver_name = "ttyS",
507 .nr = CONFIG_ADM5120_NR_UARTS,
508 .cons = &adm5120_serconsole,
511 static int __init adm5120ser_init(void)
515 ret = uart_register_driver(&adm5120ser_reg);
517 for (i = 0; i < CONFIG_ADM5120_NR_UARTS; i++)
518 uart_add_one_port(&adm5120ser_reg, &adm5120ser_ports[i]);
524 __initcall(adm5120ser_init);