Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvar...
[pandora-kernel.git] / drivers / 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/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/platform_device.h>
26 #include <linux/io.h>
27 #include <linux/altera_uart.h>
28
29 #define DRV_NAME "altera_uart"
30
31 /*
32  * Altera UART register definitions according to the Nios UART datasheet:
33  * http://www.altera.com/literature/ds/ds_nios_uart.pdf
34  */
35
36 #define ALTERA_UART_SIZE                32
37
38 #define ALTERA_UART_RXDATA_REG          0
39 #define ALTERA_UART_TXDATA_REG          4
40 #define ALTERA_UART_STATUS_REG          8
41 #define ALTERA_UART_CONTROL_REG         12
42 #define ALTERA_UART_DIVISOR_REG         16
43 #define ALTERA_UART_EOP_REG             20
44
45 #define ALTERA_UART_STATUS_PE_MSK       0x0001  /* parity error */
46 #define ALTERA_UART_STATUS_FE_MSK       0x0002  /* framing error */
47 #define ALTERA_UART_STATUS_BRK_MSK      0x0004  /* break */
48 #define ALTERA_UART_STATUS_ROE_MSK      0x0008  /* RX overrun error */
49 #define ALTERA_UART_STATUS_TOE_MSK      0x0010  /* TX overrun error */
50 #define ALTERA_UART_STATUS_TMT_MSK      0x0020  /* TX shift register state */
51 #define ALTERA_UART_STATUS_TRDY_MSK     0x0040  /* TX ready */
52 #define ALTERA_UART_STATUS_RRDY_MSK     0x0080  /* RX ready */
53 #define ALTERA_UART_STATUS_E_MSK        0x0100  /* exception condition */
54 #define ALTERA_UART_STATUS_DCTS_MSK     0x0400  /* CTS logic-level change */
55 #define ALTERA_UART_STATUS_CTS_MSK      0x0800  /* CTS logic state */
56 #define ALTERA_UART_STATUS_EOP_MSK      0x1000  /* EOP written/read */
57
58                                                 /* Enable interrupt on... */
59 #define ALTERA_UART_CONTROL_PE_MSK      0x0001  /* ...parity error */
60 #define ALTERA_UART_CONTROL_FE_MSK      0x0002  /* ...framing error */
61 #define ALTERA_UART_CONTROL_BRK_MSK     0x0004  /* ...break */
62 #define ALTERA_UART_CONTROL_ROE_MSK     0x0008  /* ...RX overrun */
63 #define ALTERA_UART_CONTROL_TOE_MSK     0x0010  /* ...TX overrun */
64 #define ALTERA_UART_CONTROL_TMT_MSK     0x0020  /* ...TX shift register empty */
65 #define ALTERA_UART_CONTROL_TRDY_MSK    0x0040  /* ...TX ready */
66 #define ALTERA_UART_CONTROL_RRDY_MSK    0x0080  /* ...RX ready */
67 #define ALTERA_UART_CONTROL_E_MSK       0x0100  /* ...exception*/
68
69 #define ALTERA_UART_CONTROL_TRBK_MSK    0x0200  /* TX break */
70 #define ALTERA_UART_CONTROL_DCTS_MSK    0x0400  /* Interrupt on CTS change */
71 #define ALTERA_UART_CONTROL_RTS_MSK     0x0800  /* RTS signal */
72 #define ALTERA_UART_CONTROL_EOP_MSK     0x1000  /* Interrupt on EOP */
73
74 /*
75  * Local per-uart structure.
76  */
77 struct altera_uart {
78         struct uart_port port;
79         unsigned int sigs;      /* Local copy of line sigs */
80         unsigned short imr;     /* Local IMR mirror */
81 };
82
83 static unsigned int altera_uart_tx_empty(struct uart_port *port)
84 {
85         return (readl(port->membase + ALTERA_UART_STATUS_REG) &
86                 ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0;
87 }
88
89 static unsigned int altera_uart_get_mctrl(struct uart_port *port)
90 {
91         struct altera_uart *pp = container_of(port, struct altera_uart, port);
92         unsigned long flags;
93         unsigned int sigs;
94
95         spin_lock_irqsave(&port->lock, flags);
96         sigs =
97             (readl(port->membase + ALTERA_UART_STATUS_REG) &
98              ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0;
99         sigs |= (pp->sigs & TIOCM_RTS);
100         spin_unlock_irqrestore(&port->lock, flags);
101
102         return sigs;
103 }
104
105 static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs)
106 {
107         struct altera_uart *pp = container_of(port, struct altera_uart, port);
108         unsigned long flags;
109
110         spin_lock_irqsave(&port->lock, flags);
111         pp->sigs = sigs;
112         if (sigs & TIOCM_RTS)
113                 pp->imr |= ALTERA_UART_CONTROL_RTS_MSK;
114         else
115                 pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK;
116         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
117         spin_unlock_irqrestore(&port->lock, flags);
118 }
119
120 static void altera_uart_start_tx(struct uart_port *port)
121 {
122         struct altera_uart *pp = container_of(port, struct altera_uart, port);
123         unsigned long flags;
124
125         spin_lock_irqsave(&port->lock, flags);
126         pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK;
127         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
128         spin_unlock_irqrestore(&port->lock, flags);
129 }
130
131 static void altera_uart_stop_tx(struct uart_port *port)
132 {
133         struct altera_uart *pp = container_of(port, struct altera_uart, port);
134         unsigned long flags;
135
136         spin_lock_irqsave(&port->lock, flags);
137         pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
138         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
139         spin_unlock_irqrestore(&port->lock, flags);
140 }
141
142 static void altera_uart_stop_rx(struct uart_port *port)
143 {
144         struct altera_uart *pp = container_of(port, struct altera_uart, port);
145         unsigned long flags;
146
147         spin_lock_irqsave(&port->lock, flags);
148         pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK;
149         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
150         spin_unlock_irqrestore(&port->lock, flags);
151 }
152
153 static void altera_uart_break_ctl(struct uart_port *port, int break_state)
154 {
155         struct altera_uart *pp = container_of(port, struct altera_uart, port);
156         unsigned long flags;
157
158         spin_lock_irqsave(&port->lock, flags);
159         if (break_state == -1)
160                 pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK;
161         else
162                 pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK;
163         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
164         spin_unlock_irqrestore(&port->lock, flags);
165 }
166
167 static void altera_uart_enable_ms(struct uart_port *port)
168 {
169 }
170
171 static void altera_uart_set_termios(struct uart_port *port,
172                                     struct ktermios *termios,
173                                     struct ktermios *old)
174 {
175         unsigned long flags;
176         unsigned int baud, baudclk;
177
178         baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
179         baudclk = port->uartclk / baud;
180
181         if (old)
182                 tty_termios_copy_hw(termios, old);
183         tty_termios_encode_baud_rate(termios, baud, baud);
184
185         spin_lock_irqsave(&port->lock, flags);
186         writel(baudclk, port->membase + ALTERA_UART_DIVISOR_REG);
187         spin_unlock_irqrestore(&port->lock, flags);
188 }
189
190 static void altera_uart_rx_chars(struct altera_uart *pp)
191 {
192         struct uart_port *port = &pp->port;
193         unsigned char ch, flag;
194         unsigned short status;
195
196         while ((status = readl(port->membase + ALTERA_UART_STATUS_REG)) &
197                ALTERA_UART_STATUS_RRDY_MSK) {
198                 ch = readl(port->membase + ALTERA_UART_RXDATA_REG);
199                 flag = TTY_NORMAL;
200                 port->icount.rx++;
201
202                 if (status & ALTERA_UART_STATUS_E_MSK) {
203                         writel(status, port->membase + ALTERA_UART_STATUS_REG);
204
205                         if (status & ALTERA_UART_STATUS_BRK_MSK) {
206                                 port->icount.brk++;
207                                 if (uart_handle_break(port))
208                                         continue;
209                         } else if (status & ALTERA_UART_STATUS_PE_MSK) {
210                                 port->icount.parity++;
211                         } else if (status & ALTERA_UART_STATUS_ROE_MSK) {
212                                 port->icount.overrun++;
213                         } else if (status & ALTERA_UART_STATUS_FE_MSK) {
214                                 port->icount.frame++;
215                         }
216
217                         status &= port->read_status_mask;
218
219                         if (status & ALTERA_UART_STATUS_BRK_MSK)
220                                 flag = TTY_BREAK;
221                         else if (status & ALTERA_UART_STATUS_PE_MSK)
222                                 flag = TTY_PARITY;
223                         else if (status & ALTERA_UART_STATUS_FE_MSK)
224                                 flag = TTY_FRAME;
225                 }
226
227                 if (uart_handle_sysrq_char(port, ch))
228                         continue;
229                 uart_insert_char(port, status, ALTERA_UART_STATUS_ROE_MSK, ch,
230                                  flag);
231         }
232
233         tty_flip_buffer_push(port->state->port.tty);
234 }
235
236 static void altera_uart_tx_chars(struct altera_uart *pp)
237 {
238         struct uart_port *port = &pp->port;
239         struct circ_buf *xmit = &port->state->xmit;
240
241         if (port->x_char) {
242                 /* Send special char - probably flow control */
243                 writel(port->x_char, port->membase + ALTERA_UART_TXDATA_REG);
244                 port->x_char = 0;
245                 port->icount.tx++;
246                 return;
247         }
248
249         while (readl(port->membase + ALTERA_UART_STATUS_REG) &
250                ALTERA_UART_STATUS_TRDY_MSK) {
251                 if (xmit->head == xmit->tail)
252                         break;
253                 writel(xmit->buf[xmit->tail],
254                        port->membase + ALTERA_UART_TXDATA_REG);
255                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
256                 port->icount.tx++;
257         }
258
259         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
260                 uart_write_wakeup(port);
261
262         if (xmit->head == xmit->tail) {
263                 pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
264                 writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
265         }
266 }
267
268 static irqreturn_t altera_uart_interrupt(int irq, void *data)
269 {
270         struct uart_port *port = data;
271         struct altera_uart *pp = container_of(port, struct altera_uart, port);
272         unsigned int isr;
273
274         isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr;
275         if (isr & ALTERA_UART_STATUS_RRDY_MSK)
276                 altera_uart_rx_chars(pp);
277         if (isr & ALTERA_UART_STATUS_TRDY_MSK)
278                 altera_uart_tx_chars(pp);
279         return IRQ_RETVAL(isr);
280 }
281
282 static void altera_uart_config_port(struct uart_port *port, int flags)
283 {
284         port->type = PORT_ALTERA_UART;
285
286         /* Clear mask, so no surprise interrupts. */
287         writel(0, port->membase + ALTERA_UART_CONTROL_REG);
288         /* Clear status register */
289         writel(0, port->membase + ALTERA_UART_STATUS_REG);
290 }
291
292 static int altera_uart_startup(struct uart_port *port)
293 {
294         struct altera_uart *pp = container_of(port, struct altera_uart, port);
295         unsigned long flags;
296         int ret;
297
298         ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED,
299                         DRV_NAME, port);
300         if (ret) {
301                 pr_err(DRV_NAME ": unable to attach Altera UART %d "
302                        "interrupt vector=%d\n", port->line, port->irq);
303                 return ret;
304         }
305
306         spin_lock_irqsave(&port->lock, flags);
307
308         /* Enable RX interrupts now */
309         pp->imr = ALTERA_UART_CONTROL_RRDY_MSK;
310         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
311
312         spin_unlock_irqrestore(&port->lock, flags);
313
314         return 0;
315 }
316
317 static void altera_uart_shutdown(struct uart_port *port)
318 {
319         struct altera_uart *pp = container_of(port, struct altera_uart, port);
320         unsigned long flags;
321
322         spin_lock_irqsave(&port->lock, flags);
323
324         /* Disable all interrupts now */
325         pp->imr = 0;
326         writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
327
328         spin_unlock_irqrestore(&port->lock, flags);
329
330         free_irq(port->irq, port);
331 }
332
333 static const char *altera_uart_type(struct uart_port *port)
334 {
335         return (port->type == PORT_ALTERA_UART) ? "Altera UART" : NULL;
336 }
337
338 static int altera_uart_request_port(struct uart_port *port)
339 {
340         /* UARTs always present */
341         return 0;
342 }
343
344 static void altera_uart_release_port(struct uart_port *port)
345 {
346         /* Nothing to release... */
347 }
348
349 static int altera_uart_verify_port(struct uart_port *port,
350                                    struct serial_struct *ser)
351 {
352         if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_ALTERA_UART))
353                 return -EINVAL;
354         return 0;
355 }
356
357 /*
358  *      Define the basic serial functions we support.
359  */
360 static struct uart_ops altera_uart_ops = {
361         .tx_empty       = altera_uart_tx_empty,
362         .get_mctrl      = altera_uart_get_mctrl,
363         .set_mctrl      = altera_uart_set_mctrl,
364         .start_tx       = altera_uart_start_tx,
365         .stop_tx        = altera_uart_stop_tx,
366         .stop_rx        = altera_uart_stop_rx,
367         .enable_ms      = altera_uart_enable_ms,
368         .break_ctl      = altera_uart_break_ctl,
369         .startup        = altera_uart_startup,
370         .shutdown       = altera_uart_shutdown,
371         .set_termios    = altera_uart_set_termios,
372         .type           = altera_uart_type,
373         .request_port   = altera_uart_request_port,
374         .release_port   = altera_uart_release_port,
375         .config_port    = altera_uart_config_port,
376         .verify_port    = altera_uart_verify_port,
377 };
378
379 static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS];
380
381 #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
382
383 int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
384 {
385         struct uart_port *port;
386         int i;
387
388         for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) {
389                 port = &altera_uart_ports[i].port;
390
391                 port->line = i;
392                 port->type = PORT_ALTERA_UART;
393                 port->mapbase = platp[i].mapbase;
394                 port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
395                 port->iotype = SERIAL_IO_MEM;
396                 port->irq = platp[i].irq;
397                 port->uartclk = platp[i].uartclk;
398                 port->flags = ASYNC_BOOT_AUTOCONF;
399                 port->ops = &altera_uart_ops;
400         }
401
402         return 0;
403 }
404
405 static void altera_uart_console_putc(struct console *co, const char c)
406 {
407         struct uart_port *port = &(altera_uart_ports + co->index)->port;
408         int i;
409
410         for (i = 0; i < 0x10000; i++) {
411                 if (readl(port->membase + ALTERA_UART_STATUS_REG) &
412                     ALTERA_UART_STATUS_TRDY_MSK)
413                         break;
414         }
415         writel(c, port->membase + ALTERA_UART_TXDATA_REG);
416         for (i = 0; i < 0x10000; i++) {
417                 if (readl(port->membase + ALTERA_UART_STATUS_REG) &
418                     ALTERA_UART_STATUS_TRDY_MSK)
419                         break;
420         }
421 }
422
423 static void altera_uart_console_write(struct console *co, const char *s,
424                                       unsigned int count)
425 {
426         for (; count; count--, s++) {
427                 altera_uart_console_putc(co, *s);
428                 if (*s == '\n')
429                         altera_uart_console_putc(co, '\r');
430         }
431 }
432
433 static int __init altera_uart_console_setup(struct console *co, char *options)
434 {
435         struct uart_port *port;
436         int baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
437         int bits = 8;
438         int parity = 'n';
439         int flow = 'n';
440
441         if (co->index < 0 || co->index >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
442                 return -EINVAL;
443         port = &altera_uart_ports[co->index].port;
444         if (port->membase == 0)
445                 return -ENODEV;
446
447         if (options)
448                 uart_parse_options(options, &baud, &parity, &bits, &flow);
449
450         return uart_set_options(port, co, baud, parity, bits, flow);
451 }
452
453 static struct uart_driver altera_uart_driver;
454
455 static struct console altera_uart_console = {
456         .name   = "ttyS",
457         .write  = altera_uart_console_write,
458         .device = uart_console_device,
459         .setup  = altera_uart_console_setup,
460         .flags  = CON_PRINTBUFFER,
461         .index  = -1,
462         .data   = &altera_uart_driver,
463 };
464
465 static int __init altera_uart_console_init(void)
466 {
467         register_console(&altera_uart_console);
468         return 0;
469 }
470
471 console_initcall(altera_uart_console_init);
472
473 #define ALTERA_UART_CONSOLE     (&altera_uart_console)
474
475 #else
476
477 #define ALTERA_UART_CONSOLE     NULL
478
479 #endif /* CONFIG_ALTERA_UART_CONSOLE */
480
481 /*
482  *      Define the altera_uart UART driver structure.
483  */
484 static struct uart_driver altera_uart_driver = {
485         .owner          = THIS_MODULE,
486         .driver_name    = DRV_NAME,
487         .dev_name       = "ttyS",
488         .major          = TTY_MAJOR,
489         .minor          = 64,
490         .nr             = CONFIG_SERIAL_ALTERA_UART_MAXPORTS,
491         .cons           = ALTERA_UART_CONSOLE,
492 };
493
494 static int __devinit altera_uart_probe(struct platform_device *pdev)
495 {
496         struct altera_uart_platform_uart *platp = pdev->dev.platform_data;
497         struct uart_port *port;
498         int i;
499
500         for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) {
501                 port = &altera_uart_ports[i].port;
502
503                 port->line = i;
504                 port->type = PORT_ALTERA_UART;
505                 port->mapbase = platp[i].mapbase;
506                 port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
507                 port->iotype = SERIAL_IO_MEM;
508                 port->irq = platp[i].irq;
509                 port->uartclk = platp[i].uartclk;
510                 port->ops = &altera_uart_ops;
511                 port->flags = ASYNC_BOOT_AUTOCONF;
512
513                 uart_add_one_port(&altera_uart_driver, port);
514         }
515
516         return 0;
517 }
518
519 static int altera_uart_remove(struct platform_device *pdev)
520 {
521         struct uart_port *port;
522         int i;
523
524         for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++) {
525                 port = &altera_uart_ports[i].port;
526                 if (port)
527                         uart_remove_one_port(&altera_uart_driver, port);
528         }
529
530         return 0;
531 }
532
533 static struct platform_driver altera_uart_platform_driver = {
534         .probe  = altera_uart_probe,
535         .remove = __devexit_p(altera_uart_remove),
536         .driver = {
537                 .name   = DRV_NAME,
538                 .owner  = THIS_MODULE,
539                 .pm     = NULL,
540         },
541 };
542
543 static int __init altera_uart_init(void)
544 {
545         int rc;
546
547         rc = uart_register_driver(&altera_uart_driver);
548         if (rc)
549                 return rc;
550         rc = platform_driver_register(&altera_uart_platform_driver);
551         if (rc) {
552                 uart_unregister_driver(&altera_uart_driver);
553                 return rc;
554         }
555         return 0;
556 }
557
558 static void __exit altera_uart_exit(void)
559 {
560         platform_driver_unregister(&altera_uart_platform_driver);
561         uart_unregister_driver(&altera_uart_driver);
562 }
563
564 module_init(altera_uart_init);
565 module_exit(altera_uart_exit);
566
567 MODULE_DESCRIPTION("Altera UART driver");
568 MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
569 MODULE_LICENSE("GPL");
570 MODULE_ALIAS("platform:" DRV_NAME);