aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorJingchang Lu <b35083@freescale.com>2013-06-06 21:20:40 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-09 01:30:44 -0400
commitc9e2e946fb0ba5d2398feb89558f98c5c28e23e3 (patch)
treec2cebc2606be1bd35623147381de3dbab3a11802 /drivers/tty/serial
parent1ba7055af26f008e8fc8dab9dcb1701534afbe16 (diff)
tty: serial: add Freescale lpuart driver support
Add Freescale lpuart driver support. The lpuart device can be found on Vybrid VF610 and Layerscape LS-1 SoCs. Signed-off-by: Jingchang Lu <b35083@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/Kconfig14
-rw-r--r--drivers/tty/serial/Makefile1
-rw-r--r--drivers/tty/serial/fsl_lpuart.c874
3 files changed, 889 insertions, 0 deletions
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 95e66acca165..46dd1c72feda 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1483,6 +1483,20 @@ config SERIAL_RP2_NR_UARTS
1483 If multiple cards are present, the default limit of 32 ports may 1483 If multiple cards are present, the default limit of 32 ports may
1484 need to be increased. 1484 need to be increased.
1485 1485
1486config SERIAL_FSL_LPUART
1487 tristate "Freescale lpuart serial port support"
1488 select SERIAL_CORE
1489 help
1490 Support for the on-chip lpuart on some Freescale SOCs.
1491
1492config SERIAL_FSL_LPUART_CONSOLE
1493 bool "Console on Freescale lpuart serial port"
1494 depends on SERIAL_FSL_LPUART=y
1495 select SERIAL_CORE_CONSOLE
1496 help
1497 If you have enabled the lpuart serial port on the Freescale SoCs,
1498 you can make it the console by answering Y to this option.
1499
1486endmenu 1500endmenu
1487 1501
1488endif # TTY 1502endif # TTY
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index eedfec40e3dd..cf650f0cd6e4 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -85,3 +85,4 @@ obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o
85obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o 85obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o
86obj-$(CONFIG_SERIAL_ARC) += arc_uart.o 86obj-$(CONFIG_SERIAL_ARC) += arc_uart.o
87obj-$(CONFIG_SERIAL_RP2) += rp2.o 87obj-$(CONFIG_SERIAL_RP2) += rp2.o
88obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
new file mode 100644
index 000000000000..263cfaabe9e2
--- /dev/null
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -0,0 +1,874 @@
1/*
2 * Freescale lpuart serial port driver
3 *
4 * Copyright 2012-2013 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#if defined(CONFIG_SERIAL_FSL_LPUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
13#define SUPPORT_SYSRQ
14#endif
15
16#include <linux/module.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/clk.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22#include <linux/console.h>
23#include <linux/serial_core.h>
24#include <linux/tty_flip.h>
25
26/* All registers are 8-bit width */
27#define UARTBDH 0x00
28#define UARTBDL 0x01
29#define UARTCR1 0x02
30#define UARTCR2 0x03
31#define UARTSR1 0x04
32#define UARTCR3 0x06
33#define UARTDR 0x07
34#define UARTCR4 0x0a
35#define UARTCR5 0x0b
36#define UARTMODEM 0x0d
37#define UARTPFIFO 0x10
38#define UARTCFIFO 0x11
39#define UARTSFIFO 0x12
40#define UARTTWFIFO 0x13
41#define UARTTCFIFO 0x14
42#define UARTRWFIFO 0x15
43
44#define UARTBDH_LBKDIE 0x80
45#define UARTBDH_RXEDGIE 0x40
46#define UARTBDH_SBR_MASK 0x1f
47
48#define UARTCR1_LOOPS 0x80
49#define UARTCR1_RSRC 0x20
50#define UARTCR1_M 0x10
51#define UARTCR1_WAKE 0x08
52#define UARTCR1_ILT 0x04
53#define UARTCR1_PE 0x02
54#define UARTCR1_PT 0x01
55
56#define UARTCR2_TIE 0x80
57#define UARTCR2_TCIE 0x40
58#define UARTCR2_RIE 0x20
59#define UARTCR2_ILIE 0x10
60#define UARTCR2_TE 0x08
61#define UARTCR2_RE 0x04
62#define UARTCR2_RWU 0x02
63#define UARTCR2_SBK 0x01
64
65#define UARTSR1_TDRE 0x80
66#define UARTSR1_TC 0x40
67#define UARTSR1_RDRF 0x20
68#define UARTSR1_IDLE 0x10
69#define UARTSR1_OR 0x08
70#define UARTSR1_NF 0x04
71#define UARTSR1_FE 0x02
72#define UARTSR1_PE 0x01
73
74#define UARTCR3_R8 0x80
75#define UARTCR3_T8 0x40
76#define UARTCR3_TXDIR 0x20
77#define UARTCR3_TXINV 0x10
78#define UARTCR3_ORIE 0x08
79#define UARTCR3_NEIE 0x04
80#define UARTCR3_FEIE 0x02
81#define UARTCR3_PEIE 0x01
82
83#define UARTCR4_MAEN1 0x80
84#define UARTCR4_MAEN2 0x40
85#define UARTCR4_M10 0x20
86#define UARTCR4_BRFA_MASK 0x1f
87#define UARTCR4_BRFA_OFF 0
88
89#define UARTCR5_TDMAS 0x80
90#define UARTCR5_RDMAS 0x20
91
92#define UARTMODEM_RXRTSE 0x08
93#define UARTMODEM_TXRTSPOL 0x04
94#define UARTMODEM_TXRTSE 0x02
95#define UARTMODEM_TXCTSE 0x01
96
97#define UARTPFIFO_TXFE 0x80
98#define UARTPFIFO_FIFOSIZE_MASK 0x7
99#define UARTPFIFO_TXSIZE_OFF 4
100#define UARTPFIFO_RXFE 0x08
101#define UARTPFIFO_RXSIZE_OFF 0
102
103#define UARTCFIFO_TXFLUSH 0x80
104#define UARTCFIFO_RXFLUSH 0x40
105#define UARTCFIFO_RXOFE 0x04
106#define UARTCFIFO_TXOFE 0x02
107#define UARTCFIFO_RXUFE 0x01
108
109#define UARTSFIFO_TXEMPT 0x80
110#define UARTSFIFO_RXEMPT 0x40
111#define UARTSFIFO_RXOF 0x04
112#define UARTSFIFO_TXOF 0x02
113#define UARTSFIFO_RXUF 0x01
114
115#define DRIVER_NAME "fsl-lpuart"
116#define DEV_NAME "ttyLP"
117#define UART_NR 6
118
119struct lpuart_port {
120 struct uart_port port;
121 struct clk *clk;
122 unsigned int txfifo_size;
123 unsigned int rxfifo_size;
124};
125
126static struct of_device_id lpuart_dt_ids[] = {
127 {
128 .compatible = "fsl,vf610-lpuart",
129 },
130 { /* sentinel */ }
131};
132MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
133
134static void lpuart_stop_tx(struct uart_port *port)
135{
136 unsigned char temp;
137
138 temp = readb(port->membase + UARTCR2);
139 temp &= ~(UARTCR2_TIE | UARTCR2_TCIE);
140 writeb(temp, port->membase + UARTCR2);
141}
142
143static void lpuart_stop_rx(struct uart_port *port)
144{
145 unsigned char temp;
146
147 temp = readb(port->membase + UARTCR2);
148 writeb(temp & ~UARTCR2_RE, port->membase + UARTCR2);
149}
150
151static void lpuart_enable_ms(struct uart_port *port)
152{
153}
154
155static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
156{
157 struct circ_buf *xmit = &sport->port.state->xmit;
158
159 while (!uart_circ_empty(xmit) &&
160 (readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size)) {
161 writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR);
162 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
163 sport->port.icount.tx++;
164 }
165
166 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
167 uart_write_wakeup(&sport->port);
168
169 if (uart_circ_empty(xmit))
170 lpuart_stop_tx(&sport->port);
171}
172
173static void lpuart_start_tx(struct uart_port *port)
174{
175 struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
176 unsigned char temp;
177
178 temp = readb(port->membase + UARTCR2);
179 writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
180
181 if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
182 lpuart_transmit_buffer(sport);
183}
184
185static irqreturn_t lpuart_txint(int irq, void *dev_id)
186{
187 struct lpuart_port *sport = dev_id;
188 struct circ_buf *xmit = &sport->port.state->xmit;
189 unsigned long flags;
190
191 spin_lock_irqsave(&sport->port.lock, flags);
192 if (sport->port.x_char) {
193 writeb(sport->port.x_char, sport->port.membase + UARTDR);
194 goto out;
195 }
196
197 if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
198 lpuart_stop_tx(&sport->port);
199 goto out;
200 }
201
202 lpuart_transmit_buffer(sport);
203
204 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
205 uart_write_wakeup(&sport->port);
206
207out:
208 spin_unlock_irqrestore(&sport->port.lock, flags);
209 return IRQ_HANDLED;
210}
211
212static irqreturn_t lpuart_rxint(int irq, void *dev_id)
213{
214 struct lpuart_port *sport = dev_id;
215 unsigned int flg, ignored = 0;
216 struct tty_port *port = &sport->port.state->port;
217 unsigned long flags;
218 unsigned char rx, sr;
219
220 spin_lock_irqsave(&sport->port.lock, flags);
221
222 while (!(readb(sport->port.membase + UARTSFIFO) & UARTSFIFO_RXEMPT)) {
223 flg = TTY_NORMAL;
224 sport->port.icount.rx++;
225 /*
226 * to clear the FE, OR, NF, FE, PE flags,
227 * read SR1 then read DR
228 */
229 sr = readb(sport->port.membase + UARTSR1);
230 rx = readb(sport->port.membase + UARTDR);
231
232 if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
233 continue;
234
235 if (sr & (UARTSR1_PE | UARTSR1_OR | UARTSR1_FE)) {
236 if (sr & UARTSR1_PE)
237 sport->port.icount.parity++;
238 else if (sr & UARTSR1_FE)
239 sport->port.icount.frame++;
240
241 if (sr & UARTSR1_OR)
242 sport->port.icount.overrun++;
243
244 if (sr & sport->port.ignore_status_mask) {
245 if (++ignored > 100)
246 goto out;
247 continue;
248 }
249
250 sr &= sport->port.read_status_mask;
251
252 if (sr & UARTSR1_PE)
253 flg = TTY_PARITY;
254 else if (sr & UARTSR1_FE)
255 flg = TTY_FRAME;
256
257 if (sr & UARTSR1_OR)
258 flg = TTY_OVERRUN;
259
260#ifdef SUPPORT_SYSRQ
261 sport->port.sysrq = 0;
262#endif
263 }
264
265 tty_insert_flip_char(port, rx, flg);
266 }
267
268out:
269 spin_unlock_irqrestore(&sport->port.lock, flags);
270
271 tty_flip_buffer_push(port);
272 return IRQ_HANDLED;
273}
274
275static irqreturn_t lpuart_int(int irq, void *dev_id)
276{
277 struct lpuart_port *sport = dev_id;
278 unsigned char sts;
279
280 sts = readb(sport->port.membase + UARTSR1);
281
282 if (sts & UARTSR1_RDRF)
283 lpuart_rxint(irq, dev_id);
284
285 if (sts & UARTSR1_TDRE &&
286 !(readb(sport->port.membase + UARTCR5) & UARTCR5_TDMAS))
287 lpuart_txint(irq, dev_id);
288
289 return IRQ_HANDLED;
290}
291
292/* return TIOCSER_TEMT when transmitter is not busy */
293static unsigned int lpuart_tx_empty(struct uart_port *port)
294{
295 return (readb(port->membase + UARTSR1) & UARTSR1_TC) ?
296 TIOCSER_TEMT : 0;
297}
298
299static unsigned int lpuart_get_mctrl(struct uart_port *port)
300{
301 unsigned int temp = 0;
302 unsigned char reg;
303
304 reg = readb(port->membase + UARTMODEM);
305 if (reg & UARTMODEM_TXCTSE)
306 temp |= TIOCM_CTS;
307
308 if (reg & UARTMODEM_RXRTSE)
309 temp |= TIOCM_RTS;
310
311 return temp;
312}
313
314static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
315{
316 unsigned char temp;
317
318 temp = readb(port->membase + UARTMODEM) &
319 ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
320
321 if (mctrl & TIOCM_RTS)
322 temp |= UARTMODEM_RXRTSE;
323
324 if (mctrl & TIOCM_CTS)
325 temp |= UARTMODEM_TXCTSE;
326
327 writeb(temp, port->membase + UARTMODEM);
328}
329
330static void lpuart_break_ctl(struct uart_port *port, int break_state)
331{
332 unsigned char temp;
333
334 temp = readb(port->membase + UARTCR2) & ~UARTCR2_SBK;
335
336 if (break_state != 0)
337 temp |= UARTCR2_SBK;
338
339 writeb(temp, port->membase + UARTCR2);
340}
341
342static void lpuart_setup_watermark(struct lpuart_port *sport)
343{
344 unsigned char val, cr2;
345
346 cr2 = readb(sport->port.membase + UARTCR2);
347 cr2 &= ~(UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_TE |
348 UARTCR2_RIE | UARTCR2_RE);
349 writeb(cr2, sport->port.membase + UARTCR2);
350
351 /* determine FIFO size and enable FIFO mode */
352 val = readb(sport->port.membase + UARTPFIFO);
353
354 sport->txfifo_size = 0x1 << (((val >> UARTPFIFO_TXSIZE_OFF) &
355 UARTPFIFO_FIFOSIZE_MASK) + 1);
356
357 sport->rxfifo_size = 0x1 << (((val >> UARTPFIFO_RXSIZE_OFF) &
358 UARTPFIFO_FIFOSIZE_MASK) + 1);
359
360 writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE,
361 sport->port.membase + UARTPFIFO);
362
363 /* flush Tx and Rx FIFO */
364 writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH,
365 sport->port.membase + UARTCFIFO);
366
367 writeb(2, sport->port.membase + UARTTWFIFO);
368 writeb(1, sport->port.membase + UARTRWFIFO);
369}
370
371static int lpuart_startup(struct uart_port *port)
372{
373 struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
374 int ret;
375 unsigned long flags;
376 unsigned char temp;
377
378 ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0,
379 DRIVER_NAME, sport);
380 if (ret)
381 return ret;
382
383 spin_lock_irqsave(&sport->port.lock, flags);
384
385 lpuart_setup_watermark(sport);
386
387 temp = readb(sport->port.membase + UARTCR2);
388 temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE);
389 writeb(temp, sport->port.membase + UARTCR2);
390
391 spin_unlock_irqrestore(&sport->port.lock, flags);
392 return 0;
393}
394
395static void lpuart_shutdown(struct uart_port *port)
396{
397 struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
398 unsigned char temp;
399 unsigned long flags;
400
401 spin_lock_irqsave(&port->lock, flags);
402
403 /* disable Rx/Tx and interrupts */
404 temp = readb(port->membase + UARTCR2);
405 temp &= ~(UARTCR2_TE | UARTCR2_RE |
406 UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE);
407 writeb(temp, port->membase + UARTCR2);
408
409 spin_unlock_irqrestore(&port->lock, flags);
410
411 devm_free_irq(port->dev, port->irq, sport);
412}
413
414static void
415lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
416 struct ktermios *old)
417{
418 struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
419 unsigned long flags;
420 unsigned char cr1, old_cr1, old_cr2, cr4, bdh, modem;
421 unsigned int baud;
422 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
423 unsigned int sbr, brfa;
424
425 cr1 = old_cr1 = readb(sport->port.membase + UARTCR1);
426 old_cr2 = readb(sport->port.membase + UARTCR2);
427 cr4 = readb(sport->port.membase + UARTCR4);
428 bdh = readb(sport->port.membase + UARTBDH);
429 modem = readb(sport->port.membase + UARTMODEM);
430 /*
431 * only support CS8 and CS7, and for CS7 must enable PE.
432 * supported mode:
433 * - (7,e/o,1)
434 * - (8,n,1)
435 * - (8,m/s,1)
436 * - (8,e/o,1)
437 */
438 while ((termios->c_cflag & CSIZE) != CS8 &&
439 (termios->c_cflag & CSIZE) != CS7) {
440 termios->c_cflag &= ~CSIZE;
441 termios->c_cflag |= old_csize;
442 old_csize = CS8;
443 }
444
445 if ((termios->c_cflag & CSIZE) == CS8 ||
446 (termios->c_cflag & CSIZE) == CS7)
447 cr1 = old_cr1 & ~UARTCR1_M;
448
449 if (termios->c_cflag & CMSPAR) {
450 if ((termios->c_cflag & CSIZE) != CS8) {
451 termios->c_cflag &= ~CSIZE;
452 termios->c_cflag |= CS8;
453 }
454 cr1 |= UARTCR1_M;
455 }
456
457 if (termios->c_cflag & CRTSCTS) {
458 modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
459 } else {
460 termios->c_cflag &= ~CRTSCTS;
461 modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
462 }
463
464 if (termios->c_cflag & CSTOPB)
465 termios->c_cflag &= ~CSTOPB;
466
467 /* parity must be enabled when CS7 to match 8-bits format */
468 if ((termios->c_cflag & CSIZE) == CS7)
469 termios->c_cflag |= PARENB;
470
471 if ((termios->c_cflag & PARENB)) {
472 if (termios->c_cflag & CMSPAR) {
473 cr1 &= ~UARTCR1_PE;
474 cr1 |= UARTCR1_M;
475 } else {
476 cr1 |= UARTCR1_PE;
477 if ((termios->c_cflag & CSIZE) == CS8)
478 cr1 |= UARTCR1_M;
479 if (termios->c_cflag & PARODD)
480 cr1 |= UARTCR1_PT;
481 else
482 cr1 &= ~UARTCR1_PT;
483 }
484 }
485
486 /* ask the core to calculate the divisor */
487 baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
488
489 spin_lock_irqsave(&sport->port.lock, flags);
490
491 sport->port.read_status_mask = 0;
492 if (termios->c_iflag & INPCK)
493 sport->port.read_status_mask |= (UARTSR1_FE | UARTSR1_PE);
494 if (termios->c_iflag & (BRKINT | PARMRK))
495 sport->port.read_status_mask |= UARTSR1_FE;
496
497 /* characters to ignore */
498 sport->port.ignore_status_mask = 0;
499 if (termios->c_iflag & IGNPAR)
500 sport->port.ignore_status_mask |= UARTSR1_PE;
501 if (termios->c_iflag & IGNBRK) {
502 sport->port.ignore_status_mask |= UARTSR1_FE;
503 /*
504 * if we're ignoring parity and break indicators,
505 * ignore overruns too (for real raw support).
506 */
507 if (termios->c_iflag & IGNPAR)
508 sport->port.ignore_status_mask |= UARTSR1_OR;
509 }
510
511 /* update the per-port timeout */
512 uart_update_timeout(port, termios->c_cflag, baud);
513
514 /* wait transmit engin complete */
515 while (!(readb(sport->port.membase + UARTSR1) & UARTSR1_TC))
516 barrier();
517
518 /* disable transmit and receive */
519 writeb(old_cr2 & ~(UARTCR2_TE | UARTCR2_RE),
520 sport->port.membase + UARTCR2);
521
522 sbr = sport->port.uartclk / (16 * baud);
523 brfa = ((sport->port.uartclk - (16 * sbr * baud)) * 2) / baud;
524 bdh &= ~UARTBDH_SBR_MASK;
525 bdh |= (sbr >> 8) & 0x1F;
526 cr4 &= ~UARTCR4_BRFA_MASK;
527 brfa &= UARTCR4_BRFA_MASK;
528 writeb(cr4 | brfa, sport->port.membase + UARTCR4);
529 writeb(bdh, sport->port.membase + UARTBDH);
530 writeb(sbr & 0xFF, sport->port.membase + UARTBDL);
531 writeb(cr1, sport->port.membase + UARTCR1);
532 writeb(modem, sport->port.membase + UARTMODEM);
533
534 /* restore control register */
535 writeb(old_cr2, sport->port.membase + UARTCR2);
536
537 spin_unlock_irqrestore(&sport->port.lock, flags);
538}
539
540static const char *lpuart_type(struct uart_port *port)
541{
542 return "FSL_LPUART";
543}
544
545static void lpuart_release_port(struct uart_port *port)
546{
547 /* nothing to do */
548}
549
550static int lpuart_request_port(struct uart_port *port)
551{
552 return 0;
553}
554
555/* configure/autoconfigure the port */
556static void lpuart_config_port(struct uart_port *port, int flags)
557{
558 if (flags & UART_CONFIG_TYPE)
559 port->type = PORT_LPUART;
560}
561
562static int lpuart_verify_port(struct uart_port *port, struct serial_struct *ser)
563{
564 int ret = 0;
565
566 if (ser->type != PORT_UNKNOWN && ser->type != PORT_LPUART)
567 ret = -EINVAL;
568 if (port->irq != ser->irq)
569 ret = -EINVAL;
570 if (ser->io_type != UPIO_MEM)
571 ret = -EINVAL;
572 if (port->uartclk / 16 != ser->baud_base)
573 ret = -EINVAL;
574 if (port->iobase != ser->port)
575 ret = -EINVAL;
576 if (ser->hub6 != 0)
577 ret = -EINVAL;
578 return ret;
579}
580
581static struct uart_ops lpuart_pops = {
582 .tx_empty = lpuart_tx_empty,
583 .set_mctrl = lpuart_set_mctrl,
584 .get_mctrl = lpuart_get_mctrl,
585 .stop_tx = lpuart_stop_tx,
586 .start_tx = lpuart_start_tx,
587 .stop_rx = lpuart_stop_rx,
588 .enable_ms = lpuart_enable_ms,
589 .break_ctl = lpuart_break_ctl,
590 .startup = lpuart_startup,
591 .shutdown = lpuart_shutdown,
592 .set_termios = lpuart_set_termios,
593 .type = lpuart_type,
594 .request_port = lpuart_request_port,
595 .release_port = lpuart_release_port,
596 .config_port = lpuart_config_port,
597 .verify_port = lpuart_verify_port,
598};
599
600static struct lpuart_port *lpuart_ports[UART_NR];
601
602#ifdef CONFIG_SERIAL_FSL_LPUART_CONSOLE
603static void lpuart_console_putchar(struct uart_port *port, int ch)
604{
605 while (!(readb(port->membase + UARTSR1) & UARTSR1_TDRE))
606 barrier();
607
608 writeb(ch, port->membase + UARTDR);
609}
610
611static void
612lpuart_console_write(struct console *co, const char *s, unsigned int count)
613{
614 struct lpuart_port *sport = lpuart_ports[co->index];
615 unsigned char old_cr2, cr2;
616
617 /* first save CR2 and then disable interrupts */
618 cr2 = old_cr2 = readb(sport->port.membase + UARTCR2);
619 cr2 |= (UARTCR2_TE | UARTCR2_RE);
620 cr2 &= ~(UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE);
621 writeb(cr2, sport->port.membase + UARTCR2);
622
623 uart_console_write(&sport->port, s, count, lpuart_console_putchar);
624
625 /* wait for transmitter finish complete and restore CR2 */
626 while (!(readb(sport->port.membase + UARTSR1) & UARTSR1_TC))
627 barrier();
628
629 writeb(old_cr2, sport->port.membase + UARTCR2);
630}
631
632/*
633 * if the port was already initialised (eg, by a boot loader),
634 * try to determine the current setup.
635 */
636static void __init
637lpuart_console_get_options(struct lpuart_port *sport, int *baud,
638 int *parity, int *bits)
639{
640 unsigned char cr, bdh, bdl, brfa;
641 unsigned int sbr, uartclk, baud_raw;
642
643 cr = readb(sport->port.membase + UARTCR2);
644 cr &= UARTCR2_TE | UARTCR2_RE;
645 if (!cr)
646 return;
647
648 /* ok, the port was enabled */
649
650 cr = readb(sport->port.membase + UARTCR1);
651
652 *parity = 'n';
653 if (cr & UARTCR1_PE) {
654 if (cr & UARTCR1_PT)
655 *parity = 'o';
656 else
657 *parity = 'e';
658 }
659
660 if (cr & UARTCR1_M)
661 *bits = 9;
662 else
663 *bits = 8;
664
665 bdh = readb(sport->port.membase + UARTBDH);
666 bdh &= UARTBDH_SBR_MASK;
667 bdl = readb(sport->port.membase + UARTBDL);
668 sbr = bdh;
669 sbr <<= 8;
670 sbr |= bdl;
671 brfa = readb(sport->port.membase + UARTCR4);
672 brfa &= UARTCR4_BRFA_MASK;
673
674 uartclk = clk_get_rate(sport->clk);
675 /*
676 * baud = mod_clk/(16*(sbr[13]+(brfa)/32)
677 */
678 baud_raw = uartclk / (16 * (sbr + brfa / 32));
679
680 if (*baud != baud_raw)
681 printk(KERN_INFO "Serial: Console lpuart rounded baud rate"
682 "from %d to %d\n", baud_raw, *baud);
683}
684
685static int __init lpuart_console_setup(struct console *co, char *options)
686{
687 struct lpuart_port *sport;
688 int baud = 115200;
689 int bits = 8;
690 int parity = 'n';
691 int flow = 'n';
692
693 /*
694 * check whether an invalid uart number has been specified, and
695 * if so, search for the first available port that does have
696 * console support.
697 */
698 if (co->index == -1 || co->index >= ARRAY_SIZE(lpuart_ports))
699 co->index = 0;
700
701 sport = lpuart_ports[co->index];
702 if (sport == NULL)
703 return -ENODEV;
704
705 if (options)
706 uart_parse_options(options, &baud, &parity, &bits, &flow);
707 else
708 lpuart_console_get_options(sport, &baud, &parity, &bits);
709
710 lpuart_setup_watermark(sport);
711
712 return uart_set_options(&sport->port, co, baud, parity, bits, flow);
713}
714
715static struct uart_driver lpuart_reg;
716static struct console lpuart_console = {
717 .name = DEV_NAME,
718 .write = lpuart_console_write,
719 .device = uart_console_device,
720 .setup = lpuart_console_setup,
721 .flags = CON_PRINTBUFFER,
722 .index = -1,
723 .data = &lpuart_reg,
724};
725
726#define LPUART_CONSOLE (&lpuart_console)
727#else
728#define LPUART_CONSOLE NULL
729#endif
730
731static struct uart_driver lpuart_reg = {
732 .owner = THIS_MODULE,
733 .driver_name = DRIVER_NAME,
734 .dev_name = DEV_NAME,
735 .nr = ARRAY_SIZE(lpuart_ports),
736 .cons = LPUART_CONSOLE,
737};
738
739static int lpuart_probe(struct platform_device *pdev)
740{
741 struct device_node *np = pdev->dev.of_node;
742 struct lpuart_port *sport;
743 struct resource *res;
744 int ret;
745
746 sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
747 if (!sport)
748 return -ENOMEM;
749
750 pdev->dev.coherent_dma_mask = 0;
751
752 ret = of_alias_get_id(np, "serial");
753 if (ret < 0) {
754 dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
755 return ret;
756 }
757 sport->port.line = ret;
758
759 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
760 if (!res)
761 return -ENODEV;
762
763 sport->port.mapbase = res->start;
764 sport->port.membase = devm_ioremap_resource(&pdev->dev, res);
765 if (IS_ERR(sport->port.membase))
766 return PTR_ERR(sport->port.membase);
767
768 sport->port.dev = &pdev->dev;
769 sport->port.type = PORT_LPUART;
770 sport->port.iotype = UPIO_MEM;
771 sport->port.irq = platform_get_irq(pdev, 0);
772 sport->port.ops = &lpuart_pops;
773 sport->port.flags = UPF_BOOT_AUTOCONF;
774
775 sport->clk = devm_clk_get(&pdev->dev, "ipg");
776 if (IS_ERR(sport->clk)) {
777 ret = PTR_ERR(sport->clk);
778 dev_err(&pdev->dev, "failed to get uart clk: %d\n", ret);
779 return ret;
780 }
781
782 ret = clk_prepare_enable(sport->clk);
783 if (ret) {
784 dev_err(&pdev->dev, "failed to enable uart clk: %d\n", ret);
785 return ret;
786 }
787
788 sport->port.uartclk = clk_get_rate(sport->clk);
789
790 lpuart_ports[sport->port.line] = sport;
791
792 platform_set_drvdata(pdev, &sport->port);
793
794 ret = uart_add_one_port(&lpuart_reg, &sport->port);
795 if (ret) {
796 clk_disable_unprepare(sport->clk);
797 return ret;
798 }
799
800 return 0;
801}
802
803static int lpuart_remove(struct platform_device *pdev)
804{
805 struct lpuart_port *sport = platform_get_drvdata(pdev);
806
807 uart_remove_one_port(&lpuart_reg, &sport->port);
808
809 clk_disable_unprepare(sport->clk);
810
811 return 0;
812}
813
814#ifdef CONFIG_PM_SLEEP
815static int lpuart_suspend(struct device *dev)
816{
817 struct lpuart_port *sport = dev_get_drvdata(dev);
818
819 uart_suspend_port(&lpuart_reg, &sport->port);
820
821 return 0;
822}
823
824static int lpuart_resume(struct device *dev)
825{
826 struct lpuart_port *sport = dev_get_drvdata(dev);
827
828 uart_resume_port(&lpuart_reg, &sport->port);
829
830 return 0;
831}
832#endif
833
834static SIMPLE_DEV_PM_OPS(lpuart_pm_ops, lpuart_suspend, lpuart_resume);
835
836static struct platform_driver lpuart_driver = {
837 .probe = lpuart_probe,
838 .remove = lpuart_remove,
839 .driver = {
840 .name = "fsl-lpuart",
841 .owner = THIS_MODULE,
842 .of_match_table = lpuart_dt_ids,
843 .pm = &lpuart_pm_ops,
844 },
845};
846
847static int __init lpuart_serial_init(void)
848{
849 int ret;
850
851 pr_info("serial: Freescale lpuart driver\n");
852
853 ret = uart_register_driver(&lpuart_reg);
854 if (ret)
855 return ret;
856
857 ret = platform_driver_register(&lpuart_driver);
858 if (ret)
859 uart_unregister_driver(&lpuart_reg);
860
861 return 0;
862}
863
864static void __exit lpuart_serial_exit(void)
865{
866 platform_driver_unregister(&lpuart_driver);
867 uart_unregister_driver(&lpuart_reg);
868}
869
870module_init(lpuart_serial_init);
871module_exit(lpuart_serial_exit);
872
873MODULE_DESCRIPTION("Freescale lpuart serial port driver");
874MODULE_LICENSE("GPL v2");