1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Freescale LINFlexD UART serial port driver
5 * Copyright 2012-2016 Freescale Semiconductor, Inc.
6 * Copyright 2017-2019 NXP
9 #include <linux/console.h>
11 #include <linux/irq.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/serial_core.h>
16 #include <linux/slab.h>
17 #include <linux/tty_flip.h>
18 #include <linux/delay.h>
20 /* All registers are 32-bit width */
22 #define LINCR1 0x0000 /* LIN control register */
23 #define LINIER 0x0004 /* LIN interrupt enable register */
24 #define LINSR 0x0008 /* LIN status register */
25 #define LINESR 0x000C /* LIN error status register */
26 #define UARTCR 0x0010 /* UART mode control register */
27 #define UARTSR 0x0014 /* UART mode status register */
28 #define LINTCSR 0x0018 /* LIN timeout control status register */
29 #define LINOCR 0x001C /* LIN output compare register */
30 #define LINTOCR 0x0020 /* LIN timeout control register */
31 #define LINFBRR 0x0024 /* LIN fractional baud rate register */
32 #define LINIBRR 0x0028 /* LIN integer baud rate register */
33 #define LINCFR 0x002C /* LIN checksum field register */
34 #define LINCR2 0x0030 /* LIN control register 2 */
35 #define BIDR 0x0034 /* Buffer identifier register */
36 #define BDRL 0x0038 /* Buffer data register least significant */
37 #define BDRM 0x003C /* Buffer data register most significant */
38 #define IFER 0x0040 /* Identifier filter enable register */
39 #define IFMI 0x0044 /* Identifier filter match index */
40 #define IFMR 0x0048 /* Identifier filter mode register */
41 #define GCR 0x004C /* Global control register */
42 #define UARTPTO 0x0050 /* UART preset timeout register */
43 #define UARTCTO 0x0054 /* UART current timeout register */
46 * Register field definitions
49 #define LINFLEXD_LINCR1_INIT BIT(0)
50 #define LINFLEXD_LINCR1_MME BIT(4)
51 #define LINFLEXD_LINCR1_BF BIT(7)
53 #define LINFLEXD_LINSR_LINS_INITMODE BIT(12)
54 #define LINFLEXD_LINSR_LINS_MASK (0xF << 12)
56 #define LINFLEXD_LINIER_SZIE BIT(15)
57 #define LINFLEXD_LINIER_OCIE BIT(14)
58 #define LINFLEXD_LINIER_BEIE BIT(13)
59 #define LINFLEXD_LINIER_CEIE BIT(12)
60 #define LINFLEXD_LINIER_HEIE BIT(11)
61 #define LINFLEXD_LINIER_FEIE BIT(8)
62 #define LINFLEXD_LINIER_BOIE BIT(7)
63 #define LINFLEXD_LINIER_LSIE BIT(6)
64 #define LINFLEXD_LINIER_WUIE BIT(5)
65 #define LINFLEXD_LINIER_DBFIE BIT(4)
66 #define LINFLEXD_LINIER_DBEIETOIE BIT(3)
67 #define LINFLEXD_LINIER_DRIE BIT(2)
68 #define LINFLEXD_LINIER_DTIE BIT(1)
69 #define LINFLEXD_LINIER_HRIE BIT(0)
71 #define LINFLEXD_UARTCR_OSR_MASK (0xF << 24)
72 #define LINFLEXD_UARTCR_OSR(uartcr) (((uartcr) \
73 & LINFLEXD_UARTCR_OSR_MASK) >> 24)
75 #define LINFLEXD_UARTCR_ROSE BIT(23)
77 #define LINFLEXD_UARTCR_RFBM BIT(9)
78 #define LINFLEXD_UARTCR_TFBM BIT(8)
79 #define LINFLEXD_UARTCR_WL1 BIT(7)
80 #define LINFLEXD_UARTCR_PC1 BIT(6)
82 #define LINFLEXD_UARTCR_RXEN BIT(5)
83 #define LINFLEXD_UARTCR_TXEN BIT(4)
84 #define LINFLEXD_UARTCR_PC0 BIT(3)
86 #define LINFLEXD_UARTCR_PCE BIT(2)
87 #define LINFLEXD_UARTCR_WL0 BIT(1)
88 #define LINFLEXD_UARTCR_UART BIT(0)
90 #define LINFLEXD_UARTSR_SZF BIT(15)
91 #define LINFLEXD_UARTSR_OCF BIT(14)
92 #define LINFLEXD_UARTSR_PE3 BIT(13)
93 #define LINFLEXD_UARTSR_PE2 BIT(12)
94 #define LINFLEXD_UARTSR_PE1 BIT(11)
95 #define LINFLEXD_UARTSR_PE0 BIT(10)
96 #define LINFLEXD_UARTSR_RMB BIT(9)
97 #define LINFLEXD_UARTSR_FEF BIT(8)
98 #define LINFLEXD_UARTSR_BOF BIT(7)
99 #define LINFLEXD_UARTSR_RPS BIT(6)
100 #define LINFLEXD_UARTSR_WUF BIT(5)
101 #define LINFLEXD_UARTSR_4 BIT(4)
103 #define LINFLEXD_UARTSR_TO BIT(3)
105 #define LINFLEXD_UARTSR_DRFRFE BIT(2)
106 #define LINFLEXD_UARTSR_DTFTFF BIT(1)
107 #define LINFLEXD_UARTSR_NF BIT(0)
108 #define LINFLEXD_UARTSR_PE (LINFLEXD_UARTSR_PE0 |\
109 LINFLEXD_UARTSR_PE1 |\
110 LINFLEXD_UARTSR_PE2 |\
113 #define LINFLEX_LDIV_MULTIPLIER (16)
115 #define DRIVER_NAME "fsl-linflexuart"
116 #define DEV_NAME "ttyLF"
119 #define EARLYCON_BUFFER_INITIAL_CAP 8
121 #define PREINIT_DELAY 2000 /* us */
123 static const struct of_device_id linflex_dt_ids
[] = {
125 .compatible
= "fsl,s32v234-linflexuart",
129 MODULE_DEVICE_TABLE(of
, linflex_dt_ids
);
131 #ifdef CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE
132 static struct uart_port
*earlycon_port
;
133 static bool linflex_earlycon_same_instance
;
134 static DEFINE_SPINLOCK(init_lock
);
135 static bool during_init
;
139 unsigned int len
, cap
;
143 static void linflex_stop_tx(struct uart_port
*port
)
147 ier
= readl(port
->membase
+ LINIER
);
148 ier
&= ~(LINFLEXD_LINIER_DTIE
);
149 writel(ier
, port
->membase
+ LINIER
);
152 static void linflex_stop_rx(struct uart_port
*port
)
156 ier
= readl(port
->membase
+ LINIER
);
157 writel(ier
& ~LINFLEXD_LINIER_DRIE
, port
->membase
+ LINIER
);
160 static void linflex_put_char(struct uart_port
*sport
, unsigned char c
)
162 unsigned long status
;
164 writeb(c
, sport
->membase
+ BDRL
);
166 /* Waiting for data transmission completed. */
167 while (((status
= readl(sport
->membase
+ UARTSR
)) &
168 LINFLEXD_UARTSR_DTFTFF
) !=
169 LINFLEXD_UARTSR_DTFTFF
)
172 writel(status
| LINFLEXD_UARTSR_DTFTFF
, sport
->membase
+ UARTSR
);
175 static inline void linflex_transmit_buffer(struct uart_port
*sport
)
177 struct tty_port
*tport
= &sport
->state
->port
;
180 while (uart_fifo_get(sport
, &c
)) {
181 linflex_put_char(sport
, c
);
185 if (kfifo_len(&tport
->xmit_fifo
) < WAKEUP_CHARS
)
186 uart_write_wakeup(sport
);
188 if (kfifo_is_empty(&tport
->xmit_fifo
))
189 linflex_stop_tx(sport
);
192 static void linflex_start_tx(struct uart_port
*port
)
196 linflex_transmit_buffer(port
);
197 ier
= readl(port
->membase
+ LINIER
);
198 writel(ier
| LINFLEXD_LINIER_DTIE
, port
->membase
+ LINIER
);
201 static irqreturn_t
linflex_txint(int irq
, void *dev_id
)
203 struct uart_port
*sport
= dev_id
;
204 struct tty_port
*tport
= &sport
->state
->port
;
207 uart_port_lock_irqsave(sport
, &flags
);
210 linflex_put_char(sport
, sport
->x_char
);
214 if (kfifo_is_empty(&tport
->xmit_fifo
) || uart_tx_stopped(sport
)) {
215 linflex_stop_tx(sport
);
219 linflex_transmit_buffer(sport
);
221 uart_port_unlock_irqrestore(sport
, flags
);
225 static irqreturn_t
linflex_rxint(int irq
, void *dev_id
)
227 struct uart_port
*sport
= dev_id
;
229 struct tty_port
*port
= &sport
->state
->port
;
230 unsigned long flags
, status
;
234 uart_port_lock_irqsave(sport
, &flags
);
236 status
= readl(sport
->membase
+ UARTSR
);
237 while (status
& LINFLEXD_UARTSR_RMB
) {
238 rx
= readb(sport
->membase
+ BDRM
);
243 if (status
& (LINFLEXD_UARTSR_BOF
| LINFLEXD_UARTSR_FEF
|
244 LINFLEXD_UARTSR_PE
)) {
245 if (status
& LINFLEXD_UARTSR_BOF
)
246 sport
->icount
.overrun
++;
247 if (status
& LINFLEXD_UARTSR_FEF
) {
252 sport
->icount
.frame
++;
254 if (status
& LINFLEXD_UARTSR_PE
)
255 sport
->icount
.parity
++;
258 writel(status
, sport
->membase
+ UARTSR
);
259 status
= readl(sport
->membase
+ UARTSR
);
262 uart_handle_break(sport
);
264 if (uart_handle_sysrq_char(sport
, (unsigned char)rx
))
266 tty_insert_flip_char(port
, rx
, flg
);
270 uart_port_unlock_irqrestore(sport
, flags
);
272 tty_flip_buffer_push(port
);
277 static irqreturn_t
linflex_int(int irq
, void *dev_id
)
279 struct uart_port
*sport
= dev_id
;
280 unsigned long status
;
282 status
= readl(sport
->membase
+ UARTSR
);
284 if (status
& LINFLEXD_UARTSR_DRFRFE
)
285 linflex_rxint(irq
, dev_id
);
286 if (status
& LINFLEXD_UARTSR_DTFTFF
)
287 linflex_txint(irq
, dev_id
);
292 /* return TIOCSER_TEMT when transmitter is not busy */
293 static unsigned int linflex_tx_empty(struct uart_port
*port
)
295 unsigned long status
;
297 status
= readl(port
->membase
+ UARTSR
) & LINFLEXD_UARTSR_DTFTFF
;
299 return status
? TIOCSER_TEMT
: 0;
302 static unsigned int linflex_get_mctrl(struct uart_port
*port
)
307 static void linflex_set_mctrl(struct uart_port
*port
, unsigned int mctrl
)
311 static void linflex_break_ctl(struct uart_port
*port
, int break_state
)
315 static void linflex_setup_watermark(struct uart_port
*sport
)
317 unsigned long cr
, ier
, cr1
;
319 /* Disable transmission/reception */
320 ier
= readl(sport
->membase
+ LINIER
);
321 ier
&= ~(LINFLEXD_LINIER_DRIE
| LINFLEXD_LINIER_DTIE
);
322 writel(ier
, sport
->membase
+ LINIER
);
324 cr
= readl(sport
->membase
+ UARTCR
);
325 cr
&= ~(LINFLEXD_UARTCR_RXEN
| LINFLEXD_UARTCR_TXEN
);
326 writel(cr
, sport
->membase
+ UARTCR
);
328 /* Enter initialization mode by setting INIT bit */
330 /* set the Linflex in master mode and activate by-pass filter */
331 cr1
= LINFLEXD_LINCR1_BF
| LINFLEXD_LINCR1_MME
332 | LINFLEXD_LINCR1_INIT
;
333 writel(cr1
, sport
->membase
+ LINCR1
);
335 /* wait for init mode entry */
336 while ((readl(sport
->membase
+ LINSR
)
337 & LINFLEXD_LINSR_LINS_MASK
)
338 != LINFLEXD_LINSR_LINS_INITMODE
)
342 * UART = 0x1; - Linflex working in UART mode
343 * TXEN = 0x1; - Enable transmission of data now
344 * RXEn = 0x1; - Receiver enabled
345 * WL0 = 0x1; - 8 bit data
346 * PCE = 0x0; - No parity
349 /* set UART bit to allow writing other bits */
350 writel(LINFLEXD_UARTCR_UART
, sport
->membase
+ UARTCR
);
352 cr
= (LINFLEXD_UARTCR_RXEN
| LINFLEXD_UARTCR_TXEN
|
353 LINFLEXD_UARTCR_WL0
| LINFLEXD_UARTCR_UART
);
355 writel(cr
, sport
->membase
+ UARTCR
);
357 cr1
&= ~(LINFLEXD_LINCR1_INIT
);
359 writel(cr1
, sport
->membase
+ LINCR1
);
361 ier
= readl(sport
->membase
+ LINIER
);
362 ier
|= LINFLEXD_LINIER_DRIE
;
363 ier
|= LINFLEXD_LINIER_DTIE
;
365 writel(ier
, sport
->membase
+ LINIER
);
368 static int linflex_startup(struct uart_port
*port
)
373 uart_port_lock_irqsave(port
, &flags
);
375 linflex_setup_watermark(port
);
377 uart_port_unlock_irqrestore(port
, flags
);
379 ret
= devm_request_irq(port
->dev
, port
->irq
, linflex_int
, 0,
385 static void linflex_shutdown(struct uart_port
*port
)
390 uart_port_lock_irqsave(port
, &flags
);
392 /* disable interrupts */
393 ier
= readl(port
->membase
+ LINIER
);
394 ier
&= ~(LINFLEXD_LINIER_DRIE
| LINFLEXD_LINIER_DTIE
);
395 writel(ier
, port
->membase
+ LINIER
);
397 uart_port_unlock_irqrestore(port
, flags
);
399 devm_free_irq(port
->dev
, port
->irq
, port
);
403 linflex_set_termios(struct uart_port
*port
, struct ktermios
*termios
,
404 const struct ktermios
*old
)
407 unsigned long cr
, old_cr
, cr1
;
408 unsigned int old_csize
= old
? old
->c_cflag
& CSIZE
: CS8
;
410 cr
= readl(port
->membase
+ UARTCR
);
413 /* Enter initialization mode by setting INIT bit */
414 cr1
= readl(port
->membase
+ LINCR1
);
415 cr1
|= LINFLEXD_LINCR1_INIT
;
416 writel(cr1
, port
->membase
+ LINCR1
);
418 /* wait for init mode entry */
419 while ((readl(port
->membase
+ LINSR
)
420 & LINFLEXD_LINSR_LINS_MASK
)
421 != LINFLEXD_LINSR_LINS_INITMODE
)
425 * only support CS8 and CS7, and for CS7 must enable PE.
431 /* enter the UART into configuration mode */
433 while ((termios
->c_cflag
& CSIZE
) != CS8
&&
434 (termios
->c_cflag
& CSIZE
) != CS7
) {
435 termios
->c_cflag
&= ~CSIZE
;
436 termios
->c_cflag
|= old_csize
;
440 if ((termios
->c_cflag
& CSIZE
) == CS7
) {
441 /* Word length: WL1WL0:00 */
442 cr
= old_cr
& ~LINFLEXD_UARTCR_WL1
& ~LINFLEXD_UARTCR_WL0
;
445 if ((termios
->c_cflag
& CSIZE
) == CS8
) {
446 /* Word length: WL1WL0:01 */
447 cr
= (old_cr
| LINFLEXD_UARTCR_WL0
) & ~LINFLEXD_UARTCR_WL1
;
450 if (termios
->c_cflag
& CMSPAR
) {
451 if ((termios
->c_cflag
& CSIZE
) != CS8
) {
452 termios
->c_cflag
&= ~CSIZE
;
453 termios
->c_cflag
|= CS8
;
455 /* has a space/sticky bit */
456 cr
|= LINFLEXD_UARTCR_WL0
;
459 if (termios
->c_cflag
& CSTOPB
)
460 termios
->c_cflag
&= ~CSTOPB
;
462 /* parity must be enabled when CS7 to match 8-bits format */
463 if ((termios
->c_cflag
& CSIZE
) == CS7
)
464 termios
->c_cflag
|= PARENB
;
466 if ((termios
->c_cflag
& PARENB
)) {
467 cr
|= LINFLEXD_UARTCR_PCE
;
468 if (termios
->c_cflag
& PARODD
)
469 cr
= (cr
| LINFLEXD_UARTCR_PC0
) &
470 (~LINFLEXD_UARTCR_PC1
);
472 cr
= cr
& (~LINFLEXD_UARTCR_PC1
&
473 ~LINFLEXD_UARTCR_PC0
);
475 cr
&= ~LINFLEXD_UARTCR_PCE
;
478 uart_port_lock_irqsave(port
, &flags
);
480 port
->read_status_mask
= 0;
482 if (termios
->c_iflag
& INPCK
)
483 port
->read_status_mask
|= (LINFLEXD_UARTSR_FEF
|
484 LINFLEXD_UARTSR_PE0
|
485 LINFLEXD_UARTSR_PE1
|
486 LINFLEXD_UARTSR_PE2
|
487 LINFLEXD_UARTSR_PE3
);
488 if (termios
->c_iflag
& (IGNBRK
| BRKINT
| PARMRK
))
489 port
->read_status_mask
|= LINFLEXD_UARTSR_FEF
;
491 /* characters to ignore */
492 port
->ignore_status_mask
= 0;
493 if (termios
->c_iflag
& IGNPAR
)
494 port
->ignore_status_mask
|= LINFLEXD_UARTSR_PE
;
495 if (termios
->c_iflag
& IGNBRK
) {
496 port
->ignore_status_mask
|= LINFLEXD_UARTSR_PE
;
498 * if we're ignoring parity and break indicators,
499 * ignore overruns too (for real raw support).
501 if (termios
->c_iflag
& IGNPAR
)
502 port
->ignore_status_mask
|= LINFLEXD_UARTSR_BOF
;
505 writel(cr
, port
->membase
+ UARTCR
);
507 cr1
&= ~(LINFLEXD_LINCR1_INIT
);
509 writel(cr1
, port
->membase
+ LINCR1
);
511 uart_port_unlock_irqrestore(port
, flags
);
514 static const char *linflex_type(struct uart_port
*port
)
516 return "FSL_LINFLEX";
519 static void linflex_release_port(struct uart_port
*port
)
524 static int linflex_request_port(struct uart_port
*port
)
529 /* configure/auto-configure the port */
530 static void linflex_config_port(struct uart_port
*port
, int flags
)
532 if (flags
& UART_CONFIG_TYPE
)
533 port
->type
= PORT_LINFLEXUART
;
536 static const struct uart_ops linflex_pops
= {
537 .tx_empty
= linflex_tx_empty
,
538 .set_mctrl
= linflex_set_mctrl
,
539 .get_mctrl
= linflex_get_mctrl
,
540 .stop_tx
= linflex_stop_tx
,
541 .start_tx
= linflex_start_tx
,
542 .stop_rx
= linflex_stop_rx
,
543 .break_ctl
= linflex_break_ctl
,
544 .startup
= linflex_startup
,
545 .shutdown
= linflex_shutdown
,
546 .set_termios
= linflex_set_termios
,
547 .type
= linflex_type
,
548 .request_port
= linflex_request_port
,
549 .release_port
= linflex_release_port
,
550 .config_port
= linflex_config_port
,
553 static struct uart_port
*linflex_ports
[UART_NR
];
555 #ifdef CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE
556 static void linflex_console_putchar(struct uart_port
*port
, unsigned char ch
)
560 cr
= readl(port
->membase
+ UARTCR
);
562 writeb(ch
, port
->membase
+ BDRL
);
564 if (!(cr
& LINFLEXD_UARTCR_TFBM
))
565 while ((readl(port
->membase
+ UARTSR
) &
566 LINFLEXD_UARTSR_DTFTFF
)
567 != LINFLEXD_UARTSR_DTFTFF
)
570 while (readl(port
->membase
+ UARTSR
) &
571 LINFLEXD_UARTSR_DTFTFF
)
574 if (!(cr
& LINFLEXD_UARTCR_TFBM
)) {
575 writel((readl(port
->membase
+ UARTSR
) |
576 LINFLEXD_UARTSR_DTFTFF
),
577 port
->membase
+ UARTSR
);
581 static void linflex_earlycon_putchar(struct uart_port
*port
, unsigned char ch
)
586 if (!linflex_earlycon_same_instance
) {
587 linflex_console_putchar(port
, ch
);
591 spin_lock_irqsave(&init_lock
, flags
);
595 if (earlycon_buf
.len
>= 1 << CONFIG_LOG_BUF_SHIFT
)
598 if (!earlycon_buf
.cap
) {
599 earlycon_buf
.content
= kmalloc(EARLYCON_BUFFER_INITIAL_CAP
,
601 earlycon_buf
.cap
= earlycon_buf
.content
?
602 EARLYCON_BUFFER_INITIAL_CAP
: 0;
603 } else if (earlycon_buf
.len
== earlycon_buf
.cap
) {
604 ret
= krealloc(earlycon_buf
.content
, earlycon_buf
.cap
<< 1,
607 earlycon_buf
.content
= ret
;
608 earlycon_buf
.cap
<<= 1;
612 if (earlycon_buf
.len
< earlycon_buf
.cap
)
613 earlycon_buf
.content
[earlycon_buf
.len
++] = ch
;
618 linflex_console_putchar(port
, ch
);
620 spin_unlock_irqrestore(&init_lock
, flags
);
623 static void linflex_string_write(struct uart_port
*sport
, const char *s
,
626 unsigned long cr
, ier
= 0;
628 ier
= readl(sport
->membase
+ LINIER
);
629 linflex_stop_tx(sport
);
631 cr
= readl(sport
->membase
+ UARTCR
);
632 cr
|= (LINFLEXD_UARTCR_TXEN
);
633 writel(cr
, sport
->membase
+ UARTCR
);
635 uart_console_write(sport
, s
, count
, linflex_console_putchar
);
637 writel(ier
, sport
->membase
+ LINIER
);
641 linflex_console_write(struct console
*co
, const char *s
, unsigned int count
)
643 struct uart_port
*sport
= linflex_ports
[co
->index
];
649 else if (oops_in_progress
)
650 locked
= uart_port_trylock_irqsave(sport
, &flags
);
652 uart_port_lock_irqsave(sport
, &flags
);
654 linflex_string_write(sport
, s
, count
);
657 uart_port_unlock_irqrestore(sport
, flags
);
661 * if the port was already initialised (eg, by a boot loader),
662 * try to determine the current setup.
665 linflex_console_get_options(struct uart_port
*sport
, int *parity
, int *bits
)
669 cr
= readl(sport
->membase
+ UARTCR
);
670 cr
&= LINFLEXD_UARTCR_RXEN
| LINFLEXD_UARTCR_TXEN
;
675 /* ok, the port was enabled */
678 if (cr
& LINFLEXD_UARTCR_PCE
) {
679 if (cr
& LINFLEXD_UARTCR_PC0
)
685 if ((cr
& LINFLEXD_UARTCR_WL0
) && ((cr
& LINFLEXD_UARTCR_WL1
) == 0)) {
686 if (cr
& LINFLEXD_UARTCR_PCE
)
693 static int __init
linflex_console_setup(struct console
*co
, char *options
)
695 struct uart_port
*sport
;
704 * check whether an invalid uart number has been specified, and
705 * if so, search for the first available port that does have
708 if (co
->index
== -1 || co
->index
>= ARRAY_SIZE(linflex_ports
))
711 sport
= linflex_ports
[co
->index
];
716 uart_parse_options(options
, &baud
, &parity
, &bits
, &flow
);
718 linflex_console_get_options(sport
, &parity
, &bits
);
720 if (earlycon_port
&& sport
->mapbase
== earlycon_port
->mapbase
) {
721 linflex_earlycon_same_instance
= true;
723 spin_lock_irqsave(&init_lock
, flags
);
725 spin_unlock_irqrestore(&init_lock
, flags
);
727 /* Workaround for character loss or output of many invalid
728 * characters, when INIT mode is entered shortly after a
729 * character has just been printed.
731 udelay(PREINIT_DELAY
);
734 linflex_setup_watermark(sport
);
736 ret
= uart_set_options(sport
, co
, baud
, parity
, bits
, flow
);
738 if (!linflex_earlycon_same_instance
)
741 spin_lock_irqsave(&init_lock
, flags
);
743 /* Emptying buffer */
744 if (earlycon_buf
.len
) {
745 for (i
= 0; i
< earlycon_buf
.len
; i
++)
746 linflex_console_putchar(earlycon_port
,
747 earlycon_buf
.content
[i
]);
749 kfree(earlycon_buf
.content
);
750 earlycon_buf
.len
= 0;
754 spin_unlock_irqrestore(&init_lock
, flags
);
760 static struct uart_driver linflex_reg
;
761 static struct console linflex_console
= {
763 .write
= linflex_console_write
,
764 .device
= uart_console_device
,
765 .setup
= linflex_console_setup
,
766 .flags
= CON_PRINTBUFFER
,
768 .data
= &linflex_reg
,
771 static void linflex_earlycon_write(struct console
*con
, const char *s
,
774 struct earlycon_device
*dev
= con
->data
;
776 uart_console_write(&dev
->port
, s
, n
, linflex_earlycon_putchar
);
779 static int __init
linflex_early_console_setup(struct earlycon_device
*device
,
782 if (!device
->port
.membase
)
785 device
->con
->write
= linflex_earlycon_write
;
786 earlycon_port
= &device
->port
;
791 OF_EARLYCON_DECLARE(linflex
, "fsl,s32v234-linflexuart",
792 linflex_early_console_setup
);
794 #define LINFLEX_CONSOLE (&linflex_console)
796 #define LINFLEX_CONSOLE NULL
799 static struct uart_driver linflex_reg
= {
800 .owner
= THIS_MODULE
,
801 .driver_name
= DRIVER_NAME
,
802 .dev_name
= DEV_NAME
,
803 .nr
= ARRAY_SIZE(linflex_ports
),
804 .cons
= LINFLEX_CONSOLE
,
807 static int linflex_probe(struct platform_device
*pdev
)
809 struct device_node
*np
= pdev
->dev
.of_node
;
810 struct uart_port
*sport
;
811 struct resource
*res
;
814 sport
= devm_kzalloc(&pdev
->dev
, sizeof(*sport
), GFP_KERNEL
);
818 ret
= of_alias_get_id(np
, "serial");
820 dev_err(&pdev
->dev
, "failed to get alias id, errno %d\n", ret
);
823 if (ret
>= UART_NR
) {
824 dev_err(&pdev
->dev
, "driver limited to %d serial ports\n",
831 sport
->membase
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
832 if (IS_ERR(sport
->membase
))
833 return PTR_ERR(sport
->membase
);
834 sport
->mapbase
= res
->start
;
836 ret
= platform_get_irq(pdev
, 0);
840 sport
->dev
= &pdev
->dev
;
841 sport
->iotype
= UPIO_MEM
;
843 sport
->ops
= &linflex_pops
;
844 sport
->flags
= UPF_BOOT_AUTOCONF
;
845 sport
->has_sysrq
= IS_ENABLED(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE
);
847 linflex_ports
[sport
->line
] = sport
;
849 platform_set_drvdata(pdev
, sport
);
851 return uart_add_one_port(&linflex_reg
, sport
);
854 static void linflex_remove(struct platform_device
*pdev
)
856 struct uart_port
*sport
= platform_get_drvdata(pdev
);
858 uart_remove_one_port(&linflex_reg
, sport
);
861 #ifdef CONFIG_PM_SLEEP
862 static int linflex_suspend(struct device
*dev
)
864 struct uart_port
*sport
= dev_get_drvdata(dev
);
866 uart_suspend_port(&linflex_reg
, sport
);
871 static int linflex_resume(struct device
*dev
)
873 struct uart_port
*sport
= dev_get_drvdata(dev
);
875 uart_resume_port(&linflex_reg
, sport
);
881 static SIMPLE_DEV_PM_OPS(linflex_pm_ops
, linflex_suspend
, linflex_resume
);
883 static struct platform_driver linflex_driver
= {
884 .probe
= linflex_probe
,
885 .remove
= linflex_remove
,
888 .of_match_table
= linflex_dt_ids
,
889 .pm
= &linflex_pm_ops
,
893 static int __init
linflex_serial_init(void)
897 ret
= uart_register_driver(&linflex_reg
);
901 ret
= platform_driver_register(&linflex_driver
);
903 uart_unregister_driver(&linflex_reg
);
908 static void __exit
linflex_serial_exit(void)
910 platform_driver_unregister(&linflex_driver
);
911 uart_unregister_driver(&linflex_reg
);
914 module_init(linflex_serial_init
);
915 module_exit(linflex_serial_exit
);
917 MODULE_DESCRIPTION("Freescale LINFlexD serial port driver");
918 MODULE_LICENSE("GPL v2");