diff options
author | Jingchang Lu <jingchang.lu@freescale.com> | 2014-07-14 05:41:11 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-17 21:15:38 -0400 |
commit | 380c966c093e7239e42a81f165b20b2bad2658bc (patch) | |
tree | 1887a9747d6c1732b443fd6767d6f11713b8f21a | |
parent | 876496b8cd01b02f7eb561c27aeaf908e4c3f86e (diff) |
tty: serial: fsl_lpuart: add 32-bit register interface support
This add the 32-bit register version LPUART support with big-endian
byte order.
Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/serial/fsl_lpuart.c | 645 |
1 files changed, 637 insertions, 8 deletions
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index acd3617677e8..6dd53af546a3 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Freescale lpuart serial port driver | 2 | * Freescale lpuart serial port driver |
3 | * | 3 | * |
4 | * Copyright 2012-2013 Freescale Semiconductor, Inc. | 4 | * Copyright 2012-2014 Freescale Semiconductor, Inc. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 | 7 | * it under the terms of the GNU General Public License as published by |
@@ -117,6 +117,113 @@ | |||
117 | #define UARTSFIFO_TXOF 0x02 | 117 | #define UARTSFIFO_TXOF 0x02 |
118 | #define UARTSFIFO_RXUF 0x01 | 118 | #define UARTSFIFO_RXUF 0x01 |
119 | 119 | ||
120 | /* 32-bit register defination */ | ||
121 | #define UARTBAUD 0x00 | ||
122 | #define UARTSTAT 0x04 | ||
123 | #define UARTCTRL 0x08 | ||
124 | #define UARTDATA 0x0C | ||
125 | #define UARTMATCH 0x10 | ||
126 | #define UARTMODIR 0x14 | ||
127 | #define UARTFIFO 0x18 | ||
128 | #define UARTWATER 0x1c | ||
129 | |||
130 | #define UARTBAUD_MAEN1 0x80000000 | ||
131 | #define UARTBAUD_MAEN2 0x40000000 | ||
132 | #define UARTBAUD_M10 0x20000000 | ||
133 | #define UARTBAUD_TDMAE 0x00800000 | ||
134 | #define UARTBAUD_RDMAE 0x00200000 | ||
135 | #define UARTBAUD_MATCFG 0x00400000 | ||
136 | #define UARTBAUD_BOTHEDGE 0x00020000 | ||
137 | #define UARTBAUD_RESYNCDIS 0x00010000 | ||
138 | #define UARTBAUD_LBKDIE 0x00008000 | ||
139 | #define UARTBAUD_RXEDGIE 0x00004000 | ||
140 | #define UARTBAUD_SBNS 0x00002000 | ||
141 | #define UARTBAUD_SBR 0x00000000 | ||
142 | #define UARTBAUD_SBR_MASK 0x1fff | ||
143 | |||
144 | #define UARTSTAT_LBKDIF 0x80000000 | ||
145 | #define UARTSTAT_RXEDGIF 0x40000000 | ||
146 | #define UARTSTAT_MSBF 0x20000000 | ||
147 | #define UARTSTAT_RXINV 0x10000000 | ||
148 | #define UARTSTAT_RWUID 0x08000000 | ||
149 | #define UARTSTAT_BRK13 0x04000000 | ||
150 | #define UARTSTAT_LBKDE 0x02000000 | ||
151 | #define UARTSTAT_RAF 0x01000000 | ||
152 | #define UARTSTAT_TDRE 0x00800000 | ||
153 | #define UARTSTAT_TC 0x00400000 | ||
154 | #define UARTSTAT_RDRF 0x00200000 | ||
155 | #define UARTSTAT_IDLE 0x00100000 | ||
156 | #define UARTSTAT_OR 0x00080000 | ||
157 | #define UARTSTAT_NF 0x00040000 | ||
158 | #define UARTSTAT_FE 0x00020000 | ||
159 | #define UARTSTAT_PE 0x00010000 | ||
160 | #define UARTSTAT_MA1F 0x00008000 | ||
161 | #define UARTSTAT_M21F 0x00004000 | ||
162 | |||
163 | #define UARTCTRL_R8T9 0x80000000 | ||
164 | #define UARTCTRL_R9T8 0x40000000 | ||
165 | #define UARTCTRL_TXDIR 0x20000000 | ||
166 | #define UARTCTRL_TXINV 0x10000000 | ||
167 | #define UARTCTRL_ORIE 0x08000000 | ||
168 | #define UARTCTRL_NEIE 0x04000000 | ||
169 | #define UARTCTRL_FEIE 0x02000000 | ||
170 | #define UARTCTRL_PEIE 0x01000000 | ||
171 | #define UARTCTRL_TIE 0x00800000 | ||
172 | #define UARTCTRL_TCIE 0x00400000 | ||
173 | #define UARTCTRL_RIE 0x00200000 | ||
174 | #define UARTCTRL_ILIE 0x00100000 | ||
175 | #define UARTCTRL_TE 0x00080000 | ||
176 | #define UARTCTRL_RE 0x00040000 | ||
177 | #define UARTCTRL_RWU 0x00020000 | ||
178 | #define UARTCTRL_SBK 0x00010000 | ||
179 | #define UARTCTRL_MA1IE 0x00008000 | ||
180 | #define UARTCTRL_MA2IE 0x00004000 | ||
181 | #define UARTCTRL_IDLECFG 0x00000100 | ||
182 | #define UARTCTRL_LOOPS 0x00000080 | ||
183 | #define UARTCTRL_DOZEEN 0x00000040 | ||
184 | #define UARTCTRL_RSRC 0x00000020 | ||
185 | #define UARTCTRL_M 0x00000010 | ||
186 | #define UARTCTRL_WAKE 0x00000008 | ||
187 | #define UARTCTRL_ILT 0x00000004 | ||
188 | #define UARTCTRL_PE 0x00000002 | ||
189 | #define UARTCTRL_PT 0x00000001 | ||
190 | |||
191 | #define UARTDATA_NOISY 0x00008000 | ||
192 | #define UARTDATA_PARITYE 0x00004000 | ||
193 | #define UARTDATA_FRETSC 0x00002000 | ||
194 | #define UARTDATA_RXEMPT 0x00001000 | ||
195 | #define UARTDATA_IDLINE 0x00000800 | ||
196 | #define UARTDATA_MASK 0x3ff | ||
197 | |||
198 | #define UARTMODIR_IREN 0x00020000 | ||
199 | #define UARTMODIR_TXCTSSRC 0x00000020 | ||
200 | #define UARTMODIR_TXCTSC 0x00000010 | ||
201 | #define UARTMODIR_RXRTSE 0x00000008 | ||
202 | #define UARTMODIR_TXRTSPOL 0x00000004 | ||
203 | #define UARTMODIR_TXRTSE 0x00000002 | ||
204 | #define UARTMODIR_TXCTSE 0x00000001 | ||
205 | |||
206 | #define UARTFIFO_TXEMPT 0x00800000 | ||
207 | #define UARTFIFO_RXEMPT 0x00400000 | ||
208 | #define UARTFIFO_TXOF 0x00020000 | ||
209 | #define UARTFIFO_RXUF 0x00010000 | ||
210 | #define UARTFIFO_TXFLUSH 0x00008000 | ||
211 | #define UARTFIFO_RXFLUSH 0x00004000 | ||
212 | #define UARTFIFO_TXOFE 0x00000200 | ||
213 | #define UARTFIFO_RXUFE 0x00000100 | ||
214 | #define UARTFIFO_TXFE 0x00000080 | ||
215 | #define UARTFIFO_FIFOSIZE_MASK 0x7 | ||
216 | #define UARTFIFO_TXSIZE_OFF 4 | ||
217 | #define UARTFIFO_RXFE 0x00000008 | ||
218 | #define UARTFIFO_RXSIZE_OFF 0 | ||
219 | |||
220 | #define UARTWATER_COUNT_MASK 0xff | ||
221 | #define UARTWATER_TXCNT_OFF 8 | ||
222 | #define UARTWATER_RXCNT_OFF 24 | ||
223 | #define UARTWATER_WATER_MASK 0xff | ||
224 | #define UARTWATER_TXWATER_OFF 0 | ||
225 | #define UARTWATER_RXWATER_OFF 16 | ||
226 | |||
120 | #define FSL_UART_RX_DMA_BUFFER_SIZE 64 | 227 | #define FSL_UART_RX_DMA_BUFFER_SIZE 64 |
121 | 228 | ||
122 | #define DRIVER_NAME "fsl-lpuart" | 229 | #define DRIVER_NAME "fsl-lpuart" |
@@ -128,6 +235,7 @@ struct lpuart_port { | |||
128 | struct clk *clk; | 235 | struct clk *clk; |
129 | unsigned int txfifo_size; | 236 | unsigned int txfifo_size; |
130 | unsigned int rxfifo_size; | 237 | unsigned int rxfifo_size; |
238 | bool lpuart32; | ||
131 | 239 | ||
132 | bool lpuart_dma_use; | 240 | bool lpuart_dma_use; |
133 | struct dma_chan *dma_tx_chan; | 241 | struct dma_chan *dma_tx_chan; |
@@ -152,6 +260,9 @@ static struct of_device_id lpuart_dt_ids[] = { | |||
152 | { | 260 | { |
153 | .compatible = "fsl,vf610-lpuart", | 261 | .compatible = "fsl,vf610-lpuart", |
154 | }, | 262 | }, |
263 | { | ||
264 | .compatible = "fsl,ls1021a-lpuart", | ||
265 | }, | ||
155 | { /* sentinel */ } | 266 | { /* sentinel */ } |
156 | }; | 267 | }; |
157 | MODULE_DEVICE_TABLE(of, lpuart_dt_ids); | 268 | MODULE_DEVICE_TABLE(of, lpuart_dt_ids); |
@@ -160,6 +271,16 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids); | |||
160 | static void lpuart_dma_tx_complete(void *arg); | 271 | static void lpuart_dma_tx_complete(void *arg); |
161 | static void lpuart_dma_rx_complete(void *arg); | 272 | static void lpuart_dma_rx_complete(void *arg); |
162 | 273 | ||
274 | static u32 lpuart32_read(void __iomem *addr) | ||
275 | { | ||
276 | return ioread32be(addr); | ||
277 | } | ||
278 | |||
279 | static void lpuart32_write(u32 val, void __iomem *addr) | ||
280 | { | ||
281 | iowrite32be(val, addr); | ||
282 | } | ||
283 | |||
163 | static void lpuart_stop_tx(struct uart_port *port) | 284 | static void lpuart_stop_tx(struct uart_port *port) |
164 | { | 285 | { |
165 | unsigned char temp; | 286 | unsigned char temp; |
@@ -169,6 +290,15 @@ static void lpuart_stop_tx(struct uart_port *port) | |||
169 | writeb(temp, port->membase + UARTCR2); | 290 | writeb(temp, port->membase + UARTCR2); |
170 | } | 291 | } |
171 | 292 | ||
293 | static void lpuart32_stop_tx(struct uart_port *port) | ||
294 | { | ||
295 | unsigned long temp; | ||
296 | |||
297 | temp = lpuart32_read(port->membase + UARTCTRL); | ||
298 | temp &= ~(UARTCTRL_TIE | UARTCTRL_TCIE); | ||
299 | lpuart32_write(temp, port->membase + UARTCTRL); | ||
300 | } | ||
301 | |||
172 | static void lpuart_stop_rx(struct uart_port *port) | 302 | static void lpuart_stop_rx(struct uart_port *port) |
173 | { | 303 | { |
174 | unsigned char temp; | 304 | unsigned char temp; |
@@ -177,6 +307,14 @@ static void lpuart_stop_rx(struct uart_port *port) | |||
177 | writeb(temp & ~UARTCR2_RE, port->membase + UARTCR2); | 307 | writeb(temp & ~UARTCR2_RE, port->membase + UARTCR2); |
178 | } | 308 | } |
179 | 309 | ||
310 | static void lpuart32_stop_rx(struct uart_port *port) | ||
311 | { | ||
312 | unsigned long temp; | ||
313 | |||
314 | temp = lpuart32_read(port->membase + UARTCTRL); | ||
315 | lpuart32_write(temp & ~UARTCTRL_RE, port->membase + UARTCTRL); | ||
316 | } | ||
317 | |||
180 | static void lpuart_copy_rx_to_tty(struct lpuart_port *sport, | 318 | static void lpuart_copy_rx_to_tty(struct lpuart_port *sport, |
181 | struct tty_port *tty, int count) | 319 | struct tty_port *tty, int count) |
182 | { | 320 | { |
@@ -399,6 +537,30 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport) | |||
399 | lpuart_stop_tx(&sport->port); | 537 | lpuart_stop_tx(&sport->port); |
400 | } | 538 | } |
401 | 539 | ||
540 | static inline void lpuart32_transmit_buffer(struct lpuart_port *sport) | ||
541 | { | ||
542 | struct circ_buf *xmit = &sport->port.state->xmit; | ||
543 | unsigned long txcnt; | ||
544 | |||
545 | txcnt = lpuart32_read(sport->port.membase + UARTWATER); | ||
546 | txcnt = txcnt >> UARTWATER_TXCNT_OFF; | ||
547 | txcnt &= UARTWATER_COUNT_MASK; | ||
548 | while (!uart_circ_empty(xmit) && (txcnt < sport->txfifo_size)) { | ||
549 | lpuart32_write(xmit->buf[xmit->tail], sport->port.membase + UARTDATA); | ||
550 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
551 | sport->port.icount.tx++; | ||
552 | txcnt = lpuart32_read(sport->port.membase + UARTWATER); | ||
553 | txcnt = txcnt >> UARTWATER_TXCNT_OFF; | ||
554 | txcnt &= UARTWATER_COUNT_MASK; | ||
555 | } | ||
556 | |||
557 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
558 | uart_write_wakeup(&sport->port); | ||
559 | |||
560 | if (uart_circ_empty(xmit)) | ||
561 | lpuart32_stop_tx(&sport->port); | ||
562 | } | ||
563 | |||
402 | static void lpuart_start_tx(struct uart_port *port) | 564 | static void lpuart_start_tx(struct uart_port *port) |
403 | { | 565 | { |
404 | struct lpuart_port *sport = container_of(port, | 566 | struct lpuart_port *sport = container_of(port, |
@@ -418,6 +580,18 @@ static void lpuart_start_tx(struct uart_port *port) | |||
418 | } | 580 | } |
419 | } | 581 | } |
420 | 582 | ||
583 | static void lpuart32_start_tx(struct uart_port *port) | ||
584 | { | ||
585 | struct lpuart_port *sport = container_of(port, struct lpuart_port, port); | ||
586 | unsigned long temp; | ||
587 | |||
588 | temp = lpuart32_read(port->membase + UARTCTRL); | ||
589 | lpuart32_write(temp | UARTCTRL_TIE, port->membase + UARTCTRL); | ||
590 | |||
591 | if (lpuart32_read(port->membase + UARTSTAT) & UARTSTAT_TDRE) | ||
592 | lpuart32_transmit_buffer(sport); | ||
593 | } | ||
594 | |||
421 | static irqreturn_t lpuart_txint(int irq, void *dev_id) | 595 | static irqreturn_t lpuart_txint(int irq, void *dev_id) |
422 | { | 596 | { |
423 | struct lpuart_port *sport = dev_id; | 597 | struct lpuart_port *sport = dev_id; |
@@ -426,16 +600,25 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id) | |||
426 | 600 | ||
427 | spin_lock_irqsave(&sport->port.lock, flags); | 601 | spin_lock_irqsave(&sport->port.lock, flags); |
428 | if (sport->port.x_char) { | 602 | if (sport->port.x_char) { |
429 | writeb(sport->port.x_char, sport->port.membase + UARTDR); | 603 | if (sport->lpuart32) |
604 | lpuart32_write(sport->port.x_char, sport->port.membase + UARTDATA); | ||
605 | else | ||
606 | writeb(sport->port.x_char, sport->port.membase + UARTDR); | ||
430 | goto out; | 607 | goto out; |
431 | } | 608 | } |
432 | 609 | ||
433 | if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { | 610 | if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { |
434 | lpuart_stop_tx(&sport->port); | 611 | if (sport->lpuart32) |
612 | lpuart32_stop_tx(&sport->port); | ||
613 | else | ||
614 | lpuart_stop_tx(&sport->port); | ||
435 | goto out; | 615 | goto out; |
436 | } | 616 | } |
437 | 617 | ||
438 | lpuart_transmit_buffer(sport); | 618 | if (sport->lpuart32) |
619 | lpuart32_transmit_buffer(sport); | ||
620 | else | ||
621 | lpuart_transmit_buffer(sport); | ||
439 | 622 | ||
440 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 623 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
441 | uart_write_wakeup(&sport->port); | 624 | uart_write_wakeup(&sport->port); |
@@ -508,6 +691,70 @@ out: | |||
508 | return IRQ_HANDLED; | 691 | return IRQ_HANDLED; |
509 | } | 692 | } |
510 | 693 | ||
694 | static irqreturn_t lpuart32_rxint(int irq, void *dev_id) | ||
695 | { | ||
696 | struct lpuart_port *sport = dev_id; | ||
697 | unsigned int flg, ignored = 0; | ||
698 | struct tty_port *port = &sport->port.state->port; | ||
699 | unsigned long flags; | ||
700 | unsigned long rx, sr; | ||
701 | |||
702 | spin_lock_irqsave(&sport->port.lock, flags); | ||
703 | |||
704 | while (!(lpuart32_read(sport->port.membase + UARTFIFO) & UARTFIFO_RXEMPT)) { | ||
705 | flg = TTY_NORMAL; | ||
706 | sport->port.icount.rx++; | ||
707 | /* | ||
708 | * to clear the FE, OR, NF, FE, PE flags, | ||
709 | * read STAT then read DATA reg | ||
710 | */ | ||
711 | sr = lpuart32_read(sport->port.membase + UARTSTAT); | ||
712 | rx = lpuart32_read(sport->port.membase + UARTDATA); | ||
713 | rx &= 0x3ff; | ||
714 | |||
715 | if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx)) | ||
716 | continue; | ||
717 | |||
718 | if (sr & (UARTSTAT_PE | UARTSTAT_OR | UARTSTAT_FE)) { | ||
719 | if (sr & UARTSTAT_PE) | ||
720 | sport->port.icount.parity++; | ||
721 | else if (sr & UARTSTAT_FE) | ||
722 | sport->port.icount.frame++; | ||
723 | |||
724 | if (sr & UARTSTAT_OR) | ||
725 | sport->port.icount.overrun++; | ||
726 | |||
727 | if (sr & sport->port.ignore_status_mask) { | ||
728 | if (++ignored > 100) | ||
729 | goto out; | ||
730 | continue; | ||
731 | } | ||
732 | |||
733 | sr &= sport->port.read_status_mask; | ||
734 | |||
735 | if (sr & UARTSTAT_PE) | ||
736 | flg = TTY_PARITY; | ||
737 | else if (sr & UARTSTAT_FE) | ||
738 | flg = TTY_FRAME; | ||
739 | |||
740 | if (sr & UARTSTAT_OR) | ||
741 | flg = TTY_OVERRUN; | ||
742 | |||
743 | #ifdef SUPPORT_SYSRQ | ||
744 | sport->port.sysrq = 0; | ||
745 | #endif | ||
746 | } | ||
747 | |||
748 | tty_insert_flip_char(port, rx, flg); | ||
749 | } | ||
750 | |||
751 | out: | ||
752 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
753 | |||
754 | tty_flip_buffer_push(port); | ||
755 | return IRQ_HANDLED; | ||
756 | } | ||
757 | |||
511 | static irqreturn_t lpuart_int(int irq, void *dev_id) | 758 | static irqreturn_t lpuart_int(int irq, void *dev_id) |
512 | { | 759 | { |
513 | struct lpuart_port *sport = dev_id; | 760 | struct lpuart_port *sport = dev_id; |
@@ -532,6 +779,26 @@ static irqreturn_t lpuart_int(int irq, void *dev_id) | |||
532 | return IRQ_HANDLED; | 779 | return IRQ_HANDLED; |
533 | } | 780 | } |
534 | 781 | ||
782 | static irqreturn_t lpuart32_int(int irq, void *dev_id) | ||
783 | { | ||
784 | struct lpuart_port *sport = dev_id; | ||
785 | unsigned long sts, rxcount; | ||
786 | |||
787 | sts = lpuart32_read(sport->port.membase + UARTSTAT); | ||
788 | rxcount = lpuart32_read(sport->port.membase + UARTWATER); | ||
789 | rxcount = rxcount >> UARTWATER_RXCNT_OFF; | ||
790 | |||
791 | if (sts & UARTSTAT_RDRF || rxcount > 0) | ||
792 | lpuart32_rxint(irq, dev_id); | ||
793 | |||
794 | if ((sts & UARTSTAT_TDRE) && | ||
795 | !(lpuart32_read(sport->port.membase + UARTBAUD) & UARTBAUD_TDMAE)) | ||
796 | lpuart_txint(irq, dev_id); | ||
797 | |||
798 | lpuart32_write(sts, sport->port.membase + UARTSTAT); | ||
799 | return IRQ_HANDLED; | ||
800 | } | ||
801 | |||
535 | /* return TIOCSER_TEMT when transmitter is not busy */ | 802 | /* return TIOCSER_TEMT when transmitter is not busy */ |
536 | static unsigned int lpuart_tx_empty(struct uart_port *port) | 803 | static unsigned int lpuart_tx_empty(struct uart_port *port) |
537 | { | 804 | { |
@@ -539,6 +806,12 @@ static unsigned int lpuart_tx_empty(struct uart_port *port) | |||
539 | TIOCSER_TEMT : 0; | 806 | TIOCSER_TEMT : 0; |
540 | } | 807 | } |
541 | 808 | ||
809 | static unsigned int lpuart32_tx_empty(struct uart_port *port) | ||
810 | { | ||
811 | return (lpuart32_read(port->membase + UARTSTAT) & UARTSTAT_TC) ? | ||
812 | TIOCSER_TEMT : 0; | ||
813 | } | ||
814 | |||
542 | static unsigned int lpuart_get_mctrl(struct uart_port *port) | 815 | static unsigned int lpuart_get_mctrl(struct uart_port *port) |
543 | { | 816 | { |
544 | unsigned int temp = 0; | 817 | unsigned int temp = 0; |
@@ -554,6 +827,21 @@ static unsigned int lpuart_get_mctrl(struct uart_port *port) | |||
554 | return temp; | 827 | return temp; |
555 | } | 828 | } |
556 | 829 | ||
830 | static unsigned int lpuart32_get_mctrl(struct uart_port *port) | ||
831 | { | ||
832 | unsigned int temp = 0; | ||
833 | unsigned long reg; | ||
834 | |||
835 | reg = lpuart32_read(port->membase + UARTMODIR); | ||
836 | if (reg & UARTMODIR_TXCTSE) | ||
837 | temp |= TIOCM_CTS; | ||
838 | |||
839 | if (reg & UARTMODIR_RXRTSE) | ||
840 | temp |= TIOCM_RTS; | ||
841 | |||
842 | return temp; | ||
843 | } | ||
844 | |||
557 | static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) | 845 | static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) |
558 | { | 846 | { |
559 | unsigned char temp; | 847 | unsigned char temp; |
@@ -570,6 +858,22 @@ static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
570 | writeb(temp, port->membase + UARTMODEM); | 858 | writeb(temp, port->membase + UARTMODEM); |
571 | } | 859 | } |
572 | 860 | ||
861 | static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
862 | { | ||
863 | unsigned long temp; | ||
864 | |||
865 | temp = lpuart32_read(port->membase + UARTMODIR) & | ||
866 | ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE); | ||
867 | |||
868 | if (mctrl & TIOCM_RTS) | ||
869 | temp |= UARTMODIR_RXRTSE; | ||
870 | |||
871 | if (mctrl & TIOCM_CTS) | ||
872 | temp |= UARTMODIR_TXCTSE; | ||
873 | |||
874 | lpuart32_write(temp, port->membase + UARTMODIR); | ||
875 | } | ||
876 | |||
573 | static void lpuart_break_ctl(struct uart_port *port, int break_state) | 877 | static void lpuart_break_ctl(struct uart_port *port, int break_state) |
574 | { | 878 | { |
575 | unsigned char temp; | 879 | unsigned char temp; |
@@ -582,6 +886,18 @@ static void lpuart_break_ctl(struct uart_port *port, int break_state) | |||
582 | writeb(temp, port->membase + UARTCR2); | 886 | writeb(temp, port->membase + UARTCR2); |
583 | } | 887 | } |
584 | 888 | ||
889 | static void lpuart32_break_ctl(struct uart_port *port, int break_state) | ||
890 | { | ||
891 | unsigned long temp; | ||
892 | |||
893 | temp = lpuart32_read(port->membase + UARTCTRL) & ~UARTCTRL_SBK; | ||
894 | |||
895 | if (break_state != 0) | ||
896 | temp |= UARTCTRL_SBK; | ||
897 | |||
898 | lpuart32_write(temp, port->membase + UARTCTRL); | ||
899 | } | ||
900 | |||
585 | static void lpuart_setup_watermark(struct lpuart_port *sport) | 901 | static void lpuart_setup_watermark(struct lpuart_port *sport) |
586 | { | 902 | { |
587 | unsigned char val, cr2; | 903 | unsigned char val, cr2; |
@@ -608,6 +924,31 @@ static void lpuart_setup_watermark(struct lpuart_port *sport) | |||
608 | writeb(cr2_saved, sport->port.membase + UARTCR2); | 924 | writeb(cr2_saved, sport->port.membase + UARTCR2); |
609 | } | 925 | } |
610 | 926 | ||
927 | static void lpuart32_setup_watermark(struct lpuart_port *sport) | ||
928 | { | ||
929 | unsigned long val, ctrl; | ||
930 | unsigned long ctrl_saved; | ||
931 | |||
932 | ctrl = lpuart32_read(sport->port.membase + UARTCTRL); | ||
933 | ctrl_saved = ctrl; | ||
934 | ctrl &= ~(UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_TE | | ||
935 | UARTCTRL_RIE | UARTCTRL_RE); | ||
936 | lpuart32_write(ctrl, sport->port.membase + UARTCTRL); | ||
937 | |||
938 | /* enable FIFO mode */ | ||
939 | val = lpuart32_read(sport->port.membase + UARTFIFO); | ||
940 | val |= UARTFIFO_TXFE | UARTFIFO_RXFE; | ||
941 | val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH; | ||
942 | lpuart32_write(val, sport->port.membase + UARTFIFO); | ||
943 | |||
944 | /* set the watermark */ | ||
945 | val = (0x1 << UARTWATER_RXWATER_OFF) | (0x0 << UARTWATER_TXWATER_OFF); | ||
946 | lpuart32_write(val, sport->port.membase + UARTWATER); | ||
947 | |||
948 | /* Restore cr2 */ | ||
949 | lpuart32_write(ctrl_saved, sport->port.membase + UARTCTRL); | ||
950 | } | ||
951 | |||
611 | static int lpuart_dma_tx_request(struct uart_port *port) | 952 | static int lpuart_dma_tx_request(struct uart_port *port) |
612 | { | 953 | { |
613 | struct lpuart_port *sport = container_of(port, | 954 | struct lpuart_port *sport = container_of(port, |
@@ -786,6 +1127,40 @@ static int lpuart_startup(struct uart_port *port) | |||
786 | return 0; | 1127 | return 0; |
787 | } | 1128 | } |
788 | 1129 | ||
1130 | static int lpuart32_startup(struct uart_port *port) | ||
1131 | { | ||
1132 | struct lpuart_port *sport = container_of(port, struct lpuart_port, port); | ||
1133 | int ret; | ||
1134 | unsigned long flags; | ||
1135 | unsigned long temp; | ||
1136 | |||
1137 | /* determine FIFO size */ | ||
1138 | temp = lpuart32_read(sport->port.membase + UARTFIFO); | ||
1139 | |||
1140 | sport->txfifo_size = 0x1 << (((temp >> UARTFIFO_TXSIZE_OFF) & | ||
1141 | UARTFIFO_FIFOSIZE_MASK) - 1); | ||
1142 | |||
1143 | sport->rxfifo_size = 0x1 << (((temp >> UARTFIFO_RXSIZE_OFF) & | ||
1144 | UARTFIFO_FIFOSIZE_MASK) - 1); | ||
1145 | |||
1146 | ret = devm_request_irq(port->dev, port->irq, lpuart32_int, 0, | ||
1147 | DRIVER_NAME, sport); | ||
1148 | if (ret) | ||
1149 | return ret; | ||
1150 | |||
1151 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1152 | |||
1153 | lpuart32_setup_watermark(sport); | ||
1154 | |||
1155 | temp = lpuart32_read(sport->port.membase + UARTCTRL); | ||
1156 | temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE | UARTCTRL_TE); | ||
1157 | temp |= UARTCTRL_ILIE; | ||
1158 | lpuart32_write(temp, sport->port.membase + UARTCTRL); | ||
1159 | |||
1160 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
789 | static void lpuart_shutdown(struct uart_port *port) | 1164 | static void lpuart_shutdown(struct uart_port *port) |
790 | { | 1165 | { |
791 | struct lpuart_port *sport = container_of(port, struct lpuart_port, port); | 1166 | struct lpuart_port *sport = container_of(port, struct lpuart_port, port); |
@@ -810,6 +1185,25 @@ static void lpuart_shutdown(struct uart_port *port) | |||
810 | } | 1185 | } |
811 | } | 1186 | } |
812 | 1187 | ||
1188 | static void lpuart32_shutdown(struct uart_port *port) | ||
1189 | { | ||
1190 | struct lpuart_port *sport = container_of(port, struct lpuart_port, port); | ||
1191 | unsigned long temp; | ||
1192 | unsigned long flags; | ||
1193 | |||
1194 | spin_lock_irqsave(&port->lock, flags); | ||
1195 | |||
1196 | /* disable Rx/Tx and interrupts */ | ||
1197 | temp = lpuart32_read(port->membase + UARTCTRL); | ||
1198 | temp &= ~(UARTCTRL_TE | UARTCTRL_RE | | ||
1199 | UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE); | ||
1200 | lpuart32_write(temp, port->membase + UARTCTRL); | ||
1201 | |||
1202 | spin_unlock_irqrestore(&port->lock, flags); | ||
1203 | |||
1204 | devm_free_irq(port->dev, port->irq, sport); | ||
1205 | } | ||
1206 | |||
813 | static void | 1207 | static void |
814 | lpuart_set_termios(struct uart_port *port, struct ktermios *termios, | 1208 | lpuart_set_termios(struct uart_port *port, struct ktermios *termios, |
815 | struct ktermios *old) | 1209 | struct ktermios *old) |
@@ -947,6 +1341,125 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, | |||
947 | spin_unlock_irqrestore(&sport->port.lock, flags); | 1341 | spin_unlock_irqrestore(&sport->port.lock, flags); |
948 | } | 1342 | } |
949 | 1343 | ||
1344 | static void | ||
1345 | lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, | ||
1346 | struct ktermios *old) | ||
1347 | { | ||
1348 | struct lpuart_port *sport = container_of(port, struct lpuart_port, port); | ||
1349 | unsigned long flags; | ||
1350 | unsigned long ctrl, old_ctrl, bd, modem; | ||
1351 | unsigned int baud; | ||
1352 | unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; | ||
1353 | unsigned int sbr; | ||
1354 | |||
1355 | ctrl = old_ctrl = lpuart32_read(sport->port.membase + UARTCTRL); | ||
1356 | bd = lpuart32_read(sport->port.membase + UARTBAUD); | ||
1357 | modem = lpuart32_read(sport->port.membase + UARTMODIR); | ||
1358 | /* | ||
1359 | * only support CS8 and CS7, and for CS7 must enable PE. | ||
1360 | * supported mode: | ||
1361 | * - (7,e/o,1) | ||
1362 | * - (8,n,1) | ||
1363 | * - (8,m/s,1) | ||
1364 | * - (8,e/o,1) | ||
1365 | */ | ||
1366 | while ((termios->c_cflag & CSIZE) != CS8 && | ||
1367 | (termios->c_cflag & CSIZE) != CS7) { | ||
1368 | termios->c_cflag &= ~CSIZE; | ||
1369 | termios->c_cflag |= old_csize; | ||
1370 | old_csize = CS8; | ||
1371 | } | ||
1372 | |||
1373 | if ((termios->c_cflag & CSIZE) == CS8 || | ||
1374 | (termios->c_cflag & CSIZE) == CS7) | ||
1375 | ctrl = old_ctrl & ~UARTCTRL_M; | ||
1376 | |||
1377 | if (termios->c_cflag & CMSPAR) { | ||
1378 | if ((termios->c_cflag & CSIZE) != CS8) { | ||
1379 | termios->c_cflag &= ~CSIZE; | ||
1380 | termios->c_cflag |= CS8; | ||
1381 | } | ||
1382 | ctrl |= UARTCTRL_M; | ||
1383 | } | ||
1384 | |||
1385 | if (termios->c_cflag & CRTSCTS) { | ||
1386 | modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); | ||
1387 | } else { | ||
1388 | termios->c_cflag &= ~CRTSCTS; | ||
1389 | modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); | ||
1390 | } | ||
1391 | |||
1392 | if (termios->c_cflag & CSTOPB) | ||
1393 | termios->c_cflag &= ~CSTOPB; | ||
1394 | |||
1395 | /* parity must be enabled when CS7 to match 8-bits format */ | ||
1396 | if ((termios->c_cflag & CSIZE) == CS7) | ||
1397 | termios->c_cflag |= PARENB; | ||
1398 | |||
1399 | if ((termios->c_cflag & PARENB)) { | ||
1400 | if (termios->c_cflag & CMSPAR) { | ||
1401 | ctrl &= ~UARTCTRL_PE; | ||
1402 | ctrl |= UARTCTRL_M; | ||
1403 | } else { | ||
1404 | ctrl |= UARTCR1_PE; | ||
1405 | if ((termios->c_cflag & CSIZE) == CS8) | ||
1406 | ctrl |= UARTCTRL_M; | ||
1407 | if (termios->c_cflag & PARODD) | ||
1408 | ctrl |= UARTCTRL_PT; | ||
1409 | else | ||
1410 | ctrl &= ~UARTCTRL_PT; | ||
1411 | } | ||
1412 | } | ||
1413 | |||
1414 | /* ask the core to calculate the divisor */ | ||
1415 | baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); | ||
1416 | |||
1417 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1418 | |||
1419 | sport->port.read_status_mask = 0; | ||
1420 | if (termios->c_iflag & INPCK) | ||
1421 | sport->port.read_status_mask |= (UARTSTAT_FE | UARTSTAT_PE); | ||
1422 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) | ||
1423 | sport->port.read_status_mask |= UARTSTAT_FE; | ||
1424 | |||
1425 | /* characters to ignore */ | ||
1426 | sport->port.ignore_status_mask = 0; | ||
1427 | if (termios->c_iflag & IGNPAR) | ||
1428 | sport->port.ignore_status_mask |= UARTSTAT_PE; | ||
1429 | if (termios->c_iflag & IGNBRK) { | ||
1430 | sport->port.ignore_status_mask |= UARTSTAT_FE; | ||
1431 | /* | ||
1432 | * if we're ignoring parity and break indicators, | ||
1433 | * ignore overruns too (for real raw support). | ||
1434 | */ | ||
1435 | if (termios->c_iflag & IGNPAR) | ||
1436 | sport->port.ignore_status_mask |= UARTSTAT_OR; | ||
1437 | } | ||
1438 | |||
1439 | /* update the per-port timeout */ | ||
1440 | uart_update_timeout(port, termios->c_cflag, baud); | ||
1441 | |||
1442 | /* wait transmit engin complete */ | ||
1443 | while (!(lpuart32_read(sport->port.membase + UARTSTAT) & UARTSTAT_TC)) | ||
1444 | barrier(); | ||
1445 | |||
1446 | /* disable transmit and receive */ | ||
1447 | lpuart32_write(old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE), | ||
1448 | sport->port.membase + UARTCTRL); | ||
1449 | |||
1450 | sbr = sport->port.uartclk / (16 * baud); | ||
1451 | bd &= ~UARTBAUD_SBR_MASK; | ||
1452 | bd |= sbr & UARTBAUD_SBR_MASK; | ||
1453 | bd |= UARTBAUD_BOTHEDGE; | ||
1454 | bd &= ~(UARTBAUD_TDMAE | UARTBAUD_RDMAE); | ||
1455 | lpuart32_write(bd, sport->port.membase + UARTBAUD); | ||
1456 | lpuart32_write(modem, sport->port.membase + UARTMODIR); | ||
1457 | lpuart32_write(ctrl, sport->port.membase + UARTCTRL); | ||
1458 | /* restore control register */ | ||
1459 | |||
1460 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1461 | } | ||
1462 | |||
950 | static const char *lpuart_type(struct uart_port *port) | 1463 | static const char *lpuart_type(struct uart_port *port) |
951 | { | 1464 | { |
952 | return "FSL_LPUART"; | 1465 | return "FSL_LPUART"; |
@@ -1006,6 +1519,24 @@ static struct uart_ops lpuart_pops = { | |||
1006 | .verify_port = lpuart_verify_port, | 1519 | .verify_port = lpuart_verify_port, |
1007 | }; | 1520 | }; |
1008 | 1521 | ||
1522 | static struct uart_ops lpuart32_pops = { | ||
1523 | .tx_empty = lpuart32_tx_empty, | ||
1524 | .set_mctrl = lpuart32_set_mctrl, | ||
1525 | .get_mctrl = lpuart32_get_mctrl, | ||
1526 | .stop_tx = lpuart32_stop_tx, | ||
1527 | .start_tx = lpuart32_start_tx, | ||
1528 | .stop_rx = lpuart32_stop_rx, | ||
1529 | .break_ctl = lpuart32_break_ctl, | ||
1530 | .startup = lpuart32_startup, | ||
1531 | .shutdown = lpuart32_shutdown, | ||
1532 | .set_termios = lpuart32_set_termios, | ||
1533 | .type = lpuart_type, | ||
1534 | .request_port = lpuart_request_port, | ||
1535 | .release_port = lpuart_release_port, | ||
1536 | .config_port = lpuart_config_port, | ||
1537 | .verify_port = lpuart_verify_port, | ||
1538 | }; | ||
1539 | |||
1009 | static struct lpuart_port *lpuart_ports[UART_NR]; | 1540 | static struct lpuart_port *lpuart_ports[UART_NR]; |
1010 | 1541 | ||
1011 | #ifdef CONFIG_SERIAL_FSL_LPUART_CONSOLE | 1542 | #ifdef CONFIG_SERIAL_FSL_LPUART_CONSOLE |
@@ -1017,6 +1548,14 @@ static void lpuart_console_putchar(struct uart_port *port, int ch) | |||
1017 | writeb(ch, port->membase + UARTDR); | 1548 | writeb(ch, port->membase + UARTDR); |
1018 | } | 1549 | } |
1019 | 1550 | ||
1551 | static void lpuart32_console_putchar(struct uart_port *port, int ch) | ||
1552 | { | ||
1553 | while (!(lpuart32_read(port->membase + UARTSTAT) & UARTSTAT_TDRE)) | ||
1554 | barrier(); | ||
1555 | |||
1556 | lpuart32_write(ch, port->membase + UARTDATA); | ||
1557 | } | ||
1558 | |||
1020 | static void | 1559 | static void |
1021 | lpuart_console_write(struct console *co, const char *s, unsigned int count) | 1560 | lpuart_console_write(struct console *co, const char *s, unsigned int count) |
1022 | { | 1561 | { |
@@ -1038,6 +1577,27 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count) | |||
1038 | writeb(old_cr2, sport->port.membase + UARTCR2); | 1577 | writeb(old_cr2, sport->port.membase + UARTCR2); |
1039 | } | 1578 | } |
1040 | 1579 | ||
1580 | static void | ||
1581 | lpuart32_console_write(struct console *co, const char *s, unsigned int count) | ||
1582 | { | ||
1583 | struct lpuart_port *sport = lpuart_ports[co->index]; | ||
1584 | unsigned long old_cr, cr; | ||
1585 | |||
1586 | /* first save CR2 and then disable interrupts */ | ||
1587 | cr = old_cr = lpuart32_read(sport->port.membase + UARTCTRL); | ||
1588 | cr |= (UARTCTRL_TE | UARTCTRL_RE); | ||
1589 | cr &= ~(UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE); | ||
1590 | lpuart32_write(cr, sport->port.membase + UARTCTRL); | ||
1591 | |||
1592 | uart_console_write(&sport->port, s, count, lpuart32_console_putchar); | ||
1593 | |||
1594 | /* wait for transmitter finish complete and restore CR2 */ | ||
1595 | while (!(lpuart32_read(sport->port.membase + UARTSTAT) & UARTSTAT_TC)) | ||
1596 | barrier(); | ||
1597 | |||
1598 | lpuart32_write(old_cr, sport->port.membase + UARTCTRL); | ||
1599 | } | ||
1600 | |||
1041 | /* | 1601 | /* |
1042 | * if the port was already initialised (eg, by a boot loader), | 1602 | * if the port was already initialised (eg, by a boot loader), |
1043 | * try to determine the current setup. | 1603 | * try to determine the current setup. |
@@ -1091,6 +1651,49 @@ lpuart_console_get_options(struct lpuart_port *sport, int *baud, | |||
1091 | "from %d to %d\n", baud_raw, *baud); | 1651 | "from %d to %d\n", baud_raw, *baud); |
1092 | } | 1652 | } |
1093 | 1653 | ||
1654 | static void __init | ||
1655 | lpuart32_console_get_options(struct lpuart_port *sport, int *baud, | ||
1656 | int *parity, int *bits) | ||
1657 | { | ||
1658 | unsigned long cr, bd; | ||
1659 | unsigned int sbr, uartclk, baud_raw; | ||
1660 | |||
1661 | cr = lpuart32_read(sport->port.membase + UARTCTRL); | ||
1662 | cr &= UARTCTRL_TE | UARTCTRL_RE; | ||
1663 | if (!cr) | ||
1664 | return; | ||
1665 | |||
1666 | /* ok, the port was enabled */ | ||
1667 | |||
1668 | cr = lpuart32_read(sport->port.membase + UARTCTRL); | ||
1669 | |||
1670 | *parity = 'n'; | ||
1671 | if (cr & UARTCTRL_PE) { | ||
1672 | if (cr & UARTCTRL_PT) | ||
1673 | *parity = 'o'; | ||
1674 | else | ||
1675 | *parity = 'e'; | ||
1676 | } | ||
1677 | |||
1678 | if (cr & UARTCTRL_M) | ||
1679 | *bits = 9; | ||
1680 | else | ||
1681 | *bits = 8; | ||
1682 | |||
1683 | bd = lpuart32_read(sport->port.membase + UARTBAUD); | ||
1684 | bd &= UARTBAUD_SBR_MASK; | ||
1685 | sbr = bd; | ||
1686 | uartclk = clk_get_rate(sport->clk); | ||
1687 | /* | ||
1688 | * baud = mod_clk/(16*(sbr[13]+(brfa)/32) | ||
1689 | */ | ||
1690 | baud_raw = uartclk / (16 * sbr); | ||
1691 | |||
1692 | if (*baud != baud_raw) | ||
1693 | printk(KERN_INFO "Serial: Console lpuart rounded baud rate" | ||
1694 | "from %d to %d\n", baud_raw, *baud); | ||
1695 | } | ||
1696 | |||
1094 | static int __init lpuart_console_setup(struct console *co, char *options) | 1697 | static int __init lpuart_console_setup(struct console *co, char *options) |
1095 | { | 1698 | { |
1096 | struct lpuart_port *sport; | 1699 | struct lpuart_port *sport; |
@@ -1114,9 +1717,15 @@ static int __init lpuart_console_setup(struct console *co, char *options) | |||
1114 | if (options) | 1717 | if (options) |
1115 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1718 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1116 | else | 1719 | else |
1117 | lpuart_console_get_options(sport, &baud, &parity, &bits); | 1720 | if (sport->lpuart32) |
1721 | lpuart32_console_get_options(sport, &baud, &parity, &bits); | ||
1722 | else | ||
1723 | lpuart_console_get_options(sport, &baud, &parity, &bits); | ||
1118 | 1724 | ||
1119 | lpuart_setup_watermark(sport); | 1725 | if (sport->lpuart32) |
1726 | lpuart32_setup_watermark(sport); | ||
1727 | else | ||
1728 | lpuart_setup_watermark(sport); | ||
1120 | 1729 | ||
1121 | return uart_set_options(&sport->port, co, baud, parity, bits, flow); | 1730 | return uart_set_options(&sport->port, co, baud, parity, bits, flow); |
1122 | } | 1731 | } |
@@ -1132,9 +1741,21 @@ static struct console lpuart_console = { | |||
1132 | .data = &lpuart_reg, | 1741 | .data = &lpuart_reg, |
1133 | }; | 1742 | }; |
1134 | 1743 | ||
1744 | static struct console lpuart32_console = { | ||
1745 | .name = DEV_NAME, | ||
1746 | .write = lpuart32_console_write, | ||
1747 | .device = uart_console_device, | ||
1748 | .setup = lpuart_console_setup, | ||
1749 | .flags = CON_PRINTBUFFER, | ||
1750 | .index = -1, | ||
1751 | .data = &lpuart_reg, | ||
1752 | }; | ||
1753 | |||
1135 | #define LPUART_CONSOLE (&lpuart_console) | 1754 | #define LPUART_CONSOLE (&lpuart_console) |
1755 | #define LPUART32_CONSOLE (&lpuart32_console) | ||
1136 | #else | 1756 | #else |
1137 | #define LPUART_CONSOLE NULL | 1757 | #define LPUART_CONSOLE NULL |
1758 | #define LPUART32_CONSOLE NULL | ||
1138 | #endif | 1759 | #endif |
1139 | 1760 | ||
1140 | static struct uart_driver lpuart_reg = { | 1761 | static struct uart_driver lpuart_reg = { |
@@ -1164,7 +1785,7 @@ static int lpuart_probe(struct platform_device *pdev) | |||
1164 | return ret; | 1785 | return ret; |
1165 | } | 1786 | } |
1166 | sport->port.line = ret; | 1787 | sport->port.line = ret; |
1167 | 1788 | sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart"); | |
1168 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1789 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1169 | if (!res) | 1790 | if (!res) |
1170 | return -ENODEV; | 1791 | return -ENODEV; |
@@ -1178,7 +1799,10 @@ static int lpuart_probe(struct platform_device *pdev) | |||
1178 | sport->port.type = PORT_LPUART; | 1799 | sport->port.type = PORT_LPUART; |
1179 | sport->port.iotype = UPIO_MEM; | 1800 | sport->port.iotype = UPIO_MEM; |
1180 | sport->port.irq = platform_get_irq(pdev, 0); | 1801 | sport->port.irq = platform_get_irq(pdev, 0); |
1181 | sport->port.ops = &lpuart_pops; | 1802 | if (sport->lpuart32) |
1803 | sport->port.ops = &lpuart32_pops; | ||
1804 | else | ||
1805 | sport->port.ops = &lpuart_pops; | ||
1182 | sport->port.flags = UPF_BOOT_AUTOCONF; | 1806 | sport->port.flags = UPF_BOOT_AUTOCONF; |
1183 | 1807 | ||
1184 | sport->clk = devm_clk_get(&pdev->dev, "ipg"); | 1808 | sport->clk = devm_clk_get(&pdev->dev, "ipg"); |
@@ -1200,6 +1824,11 @@ static int lpuart_probe(struct platform_device *pdev) | |||
1200 | 1824 | ||
1201 | platform_set_drvdata(pdev, &sport->port); | 1825 | platform_set_drvdata(pdev, &sport->port); |
1202 | 1826 | ||
1827 | if (sport->lpuart32) | ||
1828 | lpuart_reg.cons = LPUART32_CONSOLE; | ||
1829 | else | ||
1830 | lpuart_reg.cons = LPUART_CONSOLE; | ||
1831 | |||
1203 | ret = uart_add_one_port(&lpuart_reg, &sport->port); | 1832 | ret = uart_add_one_port(&lpuart_reg, &sport->port); |
1204 | if (ret) { | 1833 | if (ret) { |
1205 | clk_disable_unprepare(sport->clk); | 1834 | clk_disable_unprepare(sport->clk); |