Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / tty / serial / mxs-auart.c
1 /*
2  * Freescale STMP37XX/STMP378X Application UART driver
3  *
4  * Author: dmitry pervushin <dimka@embeddedalley.com>
5  *
6  * Copyright 2008-2010 Freescale Semiconductor, Inc.
7  * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8  *
9  * The code contained herein is licensed under the GNU General Public
10  * License. You may obtain a copy of the GNU General Public License
11  * Version 2 or later at the following locations:
12  *
13  * http://www.opensource.org/licenses/gpl-license.html
14  * http://www.gnu.org/copyleft/gpl.html
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/init.h>
20 #include <linux/console.h>
21 #include <linux/interrupt.h>
22 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/wait.h>
25 #include <linux/tty.h>
26 #include <linux/tty_driver.h>
27 #include <linux/tty_flip.h>
28 #include <linux/serial.h>
29 #include <linux/serial_core.h>
30 #include <linux/platform_device.h>
31 #include <linux/device.h>
32 #include <linux/clk.h>
33 #include <linux/delay.h>
34 #include <linux/io.h>
35 #include <linux/pinctrl/consumer.h>
36 #include <linux/of_device.h>
37
38 #include <asm/cacheflush.h>
39
40 #define MXS_AUART_PORTS 5
41
42 #define AUART_CTRL0                     0x00000000
43 #define AUART_CTRL0_SET                 0x00000004
44 #define AUART_CTRL0_CLR                 0x00000008
45 #define AUART_CTRL0_TOG                 0x0000000c
46 #define AUART_CTRL1                     0x00000010
47 #define AUART_CTRL1_SET                 0x00000014
48 #define AUART_CTRL1_CLR                 0x00000018
49 #define AUART_CTRL1_TOG                 0x0000001c
50 #define AUART_CTRL2                     0x00000020
51 #define AUART_CTRL2_SET                 0x00000024
52 #define AUART_CTRL2_CLR                 0x00000028
53 #define AUART_CTRL2_TOG                 0x0000002c
54 #define AUART_LINECTRL                  0x00000030
55 #define AUART_LINECTRL_SET              0x00000034
56 #define AUART_LINECTRL_CLR              0x00000038
57 #define AUART_LINECTRL_TOG              0x0000003c
58 #define AUART_LINECTRL2                 0x00000040
59 #define AUART_LINECTRL2_SET             0x00000044
60 #define AUART_LINECTRL2_CLR             0x00000048
61 #define AUART_LINECTRL2_TOG             0x0000004c
62 #define AUART_INTR                      0x00000050
63 #define AUART_INTR_SET                  0x00000054
64 #define AUART_INTR_CLR                  0x00000058
65 #define AUART_INTR_TOG                  0x0000005c
66 #define AUART_DATA                      0x00000060
67 #define AUART_STAT                      0x00000070
68 #define AUART_DEBUG                     0x00000080
69 #define AUART_VERSION                   0x00000090
70 #define AUART_AUTOBAUD                  0x000000a0
71
72 #define AUART_CTRL0_SFTRST                      (1 << 31)
73 #define AUART_CTRL0_CLKGATE                     (1 << 30)
74
75 #define AUART_CTRL2_CTSEN                       (1 << 15)
76 #define AUART_CTRL2_RTS                         (1 << 11)
77 #define AUART_CTRL2_RXE                         (1 << 9)
78 #define AUART_CTRL2_TXE                         (1 << 8)
79 #define AUART_CTRL2_UARTEN                      (1 << 0)
80
81 #define AUART_LINECTRL_BAUD_DIVINT_SHIFT        16
82 #define AUART_LINECTRL_BAUD_DIVINT_MASK         0xffff0000
83 #define AUART_LINECTRL_BAUD_DIVINT(v)           (((v) & 0xffff) << 16)
84 #define AUART_LINECTRL_BAUD_DIVFRAC_SHIFT       8
85 #define AUART_LINECTRL_BAUD_DIVFRAC_MASK        0x00003f00
86 #define AUART_LINECTRL_BAUD_DIVFRAC(v)          (((v) & 0x3f) << 8)
87 #define AUART_LINECTRL_WLEN_MASK                0x00000060
88 #define AUART_LINECTRL_WLEN(v)                  (((v) & 0x3) << 5)
89 #define AUART_LINECTRL_FEN                      (1 << 4)
90 #define AUART_LINECTRL_STP2                     (1 << 3)
91 #define AUART_LINECTRL_EPS                      (1 << 2)
92 #define AUART_LINECTRL_PEN                      (1 << 1)
93 #define AUART_LINECTRL_BRK                      (1 << 0)
94
95 #define AUART_INTR_RTIEN                        (1 << 22)
96 #define AUART_INTR_TXIEN                        (1 << 21)
97 #define AUART_INTR_RXIEN                        (1 << 20)
98 #define AUART_INTR_CTSMIEN                      (1 << 17)
99 #define AUART_INTR_RTIS                         (1 << 6)
100 #define AUART_INTR_TXIS                         (1 << 5)
101 #define AUART_INTR_RXIS                         (1 << 4)
102 #define AUART_INTR_CTSMIS                       (1 << 1)
103
104 #define AUART_STAT_BUSY                         (1 << 29)
105 #define AUART_STAT_CTS                          (1 << 28)
106 #define AUART_STAT_TXFE                         (1 << 27)
107 #define AUART_STAT_TXFF                         (1 << 25)
108 #define AUART_STAT_RXFE                         (1 << 24)
109 #define AUART_STAT_OERR                         (1 << 19)
110 #define AUART_STAT_BERR                         (1 << 18)
111 #define AUART_STAT_PERR                         (1 << 17)
112 #define AUART_STAT_FERR                         (1 << 16)
113
114 static struct uart_driver auart_driver;
115
116 struct mxs_auart_port {
117         struct uart_port port;
118
119         unsigned int flags;
120         unsigned int ctrl;
121
122         unsigned int irq;
123
124         struct clk *clk;
125         struct device *dev;
126 };
127
128 static void mxs_auart_stop_tx(struct uart_port *u);
129
130 #define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
131
132 static inline void mxs_auart_tx_chars(struct mxs_auart_port *s)
133 {
134         struct circ_buf *xmit = &s->port.state->xmit;
135
136         while (!(readl(s->port.membase + AUART_STAT) &
137                  AUART_STAT_TXFF)) {
138                 if (s->port.x_char) {
139                         s->port.icount.tx++;
140                         writel(s->port.x_char,
141                                      s->port.membase + AUART_DATA);
142                         s->port.x_char = 0;
143                         continue;
144                 }
145                 if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
146                         s->port.icount.tx++;
147                         writel(xmit->buf[xmit->tail],
148                                      s->port.membase + AUART_DATA);
149                         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
150                 } else
151                         break;
152         }
153         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
154                 uart_write_wakeup(&s->port);
155
156         if (uart_circ_empty(&(s->port.state->xmit)))
157                 writel(AUART_INTR_TXIEN,
158                              s->port.membase + AUART_INTR_CLR);
159         else
160                 writel(AUART_INTR_TXIEN,
161                              s->port.membase + AUART_INTR_SET);
162
163         if (uart_tx_stopped(&s->port))
164                 mxs_auart_stop_tx(&s->port);
165 }
166
167 static void mxs_auart_rx_char(struct mxs_auart_port *s)
168 {
169         int flag;
170         u32 stat;
171         u8 c;
172
173         c = readl(s->port.membase + AUART_DATA);
174         stat = readl(s->port.membase + AUART_STAT);
175
176         flag = TTY_NORMAL;
177         s->port.icount.rx++;
178
179         if (stat & AUART_STAT_BERR) {
180                 s->port.icount.brk++;
181                 if (uart_handle_break(&s->port))
182                         goto out;
183         } else if (stat & AUART_STAT_PERR) {
184                 s->port.icount.parity++;
185         } else if (stat & AUART_STAT_FERR) {
186                 s->port.icount.frame++;
187         }
188
189         /*
190          * Mask off conditions which should be ingored.
191          */
192         stat &= s->port.read_status_mask;
193
194         if (stat & AUART_STAT_BERR) {
195                 flag = TTY_BREAK;
196         } else if (stat & AUART_STAT_PERR)
197                 flag = TTY_PARITY;
198         else if (stat & AUART_STAT_FERR)
199                 flag = TTY_FRAME;
200
201         if (stat & AUART_STAT_OERR)
202                 s->port.icount.overrun++;
203
204         if (uart_handle_sysrq_char(&s->port, c))
205                 goto out;
206
207         uart_insert_char(&s->port, stat, AUART_STAT_OERR, c, flag);
208 out:
209         writel(stat, s->port.membase + AUART_STAT);
210 }
211
212 static void mxs_auart_rx_chars(struct mxs_auart_port *s)
213 {
214         struct tty_struct *tty = s->port.state->port.tty;
215         u32 stat = 0;
216
217         for (;;) {
218                 stat = readl(s->port.membase + AUART_STAT);
219                 if (stat & AUART_STAT_RXFE)
220                         break;
221                 mxs_auart_rx_char(s);
222         }
223
224         writel(stat, s->port.membase + AUART_STAT);
225         tty_flip_buffer_push(tty);
226 }
227
228 static int mxs_auart_request_port(struct uart_port *u)
229 {
230         return 0;
231 }
232
233 static int mxs_auart_verify_port(struct uart_port *u,
234                                     struct serial_struct *ser)
235 {
236         if (u->type != PORT_UNKNOWN && u->type != PORT_IMX)
237                 return -EINVAL;
238         return 0;
239 }
240
241 static void mxs_auart_config_port(struct uart_port *u, int flags)
242 {
243 }
244
245 static const char *mxs_auart_type(struct uart_port *u)
246 {
247         struct mxs_auart_port *s = to_auart_port(u);
248
249         return dev_name(s->dev);
250 }
251
252 static void mxs_auart_release_port(struct uart_port *u)
253 {
254 }
255
256 static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)
257 {
258         struct mxs_auart_port *s = to_auart_port(u);
259
260         u32 ctrl = readl(u->membase + AUART_CTRL2);
261
262         ctrl &= ~AUART_CTRL2_RTS;
263         if (mctrl & TIOCM_RTS)
264                 ctrl |= AUART_CTRL2_RTS;
265         s->ctrl = mctrl;
266         writel(ctrl, u->membase + AUART_CTRL2);
267 }
268
269 static u32 mxs_auart_get_mctrl(struct uart_port *u)
270 {
271         struct mxs_auart_port *s = to_auart_port(u);
272         u32 stat = readl(u->membase + AUART_STAT);
273         int ctrl2 = readl(u->membase + AUART_CTRL2);
274         u32 mctrl = s->ctrl;
275
276         mctrl &= ~TIOCM_CTS;
277         if (stat & AUART_STAT_CTS)
278                 mctrl |= TIOCM_CTS;
279
280         if (ctrl2 & AUART_CTRL2_RTS)
281                 mctrl |= TIOCM_RTS;
282
283         return mctrl;
284 }
285
286 static void mxs_auart_settermios(struct uart_port *u,
287                                  struct ktermios *termios,
288                                  struct ktermios *old)
289 {
290         u32 bm, ctrl, ctrl2, div;
291         unsigned int cflag, baud;
292
293         cflag = termios->c_cflag;
294
295         ctrl = AUART_LINECTRL_FEN;
296         ctrl2 = readl(u->membase + AUART_CTRL2);
297
298         /* byte size */
299         switch (cflag & CSIZE) {
300         case CS5:
301                 bm = 0;
302                 break;
303         case CS6:
304                 bm = 1;
305                 break;
306         case CS7:
307                 bm = 2;
308                 break;
309         case CS8:
310                 bm = 3;
311                 break;
312         default:
313                 return;
314         }
315
316         ctrl |= AUART_LINECTRL_WLEN(bm);
317
318         /* parity */
319         if (cflag & PARENB) {
320                 ctrl |= AUART_LINECTRL_PEN;
321                 if ((cflag & PARODD) == 0)
322                         ctrl |= AUART_LINECTRL_EPS;
323         }
324
325         u->read_status_mask = 0;
326
327         if (termios->c_iflag & INPCK)
328                 u->read_status_mask |= AUART_STAT_PERR;
329         if (termios->c_iflag & (BRKINT | PARMRK))
330                 u->read_status_mask |= AUART_STAT_BERR;
331
332         /*
333          * Characters to ignore
334          */
335         u->ignore_status_mask = 0;
336         if (termios->c_iflag & IGNPAR)
337                 u->ignore_status_mask |= AUART_STAT_PERR;
338         if (termios->c_iflag & IGNBRK) {
339                 u->ignore_status_mask |= AUART_STAT_BERR;
340                 /*
341                  * If we're ignoring parity and break indicators,
342                  * ignore overruns too (for real raw support).
343                  */
344                 if (termios->c_iflag & IGNPAR)
345                         u->ignore_status_mask |= AUART_STAT_OERR;
346         }
347
348         /*
349          * ignore all characters if CREAD is not set
350          */
351         if (cflag & CREAD)
352                 ctrl2 |= AUART_CTRL2_RXE;
353         else
354                 ctrl2 &= ~AUART_CTRL2_RXE;
355
356         /* figure out the stop bits requested */
357         if (cflag & CSTOPB)
358                 ctrl |= AUART_LINECTRL_STP2;
359
360         /* figure out the hardware flow control settings */
361         if (cflag & CRTSCTS)
362                 ctrl2 |= AUART_CTRL2_CTSEN;
363         else
364                 ctrl2 &= ~AUART_CTRL2_CTSEN;
365
366         /* set baud rate */
367         baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
368         div = u->uartclk * 32 / baud;
369         ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);
370         ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6);
371
372         writel(ctrl, u->membase + AUART_LINECTRL);
373         writel(ctrl2, u->membase + AUART_CTRL2);
374
375         uart_update_timeout(u, termios->c_cflag, baud);
376 }
377
378 static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
379 {
380         u32 istatus, istat;
381         struct mxs_auart_port *s = context;
382         u32 stat = readl(s->port.membase + AUART_STAT);
383
384         istatus = istat = readl(s->port.membase + AUART_INTR);
385
386         if (istat & AUART_INTR_CTSMIS) {
387                 uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
388                 writel(AUART_INTR_CTSMIS,
389                                 s->port.membase + AUART_INTR_CLR);
390                 istat &= ~AUART_INTR_CTSMIS;
391         }
392
393         if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) {
394                 mxs_auart_rx_chars(s);
395                 istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS);
396         }
397
398         if (istat & AUART_INTR_TXIS) {
399                 mxs_auart_tx_chars(s);
400                 istat &= ~AUART_INTR_TXIS;
401         }
402
403         writel(istatus & (AUART_INTR_RTIS
404                 | AUART_INTR_TXIS
405                 | AUART_INTR_RXIS
406                 | AUART_INTR_CTSMIS),
407                         s->port.membase + AUART_INTR_CLR);
408
409         return IRQ_HANDLED;
410 }
411
412 static void mxs_auart_reset(struct uart_port *u)
413 {
414         int i;
415         unsigned int reg;
416
417         writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_CLR);
418
419         for (i = 0; i < 10000; i++) {
420                 reg = readl(u->membase + AUART_CTRL0);
421                 if (!(reg & AUART_CTRL0_SFTRST))
422                         break;
423                 udelay(3);
424         }
425         writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
426 }
427
428 static int mxs_auart_startup(struct uart_port *u)
429 {
430         struct mxs_auart_port *s = to_auart_port(u);
431
432         clk_prepare_enable(s->clk);
433
434         writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
435
436         writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET);
437
438         writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
439                         u->membase + AUART_INTR);
440
441         /*
442          * Enable fifo so all four bytes of a DMA word are written to
443          * output (otherwise, only the LSB is written, ie. 1 in 4 bytes)
444          */
445         writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET);
446
447         return 0;
448 }
449
450 static void mxs_auart_shutdown(struct uart_port *u)
451 {
452         struct mxs_auart_port *s = to_auart_port(u);
453
454         writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
455
456         writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET);
457
458         writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
459                         u->membase + AUART_INTR_CLR);
460
461         clk_disable_unprepare(s->clk);
462 }
463
464 static unsigned int mxs_auart_tx_empty(struct uart_port *u)
465 {
466         if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE)
467                 return TIOCSER_TEMT;
468         else
469                 return 0;
470 }
471
472 static void mxs_auart_start_tx(struct uart_port *u)
473 {
474         struct mxs_auart_port *s = to_auart_port(u);
475
476         /* enable transmitter */
477         writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_SET);
478
479         mxs_auart_tx_chars(s);
480 }
481
482 static void mxs_auart_stop_tx(struct uart_port *u)
483 {
484         writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_CLR);
485 }
486
487 static void mxs_auart_stop_rx(struct uart_port *u)
488 {
489         writel(AUART_CTRL2_RXE, u->membase + AUART_CTRL2_CLR);
490 }
491
492 static void mxs_auart_break_ctl(struct uart_port *u, int ctl)
493 {
494         if (ctl)
495                 writel(AUART_LINECTRL_BRK,
496                              u->membase + AUART_LINECTRL_SET);
497         else
498                 writel(AUART_LINECTRL_BRK,
499                              u->membase + AUART_LINECTRL_CLR);
500 }
501
502 static void mxs_auart_enable_ms(struct uart_port *port)
503 {
504         /* just empty */
505 }
506
507 static struct uart_ops mxs_auart_ops = {
508         .tx_empty       = mxs_auart_tx_empty,
509         .start_tx       = mxs_auart_start_tx,
510         .stop_tx        = mxs_auart_stop_tx,
511         .stop_rx        = mxs_auart_stop_rx,
512         .enable_ms      = mxs_auart_enable_ms,
513         .break_ctl      = mxs_auart_break_ctl,
514         .set_mctrl      = mxs_auart_set_mctrl,
515         .get_mctrl      = mxs_auart_get_mctrl,
516         .startup        = mxs_auart_startup,
517         .shutdown       = mxs_auart_shutdown,
518         .set_termios    = mxs_auart_settermios,
519         .type           = mxs_auart_type,
520         .release_port   = mxs_auart_release_port,
521         .request_port   = mxs_auart_request_port,
522         .config_port    = mxs_auart_config_port,
523         .verify_port    = mxs_auart_verify_port,
524 };
525
526 static struct mxs_auart_port *auart_port[MXS_AUART_PORTS];
527
528 #ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE
529 static void mxs_auart_console_putchar(struct uart_port *port, int ch)
530 {
531         unsigned int to = 1000;
532
533         while (readl(port->membase + AUART_STAT) & AUART_STAT_TXFF) {
534                 if (!to--)
535                         break;
536                 udelay(1);
537         }
538
539         writel(ch, port->membase + AUART_DATA);
540 }
541
542 static void
543 auart_console_write(struct console *co, const char *str, unsigned int count)
544 {
545         struct mxs_auart_port *s;
546         struct uart_port *port;
547         unsigned int old_ctrl0, old_ctrl2;
548         unsigned int to = 1000;
549
550         if (co->index > MXS_AUART_PORTS || co->index < 0)
551                 return;
552
553         s = auart_port[co->index];
554         port = &s->port;
555
556         clk_enable(s->clk);
557
558         /* First save the CR then disable the interrupts */
559         old_ctrl2 = readl(port->membase + AUART_CTRL2);
560         old_ctrl0 = readl(port->membase + AUART_CTRL0);
561
562         writel(AUART_CTRL0_CLKGATE,
563                      port->membase + AUART_CTRL0_CLR);
564         writel(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE,
565                      port->membase + AUART_CTRL2_SET);
566
567         uart_console_write(port, str, count, mxs_auart_console_putchar);
568
569         /*
570          * Finally, wait for transmitter to become empty
571          * and restore the TCR
572          */
573         while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
574                 if (!to--)
575                         break;
576                 udelay(1);
577         }
578
579         writel(old_ctrl0, port->membase + AUART_CTRL0);
580         writel(old_ctrl2, port->membase + AUART_CTRL2);
581
582         clk_disable(s->clk);
583 }
584
585 static void __init
586 auart_console_get_options(struct uart_port *port, int *baud,
587                           int *parity, int *bits)
588 {
589         unsigned int lcr_h, quot;
590
591         if (!(readl(port->membase + AUART_CTRL2) & AUART_CTRL2_UARTEN))
592                 return;
593
594         lcr_h = readl(port->membase + AUART_LINECTRL);
595
596         *parity = 'n';
597         if (lcr_h & AUART_LINECTRL_PEN) {
598                 if (lcr_h & AUART_LINECTRL_EPS)
599                         *parity = 'e';
600                 else
601                         *parity = 'o';
602         }
603
604         if ((lcr_h & AUART_LINECTRL_WLEN_MASK) == AUART_LINECTRL_WLEN(2))
605                 *bits = 7;
606         else
607                 *bits = 8;
608
609         quot = ((readl(port->membase + AUART_LINECTRL)
610                         & AUART_LINECTRL_BAUD_DIVINT_MASK))
611                             >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6);
612         quot |= ((readl(port->membase + AUART_LINECTRL)
613                         & AUART_LINECTRL_BAUD_DIVFRAC_MASK))
614                                 >> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT;
615         if (quot == 0)
616                 quot = 1;
617
618         *baud = (port->uartclk << 2) / quot;
619 }
620
621 static int __init
622 auart_console_setup(struct console *co, char *options)
623 {
624         struct mxs_auart_port *s;
625         int baud = 9600;
626         int bits = 8;
627         int parity = 'n';
628         int flow = 'n';
629         int ret;
630
631         /*
632          * Check whether an invalid uart number has been specified, and
633          * if so, search for the first available port that does have
634          * console support.
635          */
636         if (co->index == -1 || co->index >= ARRAY_SIZE(auart_port))
637                 co->index = 0;
638         s = auart_port[co->index];
639         if (!s)
640                 return -ENODEV;
641
642         clk_prepare_enable(s->clk);
643
644         if (options)
645                 uart_parse_options(options, &baud, &parity, &bits, &flow);
646         else
647                 auart_console_get_options(&s->port, &baud, &parity, &bits);
648
649         ret = uart_set_options(&s->port, co, baud, parity, bits, flow);
650
651         clk_disable_unprepare(s->clk);
652
653         return ret;
654 }
655
656 static struct console auart_console = {
657         .name           = "ttyAPP",
658         .write          = auart_console_write,
659         .device         = uart_console_device,
660         .setup          = auart_console_setup,
661         .flags          = CON_PRINTBUFFER,
662         .index          = -1,
663         .data           = &auart_driver,
664 };
665 #endif
666
667 static struct uart_driver auart_driver = {
668         .owner          = THIS_MODULE,
669         .driver_name    = "ttyAPP",
670         .dev_name       = "ttyAPP",
671         .major          = 0,
672         .minor          = 0,
673         .nr             = MXS_AUART_PORTS,
674 #ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE
675         .cons =         &auart_console,
676 #endif
677 };
678
679 /*
680  * This function returns 1 if pdev isn't a device instatiated by dt, 0 if it
681  * could successfully get all information from dt or a negative errno.
682  */
683 static int serial_mxs_probe_dt(struct mxs_auart_port *s,
684                 struct platform_device *pdev)
685 {
686         struct device_node *np = pdev->dev.of_node;
687         int ret;
688
689         if (!np)
690                 /* no device tree device */
691                 return 1;
692
693         ret = of_alias_get_id(np, "serial");
694         if (ret < 0) {
695                 dev_err(&pdev->dev, "failed to get alias id: %d\n", ret);
696                 return ret;
697         }
698         s->port.line = ret;
699
700         return 0;
701 }
702
703 static int __devinit mxs_auart_probe(struct platform_device *pdev)
704 {
705         struct mxs_auart_port *s;
706         u32 version;
707         int ret = 0;
708         struct resource *r;
709         struct pinctrl *pinctrl;
710
711         s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL);
712         if (!s) {
713                 ret = -ENOMEM;
714                 goto out;
715         }
716
717         ret = serial_mxs_probe_dt(s, pdev);
718         if (ret > 0)
719                 s->port.line = pdev->id < 0 ? 0 : pdev->id;
720         else if (ret < 0)
721                 goto out_free;
722
723         pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
724         if (IS_ERR(pinctrl)) {
725                 ret = PTR_ERR(pinctrl);
726                 goto out_free;
727         }
728
729         s->clk = clk_get(&pdev->dev, NULL);
730         if (IS_ERR(s->clk)) {
731                 ret = PTR_ERR(s->clk);
732                 goto out_free;
733         }
734
735         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
736         if (!r) {
737                 ret = -ENXIO;
738                 goto out_free_clk;
739         }
740
741         s->port.mapbase = r->start;
742         s->port.membase = ioremap(r->start, resource_size(r));
743         s->port.ops = &mxs_auart_ops;
744         s->port.iotype = UPIO_MEM;
745         s->port.fifosize = 16;
746         s->port.uartclk = clk_get_rate(s->clk);
747         s->port.type = PORT_IMX;
748         s->port.dev = s->dev = get_device(&pdev->dev);
749
750         s->flags = 0;
751         s->ctrl = 0;
752
753         s->irq = platform_get_irq(pdev, 0);
754         s->port.irq = s->irq;
755         ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s);
756         if (ret)
757                 goto out_free_clk;
758
759         platform_set_drvdata(pdev, s);
760
761         auart_port[s->port.line] = s;
762
763         mxs_auart_reset(&s->port);
764
765         ret = uart_add_one_port(&auart_driver, &s->port);
766         if (ret)
767                 goto out_free_irq;
768
769         version = readl(s->port.membase + AUART_VERSION);
770         dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n",
771                (version >> 24) & 0xff,
772                (version >> 16) & 0xff, version & 0xffff);
773
774         return 0;
775
776 out_free_irq:
777         auart_port[pdev->id] = NULL;
778         free_irq(s->irq, s);
779 out_free_clk:
780         clk_put(s->clk);
781 out_free:
782         kfree(s);
783 out:
784         return ret;
785 }
786
787 static int __devexit mxs_auart_remove(struct platform_device *pdev)
788 {
789         struct mxs_auart_port *s = platform_get_drvdata(pdev);
790
791         uart_remove_one_port(&auart_driver, &s->port);
792
793         auart_port[pdev->id] = NULL;
794
795         clk_put(s->clk);
796         free_irq(s->irq, s);
797         kfree(s);
798
799         return 0;
800 }
801
802 static struct of_device_id mxs_auart_dt_ids[] = {
803         { .compatible = "fsl,imx23-auart", },
804         { /* sentinel */ }
805 };
806 MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
807
808 static struct platform_driver mxs_auart_driver = {
809         .probe = mxs_auart_probe,
810         .remove = __devexit_p(mxs_auart_remove),
811         .driver = {
812                 .name = "mxs-auart",
813                 .owner = THIS_MODULE,
814                 .of_match_table = mxs_auart_dt_ids,
815         },
816 };
817
818 static int __init mxs_auart_init(void)
819 {
820         int r;
821
822         r = uart_register_driver(&auart_driver);
823         if (r)
824                 goto out;
825
826         r = platform_driver_register(&mxs_auart_driver);
827         if (r)
828                 goto out_err;
829
830         return 0;
831 out_err:
832         uart_unregister_driver(&auart_driver);
833 out:
834         return r;
835 }
836
837 static void __exit mxs_auart_exit(void)
838 {
839         platform_driver_unregister(&mxs_auart_driver);
840         uart_unregister_driver(&auart_driver);
841 }
842
843 module_init(mxs_auart_init);
844 module_exit(mxs_auart_exit);
845 MODULE_LICENSE("GPL");
846 MODULE_DESCRIPTION("Freescale MXS application uart driver");
847 MODULE_ALIAS("platform:mxs-auart");