aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/altera_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/altera_uart.c')
-rw-r--r--drivers/serial/altera_uart.c156
1 files changed, 106 insertions, 50 deletions
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index f8d8a00554da..721216292a50 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/timer.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/console.h> 21#include <linux/console.h>
@@ -27,6 +28,8 @@
27#include <linux/altera_uart.h> 28#include <linux/altera_uart.h>
28 29
29#define DRV_NAME "altera_uart" 30#define DRV_NAME "altera_uart"
31#define SERIAL_ALTERA_MAJOR 204
32#define SERIAL_ALTERA_MINOR 213
30 33
31/* 34/*
32 * Altera UART register definitions according to the Nios UART datasheet: 35 * Altera UART register definitions according to the Nios UART datasheet:
@@ -76,13 +79,28 @@
76 */ 79 */
77struct altera_uart { 80struct altera_uart {
78 struct uart_port port; 81 struct uart_port port;
82 struct timer_list tmr;
79 unsigned int sigs; /* Local copy of line sigs */ 83 unsigned int sigs; /* Local copy of line sigs */
80 unsigned short imr; /* Local IMR mirror */ 84 unsigned short imr; /* Local IMR mirror */
81}; 85};
82 86
87static u32 altera_uart_readl(struct uart_port *port, int reg)
88{
89 struct altera_uart_platform_uart *platp = port->private_data;
90
91 return readl(port->membase + (reg << platp->bus_shift));
92}
93
94static void altera_uart_writel(struct uart_port *port, u32 dat, int reg)
95{
96 struct altera_uart_platform_uart *platp = port->private_data;
97
98 writel(dat, port->membase + (reg << platp->bus_shift));
99}
100
83static unsigned int altera_uart_tx_empty(struct uart_port *port) 101static unsigned int altera_uart_tx_empty(struct uart_port *port)
84{ 102{
85 return (readl(port->membase + ALTERA_UART_STATUS_REG) & 103 return (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
86 ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0; 104 ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0;
87} 105}
88 106
@@ -91,8 +109,7 @@ static unsigned int altera_uart_get_mctrl(struct uart_port *port)
91 struct altera_uart *pp = container_of(port, struct altera_uart, port); 109 struct altera_uart *pp = container_of(port, struct altera_uart, port);
92 unsigned int sigs; 110 unsigned int sigs;
93 111
94 sigs = 112 sigs = (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
95 (readl(port->membase + ALTERA_UART_STATUS_REG) &
96 ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; 113 ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0;
97 sigs |= (pp->sigs & TIOCM_RTS); 114 sigs |= (pp->sigs & TIOCM_RTS);
98 115
@@ -108,7 +125,7 @@ static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs)
108 pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; 125 pp->imr |= ALTERA_UART_CONTROL_RTS_MSK;
109 else 126 else
110 pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; 127 pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK;
111 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 128 altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
112} 129}
113 130
114static void altera_uart_start_tx(struct uart_port *port) 131static void altera_uart_start_tx(struct uart_port *port)
@@ -116,7 +133,7 @@ static void altera_uart_start_tx(struct uart_port *port)
116 struct altera_uart *pp = container_of(port, struct altera_uart, port); 133 struct altera_uart *pp = container_of(port, struct altera_uart, port);
117 134
118 pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; 135 pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK;
119 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 136 altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
120} 137}
121 138
122static void altera_uart_stop_tx(struct uart_port *port) 139static void altera_uart_stop_tx(struct uart_port *port)
@@ -124,7 +141,7 @@ static void altera_uart_stop_tx(struct uart_port *port)
124 struct altera_uart *pp = container_of(port, struct altera_uart, port); 141 struct altera_uart *pp = container_of(port, struct altera_uart, port);
125 142
126 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; 143 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
127 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 144 altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
128} 145}
129 146
130static void altera_uart_stop_rx(struct uart_port *port) 147static void altera_uart_stop_rx(struct uart_port *port)
@@ -132,7 +149,7 @@ static void altera_uart_stop_rx(struct uart_port *port)
132 struct altera_uart *pp = container_of(port, struct altera_uart, port); 149 struct altera_uart *pp = container_of(port, struct altera_uart, port);
133 150
134 pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; 151 pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK;
135 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 152 altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
136} 153}
137 154
138static void altera_uart_break_ctl(struct uart_port *port, int break_state) 155static void altera_uart_break_ctl(struct uart_port *port, int break_state)
@@ -145,7 +162,7 @@ static void altera_uart_break_ctl(struct uart_port *port, int break_state)
145 pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK; 162 pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK;
146 else 163 else
147 pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK; 164 pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK;
148 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 165 altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
149 spin_unlock_irqrestore(&port->lock, flags); 166 spin_unlock_irqrestore(&port->lock, flags);
150} 167}
151 168
@@ -168,7 +185,8 @@ static void altera_uart_set_termios(struct uart_port *port,
168 tty_termios_encode_baud_rate(termios, baud, baud); 185 tty_termios_encode_baud_rate(termios, baud, baud);
169 186
170 spin_lock_irqsave(&port->lock, flags); 187 spin_lock_irqsave(&port->lock, flags);
171 writel(baudclk, port->membase + ALTERA_UART_DIVISOR_REG); 188 uart_update_timeout(port, termios->c_cflag, baud);
189 altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG);
172 spin_unlock_irqrestore(&port->lock, flags); 190 spin_unlock_irqrestore(&port->lock, flags);
173} 191}
174 192
@@ -178,14 +196,15 @@ static void altera_uart_rx_chars(struct altera_uart *pp)
178 unsigned char ch, flag; 196 unsigned char ch, flag;
179 unsigned short status; 197 unsigned short status;
180 198
181 while ((status = readl(port->membase + ALTERA_UART_STATUS_REG)) & 199 while ((status = altera_uart_readl(port, ALTERA_UART_STATUS_REG)) &
182 ALTERA_UART_STATUS_RRDY_MSK) { 200 ALTERA_UART_STATUS_RRDY_MSK) {
183 ch = readl(port->membase + ALTERA_UART_RXDATA_REG); 201 ch = altera_uart_readl(port, ALTERA_UART_RXDATA_REG);
184 flag = TTY_NORMAL; 202 flag = TTY_NORMAL;
185 port->icount.rx++; 203 port->icount.rx++;
186 204
187 if (status & ALTERA_UART_STATUS_E_MSK) { 205 if (status & ALTERA_UART_STATUS_E_MSK) {
188 writel(status, port->membase + ALTERA_UART_STATUS_REG); 206 altera_uart_writel(port, status,
207 ALTERA_UART_STATUS_REG);
189 208
190 if (status & ALTERA_UART_STATUS_BRK_MSK) { 209 if (status & ALTERA_UART_STATUS_BRK_MSK) {
191 port->icount.brk++; 210 port->icount.brk++;
@@ -225,18 +244,18 @@ static void altera_uart_tx_chars(struct altera_uart *pp)
225 244
226 if (port->x_char) { 245 if (port->x_char) {
227 /* Send special char - probably flow control */ 246 /* Send special char - probably flow control */
228 writel(port->x_char, port->membase + ALTERA_UART_TXDATA_REG); 247 altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG);
229 port->x_char = 0; 248 port->x_char = 0;
230 port->icount.tx++; 249 port->icount.tx++;
231 return; 250 return;
232 } 251 }
233 252
234 while (readl(port->membase + ALTERA_UART_STATUS_REG) & 253 while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
235 ALTERA_UART_STATUS_TRDY_MSK) { 254 ALTERA_UART_STATUS_TRDY_MSK) {
236 if (xmit->head == xmit->tail) 255 if (xmit->head == xmit->tail)
237 break; 256 break;
238 writel(xmit->buf[xmit->tail], 257 altera_uart_writel(port, xmit->buf[xmit->tail],
239 port->membase + ALTERA_UART_TXDATA_REG); 258 ALTERA_UART_TXDATA_REG);
240 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 259 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
241 port->icount.tx++; 260 port->icount.tx++;
242 } 261 }
@@ -246,7 +265,7 @@ static void altera_uart_tx_chars(struct altera_uart *pp)
246 265
247 if (xmit->head == xmit->tail) { 266 if (xmit->head == xmit->tail) {
248 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; 267 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
249 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); 268 altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG);
250 } 269 }
251} 270}
252 271
@@ -256,7 +275,7 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data)
256 struct altera_uart *pp = container_of(port, struct altera_uart, port); 275 struct altera_uart *pp = container_of(port, struct altera_uart, port);
257 unsigned int isr; 276 unsigned int isr;
258 277
259 isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr; 278 isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr;
260 279
261 spin_lock(&port->lock); 280 spin_lock(&port->lock);
262 if (isr & ALTERA_UART_STATUS_RRDY_MSK) 281 if (isr & ALTERA_UART_STATUS_RRDY_MSK)
@@ -268,14 +287,23 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data)
268 return IRQ_RETVAL(isr); 287 return IRQ_RETVAL(isr);
269} 288}
270 289
290static void altera_uart_timer(unsigned long data)
291{
292 struct uart_port *port = (void *)data;
293 struct altera_uart *pp = container_of(port, struct altera_uart, port);
294
295 altera_uart_interrupt(0, port);
296 mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port));
297}
298
271static void altera_uart_config_port(struct uart_port *port, int flags) 299static void altera_uart_config_port(struct uart_port *port, int flags)
272{ 300{
273 port->type = PORT_ALTERA_UART; 301 port->type = PORT_ALTERA_UART;
274 302
275 /* Clear mask, so no surprise interrupts. */ 303 /* Clear mask, so no surprise interrupts. */
276 writel(0, port->membase + ALTERA_UART_CONTROL_REG); 304 altera_uart_writel(port, 0, ALTERA_UART_CONTROL_REG);
277 /* Clear status register */ 305 /* Clear status register */
278 writel(0, port->membase + ALTERA_UART_STATUS_REG); 306 altera_uart_writel(port, 0, ALTERA_UART_STATUS_REG);
279} 307}
280 308
281static int altera_uart_startup(struct uart_port *port) 309static int altera_uart_startup(struct uart_port *port)
@@ -284,6 +312,12 @@ static int altera_uart_startup(struct uart_port *port)
284 unsigned long flags; 312 unsigned long flags;
285 int ret; 313 int ret;
286 314
315 if (!port->irq) {
316 setup_timer(&pp->tmr, altera_uart_timer, (unsigned long)port);
317 mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port));
318 return 0;
319 }
320
287 ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED, 321 ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED,
288 DRV_NAME, port); 322 DRV_NAME, port);
289 if (ret) { 323 if (ret) {
@@ -316,7 +350,10 @@ static void altera_uart_shutdown(struct uart_port *port)
316 350
317 spin_unlock_irqrestore(&port->lock, flags); 351 spin_unlock_irqrestore(&port->lock, flags);
318 352
319 free_irq(port->irq, port); 353 if (port->irq)
354 free_irq(port->irq, port);
355 else
356 del_timer_sync(&pp->tmr);
320} 357}
321 358
322static const char *altera_uart_type(struct uart_port *port) 359static const char *altera_uart_type(struct uart_port *port)
@@ -384,8 +421,9 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
384 port->iotype = SERIAL_IO_MEM; 421 port->iotype = SERIAL_IO_MEM;
385 port->irq = platp[i].irq; 422 port->irq = platp[i].irq;
386 port->uartclk = platp[i].uartclk; 423 port->uartclk = platp[i].uartclk;
387 port->flags = ASYNC_BOOT_AUTOCONF; 424 port->flags = UPF_BOOT_AUTOCONF;
388 port->ops = &altera_uart_ops; 425 port->ops = &altera_uart_ops;
426 port->private_data = platp;
389 } 427 }
390 428
391 return 0; 429 return 0;
@@ -393,7 +431,7 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
393 431
394static void altera_uart_console_putc(struct uart_port *port, const char c) 432static void altera_uart_console_putc(struct uart_port *port, const char c)
395{ 433{
396 while (!(readl(port->membase + ALTERA_UART_STATUS_REG) & 434 while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
397 ALTERA_UART_STATUS_TRDY_MSK)) 435 ALTERA_UART_STATUS_TRDY_MSK))
398 cpu_relax(); 436 cpu_relax();
399 437
@@ -423,7 +461,7 @@ static int __init altera_uart_console_setup(struct console *co, char *options)
423 if (co->index < 0 || co->index >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS) 461 if (co->index < 0 || co->index >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
424 return -EINVAL; 462 return -EINVAL;
425 port = &altera_uart_ports[co->index].port; 463 port = &altera_uart_ports[co->index].port;
426 if (port->membase == 0) 464 if (!port->membase)
427 return -ENODEV; 465 return -ENODEV;
428 466
429 if (options) 467 if (options)
@@ -435,7 +473,7 @@ static int __init altera_uart_console_setup(struct console *co, char *options)
435static struct uart_driver altera_uart_driver; 473static struct uart_driver altera_uart_driver;
436 474
437static struct console altera_uart_console = { 475static struct console altera_uart_console = {
438 .name = "ttyS", 476 .name = "ttyAL",
439 .write = altera_uart_console_write, 477 .write = altera_uart_console_write,
440 .device = uart_console_device, 478 .device = uart_console_device,
441 .setup = altera_uart_console_setup, 479 .setup = altera_uart_console_setup,
@@ -466,9 +504,9 @@ console_initcall(altera_uart_console_init);
466static struct uart_driver altera_uart_driver = { 504static struct uart_driver altera_uart_driver = {
467 .owner = THIS_MODULE, 505 .owner = THIS_MODULE,
468 .driver_name = DRV_NAME, 506 .driver_name = DRV_NAME,
469 .dev_name = "ttyS", 507 .dev_name = "ttyAL",
470 .major = TTY_MAJOR, 508 .major = SERIAL_ALTERA_MAJOR,
471 .minor = 64, 509 .minor = SERIAL_ALTERA_MINOR,
472 .nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS, 510 .nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS,
473 .cons = ALTERA_UART_CONSOLE, 511 .cons = ALTERA_UART_CONSOLE,
474}; 512};
@@ -477,38 +515,55 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
477{ 515{
478 struct altera_uart_platform_uart *platp = pdev->dev.platform_data; 516 struct altera_uart_platform_uart *platp = pdev->dev.platform_data;
479 struct uart_port *port; 517 struct uart_port *port;
480 int i; 518 struct resource *res_mem;
519 struct resource *res_irq;
520 int i = pdev->id;
481 521
482 for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) { 522 /* -1 emphasizes that the platform must have one port, no .N suffix */
483 port = &altera_uart_ports[i].port; 523 if (i == -1)
524 i = 0;
484 525
485 port->line = i; 526 if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
486 port->type = PORT_ALTERA_UART; 527 return -EINVAL;
487 port->mapbase = platp[i].mapbase;
488 port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
489 port->iotype = SERIAL_IO_MEM;
490 port->irq = platp[i].irq;
491 port->uartclk = platp[i].uartclk;
492 port->ops = &altera_uart_ops;
493 port->flags = ASYNC_BOOT_AUTOCONF;
494 528
495 uart_add_one_port(&altera_uart_driver, port); 529 port = &altera_uart_ports[i].port;
496 } 530
531 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
532 if (res_mem)
533 port->mapbase = res_mem->start;
534 else if (platp->mapbase)
535 port->mapbase = platp->mapbase;
536 else
537 return -EINVAL;
538
539 res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
540 if (res_irq)
541 port->irq = res_irq->start;
542 else if (platp->irq)
543 port->irq = platp->irq;
544
545 port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
546 if (!port->membase)
547 return -ENOMEM;
548
549 port->line = i;
550 port->type = PORT_ALTERA_UART;
551 port->iotype = SERIAL_IO_MEM;
552 port->uartclk = platp->uartclk;
553 port->ops = &altera_uart_ops;
554 port->flags = UPF_BOOT_AUTOCONF;
555 port->private_data = platp;
556
557 uart_add_one_port(&altera_uart_driver, port);
497 558
498 return 0; 559 return 0;
499} 560}
500 561
501static int __devexit altera_uart_remove(struct platform_device *pdev) 562static int __devexit altera_uart_remove(struct platform_device *pdev)
502{ 563{
503 struct uart_port *port; 564 struct uart_port *port = &altera_uart_ports[pdev->id].port;
504 int i;
505
506 for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++) {
507 port = &altera_uart_ports[i].port;
508 if (port)
509 uart_remove_one_port(&altera_uart_driver, port);
510 }
511 565
566 uart_remove_one_port(&altera_uart_driver, port);
512 return 0; 567 return 0;
513} 568}
514 569
@@ -550,3 +605,4 @@ MODULE_DESCRIPTION("Altera UART driver");
550MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); 605MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
551MODULE_LICENSE("GPL"); 606MODULE_LICENSE("GPL");
552MODULE_ALIAS("platform:" DRV_NAME); 607MODULE_ALIAS("platform:" DRV_NAME);
608MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_ALTERA_MAJOR);