]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/serial/cpm_uart/cpm_uart_core.c
powerpc: implement GPIO LIB API on CPM1 Freescale SoC.
[mirror_ubuntu-bionic-kernel.git] / drivers / serial / cpm_uart / cpm_uart_core.c
CommitLineData
1da177e4
LT
1/*
2 * linux/drivers/serial/cpm_uart.c
3 *
4 * Driver for CPM (SCC/SMC) serial ports; core driver
5 *
6 * Based on arch/ppc/cpm2_io/uart.c by Dan Malek
7 * Based on ppc8xx.c by Thomas Gleixner
8 * Based on drivers/serial/amba.c by Russell King
9 *
4c8d3d99 10 * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
1da177e4 11 * Pantelis Antoniou (panto@intracom.gr) (CPM1)
311c4627 12 *
7ae87036 13 * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc.
1da177e4 14 * (C) 2004 Intracom, S.A.
6e197696 15 * (C) 2005-2006 MontaVista Software, Inc.
0d844065 16 * Vitaly Bordug <vbordug@ru.mvista.com>
1da177e4
LT
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 *
32 */
33
1da177e4
LT
34#include <linux/module.h>
35#include <linux/tty.h>
36#include <linux/ioport.h>
37#include <linux/init.h>
38#include <linux/serial.h>
39#include <linux/console.h>
40#include <linux/sysrq.h>
41#include <linux/device.h>
42#include <linux/bootmem.h>
43#include <linux/dma-mapping.h>
e27987cd 44#include <linux/fs_uart_pd.h>
0b2a2e5b 45#include <linux/of_platform.h>
1da177e4
LT
46
47#include <asm/io.h>
48#include <asm/irq.h>
49#include <asm/delay.h>
3dd0dcbe 50#include <asm/fs_pd.h>
7ae87036
SW
51#include <asm/udbg.h>
52
1da177e4
LT
53#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
54#define SUPPORT_SYSRQ
55#endif
56
57#include <linux/serial_core.h>
58#include <linux/kernel.h>
59
60#include "cpm_uart.h"
61
1da177e4
LT
62
63/**************************************************************/
64
65static int cpm_uart_tx_pump(struct uart_port *port);
66static void cpm_uart_init_smc(struct uart_cpm_port *pinfo);
67static void cpm_uart_init_scc(struct uart_cpm_port *pinfo);
68static void cpm_uart_initbd(struct uart_cpm_port *pinfo);
69
70/**************************************************************/
71
72/*
311c4627 73 * Check, if transmit buffers are processed
1da177e4
LT
74*/
75static unsigned int cpm_uart_tx_empty(struct uart_port *port)
76{
77 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
c1dcfd9d 78 cbd_t __iomem *bdp = pinfo->tx_bd_base;
1da177e4
LT
79 int ret = 0;
80
81 while (1) {
c1dcfd9d 82 if (in_be16(&bdp->cbd_sc) & BD_SC_READY)
1da177e4
LT
83 break;
84
c1dcfd9d 85 if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) {
1da177e4
LT
86 ret = TIOCSER_TEMT;
87 break;
88 }
89 bdp++;
90 }
91
92 pr_debug("CPM uart[%d]:tx_empty: %d\n", port->line, ret);
93
94 return ret;
95}
96
97static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
98{
99 /* Whee. Do nothing. */
100}
101
102static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
103{
104 /* Whee. Do nothing. */
105 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
106}
107
108/*
109 * Stop transmitter
110 */
b129a8cc 111static void cpm_uart_stop_tx(struct uart_port *port)
1da177e4
LT
112{
113 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
c1dcfd9d
SW
114 smc_t __iomem *smcp = pinfo->smcp;
115 scc_t __iomem *sccp = pinfo->sccp;
1da177e4
LT
116
117 pr_debug("CPM uart[%d]:stop tx\n", port->line);
118
119 if (IS_SMC(pinfo))
c1dcfd9d 120 clrbits8(&smcp->smc_smcm, SMCM_TX);
1da177e4 121 else
c1dcfd9d 122 clrbits16(&sccp->scc_sccm, UART_SCCM_TX);
1da177e4
LT
123}
124
125/*
126 * Start transmitter
127 */
b129a8cc 128static void cpm_uart_start_tx(struct uart_port *port)
1da177e4
LT
129{
130 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
c1dcfd9d
SW
131 smc_t __iomem *smcp = pinfo->smcp;
132 scc_t __iomem *sccp = pinfo->sccp;
1da177e4
LT
133
134 pr_debug("CPM uart[%d]:start tx\n", port->line);
135
136 if (IS_SMC(pinfo)) {
c1dcfd9d 137 if (in_8(&smcp->smc_smcm) & SMCM_TX)
1da177e4
LT
138 return;
139 } else {
c1dcfd9d 140 if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX)
1da177e4
LT
141 return;
142 }
143
144 if (cpm_uart_tx_pump(port) != 0) {
311c4627 145 if (IS_SMC(pinfo)) {
c1dcfd9d 146 setbits8(&smcp->smc_smcm, SMCM_TX);
311c4627 147 } else {
c1dcfd9d 148 setbits16(&sccp->scc_sccm, UART_SCCM_TX);
311c4627 149 }
1da177e4
LT
150 }
151}
152
153/*
311c4627 154 * Stop receiver
1da177e4
LT
155 */
156static void cpm_uart_stop_rx(struct uart_port *port)
157{
158 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
c1dcfd9d
SW
159 smc_t __iomem *smcp = pinfo->smcp;
160 scc_t __iomem *sccp = pinfo->sccp;
1da177e4
LT
161
162 pr_debug("CPM uart[%d]:stop rx\n", port->line);
163
164 if (IS_SMC(pinfo))
c1dcfd9d 165 clrbits8(&smcp->smc_smcm, SMCM_RX);
1da177e4 166 else
c1dcfd9d 167 clrbits16(&sccp->scc_sccm, UART_SCCM_RX);
1da177e4
LT
168}
169
170/*
171 * Enable Modem status interrupts
172 */
173static void cpm_uart_enable_ms(struct uart_port *port)
174{
175 pr_debug("CPM uart[%d]:enable ms\n", port->line);
176}
177
178/*
311c4627 179 * Generate a break.
1da177e4
LT
180 */
181static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
182{
183 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
1da177e4
LT
184
185 pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
186 break_state);
187
188 if (break_state)
7ae87036 189 cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
1da177e4 190 else
7ae87036 191 cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX);
1da177e4
LT
192}
193
194/*
195 * Transmit characters, refill buffer descriptor, if possible
196 */
7d12e780 197static void cpm_uart_int_tx(struct uart_port *port)
1da177e4
LT
198{
199 pr_debug("CPM uart[%d]:TX INT\n", port->line);
200
201 cpm_uart_tx_pump(port);
202}
203
8e21d04c
JW
204#ifdef CONFIG_CONSOLE_POLL
205static int serial_polled;
206#endif
207
1da177e4
LT
208/*
209 * Receive characters
210 */
7d12e780 211static void cpm_uart_int_rx(struct uart_port *port)
1da177e4
LT
212{
213 int i;
c1dcfd9d
SW
214 unsigned char ch;
215 u8 *cp;
f10140fb 216 struct tty_struct *tty = port->info->port.tty;
1da177e4 217 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
c1dcfd9d 218 cbd_t __iomem *bdp;
1da177e4
LT
219 u16 status;
220 unsigned int flg;
221
222 pr_debug("CPM uart[%d]:RX INT\n", port->line);
223
224 /* Just loop through the closed BDs and copy the characters into
225 * the buffer.
226 */
227 bdp = pinfo->rx_cur;
228 for (;;) {
8e21d04c
JW
229#ifdef CONFIG_CONSOLE_POLL
230 if (unlikely(serial_polled)) {
231 serial_polled = 0;
232 return;
233 }
234#endif
1da177e4 235 /* get status */
c1dcfd9d 236 status = in_be16(&bdp->cbd_sc);
1da177e4
LT
237 /* If this one is empty, return happy */
238 if (status & BD_SC_EMPTY)
239 break;
240
241 /* get number of characters, and check spce in flip-buffer */
c1dcfd9d 242 i = in_be16(&bdp->cbd_datlen);
1da177e4 243
311c4627 244 /* If we have not enough room in tty flip buffer, then we try
1da177e4
LT
245 * later, which will be the next rx-interrupt or a timeout
246 */
76a55431
VB
247 if(tty_buffer_request_room(tty, i) < i) {
248 printk(KERN_WARNING "No room in flip buffer\n");
249 return;
1da177e4
LT
250 }
251
252 /* get pointer */
c1dcfd9d 253 cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
1da177e4
LT
254
255 /* loop through the buffer */
256 while (i-- > 0) {
257 ch = *cp++;
258 port->icount.rx++;
259 flg = TTY_NORMAL;
260
261 if (status &
262 (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV))
263 goto handle_error;
7d12e780 264 if (uart_handle_sysrq_char(port, ch))
1da177e4 265 continue;
8e21d04c
JW
266#ifdef CONFIG_CONSOLE_POLL
267 if (unlikely(serial_polled)) {
268 serial_polled = 0;
269 return;
270 }
271#endif
1da177e4 272 error_return:
76a55431 273 tty_insert_flip_char(tty, ch, flg);
1da177e4
LT
274
275 } /* End while (i--) */
276
277 /* This BD is ready to be used again. Clear status. get next */
c1dcfd9d
SW
278 clrbits16(&bdp->cbd_sc, BD_SC_BR | BD_SC_FR | BD_SC_PR |
279 BD_SC_OV | BD_SC_ID);
280 setbits16(&bdp->cbd_sc, BD_SC_EMPTY);
1da177e4 281
c1dcfd9d 282 if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
1da177e4
LT
283 bdp = pinfo->rx_bd_base;
284 else
285 bdp++;
311c4627 286
1da177e4
LT
287 } /* End for (;;) */
288
289 /* Write back buffer pointer */
c1dcfd9d 290 pinfo->rx_cur = bdp;
1da177e4
LT
291
292 /* activate BH processing */
293 tty_flip_buffer_push(tty);
294
295 return;
296
297 /* Error processing */
298
299 handle_error:
300 /* Statistics */
301 if (status & BD_SC_BR)
302 port->icount.brk++;
303 if (status & BD_SC_PR)
304 port->icount.parity++;
305 if (status & BD_SC_FR)
306 port->icount.frame++;
307 if (status & BD_SC_OV)
308 port->icount.overrun++;
309
310 /* Mask out ignored conditions */
311 status &= port->read_status_mask;
312
313 /* Handle the remaining ones */
314 if (status & BD_SC_BR)
315 flg = TTY_BREAK;
316 else if (status & BD_SC_PR)
317 flg = TTY_PARITY;
318 else if (status & BD_SC_FR)
319 flg = TTY_FRAME;
320
321 /* overrun does not affect the current character ! */
322 if (status & BD_SC_OV) {
323 ch = 0;
324 flg = TTY_OVERRUN;
325 /* We skip this buffer */
326 /* CHECK: Is really nothing senseful there */
327 /* ASSUMPTION: it contains nothing valid */
328 i = 0;
329 }
330#ifdef SUPPORT_SYSRQ
331 port->sysrq = 0;
332#endif
333 goto error_return;
334}
335
336/*
337 * Asynchron mode interrupt handler
338 */
7d12e780 339static irqreturn_t cpm_uart_int(int irq, void *data)
1da177e4
LT
340{
341 u8 events;
15aafa2f 342 struct uart_port *port = data;
1da177e4 343 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
c1dcfd9d
SW
344 smc_t __iomem *smcp = pinfo->smcp;
345 scc_t __iomem *sccp = pinfo->sccp;
1da177e4
LT
346
347 pr_debug("CPM uart[%d]:IRQ\n", port->line);
348
349 if (IS_SMC(pinfo)) {
c1dcfd9d
SW
350 events = in_8(&smcp->smc_smce);
351 out_8(&smcp->smc_smce, events);
1da177e4
LT
352 if (events & SMCM_BRKE)
353 uart_handle_break(port);
354 if (events & SMCM_RX)
7d12e780 355 cpm_uart_int_rx(port);
1da177e4 356 if (events & SMCM_TX)
7d12e780 357 cpm_uart_int_tx(port);
1da177e4 358 } else {
c1dcfd9d
SW
359 events = in_be16(&sccp->scc_scce);
360 out_be16(&sccp->scc_scce, events);
1da177e4
LT
361 if (events & UART_SCCM_BRKE)
362 uart_handle_break(port);
363 if (events & UART_SCCM_RX)
7d12e780 364 cpm_uart_int_rx(port);
1da177e4 365 if (events & UART_SCCM_TX)
7d12e780 366 cpm_uart_int_tx(port);
1da177e4
LT
367 }
368 return (events) ? IRQ_HANDLED : IRQ_NONE;
369}
370
371static int cpm_uart_startup(struct uart_port *port)
372{
373 int retval;
374 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
375
376 pr_debug("CPM uart[%d]:startup\n", port->line);
377
378 /* Install interrupt handler. */
379 retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
380 if (retval)
381 return retval;
382
383 /* Startup rx-int */
384 if (IS_SMC(pinfo)) {
c1dcfd9d
SW
385 setbits8(&pinfo->smcp->smc_smcm, SMCM_RX);
386 setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN));
1da177e4 387 } else {
c1dcfd9d
SW
388 setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
389 setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT));
1da177e4
LT
390 }
391
311c4627 392 if (!(pinfo->flags & FLAG_CONSOLE))
7ae87036 393 cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
1da177e4
LT
394 return 0;
395}
396
311c4627
KG
397inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo)
398{
638861d5
KG
399 set_current_state(TASK_UNINTERRUPTIBLE);
400 schedule_timeout(pinfo->wait_closing);
311c4627
KG
401}
402
1da177e4
LT
403/*
404 * Shutdown the uart
405 */
406static void cpm_uart_shutdown(struct uart_port *port)
407{
408 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
1da177e4
LT
409
410 pr_debug("CPM uart[%d]:shutdown\n", port->line);
411
412 /* free interrupt handler */
413 free_irq(port->irq, port);
414
415 /* If the port is not the console, disable Rx and Tx. */
416 if (!(pinfo->flags & FLAG_CONSOLE)) {
311c4627 417 /* Wait for all the BDs marked sent */
638861d5
KG
418 while(!cpm_uart_tx_empty(port)) {
419 set_current_state(TASK_UNINTERRUPTIBLE);
311c4627 420 schedule_timeout(2);
638861d5
KG
421 }
422
423 if (pinfo->wait_closing)
311c4627
KG
424 cpm_uart_wait_until_send(pinfo);
425
1da177e4
LT
426 /* Stop uarts */
427 if (IS_SMC(pinfo)) {
c1dcfd9d
SW
428 smc_t __iomem *smcp = pinfo->smcp;
429 clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
430 clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX);
1da177e4 431 } else {
c1dcfd9d
SW
432 scc_t __iomem *sccp = pinfo->sccp;
433 clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
434 clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
1da177e4
LT
435 }
436
437 /* Shut them really down and reinit buffer descriptors */
ae2d4c39
NL
438 if (IS_SMC(pinfo)) {
439 out_be16(&pinfo->smcup->smc_brkcr, 0);
7ae87036 440 cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
ae2d4c39
NL
441 } else {
442 out_be16(&pinfo->sccup->scc_brkcr, 0);
7ae87036 443 cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
ae2d4c39 444 }
61f5657c 445
1da177e4
LT
446 cpm_uart_initbd(pinfo);
447 }
448}
449
450static void cpm_uart_set_termios(struct uart_port *port,
1bda8f30
SW
451 struct ktermios *termios,
452 struct ktermios *old)
1da177e4
LT
453{
454 int baud;
455 unsigned long flags;
456 u16 cval, scval, prev_mode;
457 int bits, sbits;
458 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
c1dcfd9d
SW
459 smc_t __iomem *smcp = pinfo->smcp;
460 scc_t __iomem *sccp = pinfo->sccp;
1da177e4
LT
461
462 pr_debug("CPM uart[%d]:set_termios\n", port->line);
463
464 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
465
466 /* Character length programmed into the mode register is the
467 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
468 * 1 or 2 stop bits, minus 1.
469 * The value 'bits' counts this for us.
470 */
471 cval = 0;
472 scval = 0;
473
474 /* byte size */
475 switch (termios->c_cflag & CSIZE) {
476 case CS5:
477 bits = 5;
478 break;
479 case CS6:
480 bits = 6;
481 break;
482 case CS7:
483 bits = 7;
484 break;
485 case CS8:
486 bits = 8;
487 break;
488 /* Never happens, but GCC is too dumb to figure it out */
489 default:
490 bits = 8;
491 break;
492 }
493 sbits = bits - 5;
494
495 if (termios->c_cflag & CSTOPB) {
496 cval |= SMCMR_SL; /* Two stops */
497 scval |= SCU_PSMR_SL;
498 bits++;
499 }
500
501 if (termios->c_cflag & PARENB) {
502 cval |= SMCMR_PEN;
503 scval |= SCU_PSMR_PEN;
504 bits++;
505 if (!(termios->c_cflag & PARODD)) {
506 cval |= SMCMR_PM_EVEN;
507 scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP);
508 }
509 }
510
dc320815
LP
511 /*
512 * Update the timeout
513 */
514 uart_update_timeout(port, termios->c_cflag, baud);
515
1da177e4
LT
516 /*
517 * Set up parity check flag
518 */
519#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
520
521 port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
522 if (termios->c_iflag & INPCK)
523 port->read_status_mask |= BD_SC_FR | BD_SC_PR;
524 if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK))
525 port->read_status_mask |= BD_SC_BR;
526
527 /*
528 * Characters to ignore
529 */
530 port->ignore_status_mask = 0;
531 if (termios->c_iflag & IGNPAR)
532 port->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
533 if (termios->c_iflag & IGNBRK) {
534 port->ignore_status_mask |= BD_SC_BR;
535 /*
536 * If we're ignore parity and break indicators, ignore
537 * overruns too. (For real raw support).
538 */
539 if (termios->c_iflag & IGNPAR)
540 port->ignore_status_mask |= BD_SC_OV;
541 }
542 /*
543 * !!! ignore all characters if CREAD is not set
544 */
545 if ((termios->c_cflag & CREAD) == 0)
546 port->read_status_mask &= ~BD_SC_EMPTY;
311c4627 547
1da177e4
LT
548 spin_lock_irqsave(&port->lock, flags);
549
550 /* Start bit has not been added (so don't, because we would just
551 * subtract it later), and we need to add one for the number of
552 * stops bits (there is always at least one).
553 */
554 bits++;
555 if (IS_SMC(pinfo)) {
556 /* Set the mode register. We want to keep a copy of the
557 * enables, because we want to put them back if they were
558 * present.
559 */
ae2d4c39
NL
560 prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN);
561 /* Output in *one* operation, so we don't interrupt RX/TX if they
562 * were already enabled. */
563 out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval |
564 SMCMR_SM_UART | prev_mode);
1da177e4 565 } else {
c1dcfd9d 566 out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
1da177e4
LT
567 }
568
569 cpm_set_brg(pinfo->brg - 1, baud);
570 spin_unlock_irqrestore(&port->lock, flags);
1da177e4
LT
571}
572
573static const char *cpm_uart_type(struct uart_port *port)
574{
575 pr_debug("CPM uart[%d]:uart_type\n", port->line);
576
577 return port->type == PORT_CPM ? "CPM UART" : NULL;
578}
579
580/*
581 * verify the new serial_struct (for TIOCSSERIAL).
582 */
583static int cpm_uart_verify_port(struct uart_port *port,
584 struct serial_struct *ser)
585{
586 int ret = 0;
587
588 pr_debug("CPM uart[%d]:verify_port\n", port->line);
589
590 if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM)
591 ret = -EINVAL;
592 if (ser->irq < 0 || ser->irq >= NR_IRQS)
593 ret = -EINVAL;
594 if (ser->baud_base < 9600)
595 ret = -EINVAL;
596 return ret;
597}
598
599/*
600 * Transmit characters, refill buffer descriptor, if possible
601 */
602static int cpm_uart_tx_pump(struct uart_port *port)
603{
c1dcfd9d
SW
604 cbd_t __iomem *bdp;
605 u8 *p;
1da177e4
LT
606 int count;
607 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
608 struct circ_buf *xmit = &port->info->xmit;
609
610 /* Handle xon/xoff */
611 if (port->x_char) {
612 /* Pick next descriptor and fill from buffer */
613 bdp = pinfo->tx_cur;
614
c1dcfd9d 615 p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
311c4627 616
03929c76 617 *p++ = port->x_char;
c1dcfd9d
SW
618
619 out_be16(&bdp->cbd_datlen, 1);
620 setbits16(&bdp->cbd_sc, BD_SC_READY);
1da177e4 621 /* Get next BD. */
c1dcfd9d 622 if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
1da177e4
LT
623 bdp = pinfo->tx_bd_base;
624 else
625 bdp++;
626 pinfo->tx_cur = bdp;
627
628 port->icount.tx++;
629 port->x_char = 0;
630 return 1;
631 }
632
633 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
b129a8cc 634 cpm_uart_stop_tx(port);
1da177e4
LT
635 return 0;
636 }
637
638 /* Pick next descriptor and fill from buffer */
639 bdp = pinfo->tx_cur;
640
c1dcfd9d
SW
641 while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) &&
642 xmit->tail != xmit->head) {
1da177e4 643 count = 0;
c1dcfd9d 644 p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
1da177e4
LT
645 while (count < pinfo->tx_fifosize) {
646 *p++ = xmit->buf[xmit->tail];
647 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
648 port->icount.tx++;
649 count++;
650 if (xmit->head == xmit->tail)
651 break;
652 }
c1dcfd9d
SW
653 out_be16(&bdp->cbd_datlen, count);
654 setbits16(&bdp->cbd_sc, BD_SC_READY);
1da177e4 655 /* Get next BD. */
c1dcfd9d 656 if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
1da177e4
LT
657 bdp = pinfo->tx_bd_base;
658 else
659 bdp++;
660 }
661 pinfo->tx_cur = bdp;
662
663 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
664 uart_write_wakeup(port);
665
666 if (uart_circ_empty(xmit)) {
b129a8cc 667 cpm_uart_stop_tx(port);
1da177e4
LT
668 return 0;
669 }
670
671 return 1;
672}
673
674/*
675 * init buffer descriptors
676 */
677static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
678{
679 int i;
680 u8 *mem_addr;
c1dcfd9d 681 cbd_t __iomem *bdp;
1da177e4
LT
682
683 pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line);
684
685 /* Set the physical address of the host memory
686 * buffers in the buffer descriptors, and the
687 * virtual address for us to work with.
688 */
689 mem_addr = pinfo->mem_addr;
690 bdp = pinfo->rx_cur = pinfo->rx_bd_base;
691 for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
c1dcfd9d
SW
692 out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
693 out_be16(&bdp->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT);
1da177e4
LT
694 mem_addr += pinfo->rx_fifosize;
695 }
311c4627 696
c1dcfd9d
SW
697 out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
698 out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT);
1da177e4
LT
699
700 /* Set the physical address of the host memory
701 * buffers in the buffer descriptors, and the
702 * virtual address for us to work with.
703 */
704 mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
705 bdp = pinfo->tx_cur = pinfo->tx_bd_base;
706 for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
c1dcfd9d
SW
707 out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
708 out_be16(&bdp->cbd_sc, BD_SC_INTRPT);
1da177e4
LT
709 mem_addr += pinfo->tx_fifosize;
710 }
311c4627 711
c1dcfd9d
SW
712 out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
713 out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_INTRPT);
1da177e4
LT
714}
715
716static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
717{
c1dcfd9d
SW
718 scc_t __iomem *scp;
719 scc_uart_t __iomem *sup;
1da177e4
LT
720
721 pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line);
722
723 scp = pinfo->sccp;
724 sup = pinfo->sccup;
725
726 /* Store address */
c1dcfd9d
SW
727 out_be16(&pinfo->sccup->scc_genscc.scc_rbase,
728 (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE);
729 out_be16(&pinfo->sccup->scc_genscc.scc_tbase,
730 (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);
1da177e4
LT
731
732 /* Set up the uart parameters in the
733 * parameter ram.
734 */
735
736 cpm_set_scc_fcr(sup);
737
c1dcfd9d
SW
738 out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize);
739 out_be16(&sup->scc_maxidl, pinfo->rx_fifosize);
740 out_be16(&sup->scc_brkcr, 1);
741 out_be16(&sup->scc_parec, 0);
742 out_be16(&sup->scc_frmec, 0);
743 out_be16(&sup->scc_nosec, 0);
744 out_be16(&sup->scc_brkec, 0);
745 out_be16(&sup->scc_uaddr1, 0);
746 out_be16(&sup->scc_uaddr2, 0);
747 out_be16(&sup->scc_toseq, 0);
748 out_be16(&sup->scc_char1, 0x8000);
749 out_be16(&sup->scc_char2, 0x8000);
750 out_be16(&sup->scc_char3, 0x8000);
751 out_be16(&sup->scc_char4, 0x8000);
752 out_be16(&sup->scc_char5, 0x8000);
753 out_be16(&sup->scc_char6, 0x8000);
754 out_be16(&sup->scc_char7, 0x8000);
755 out_be16(&sup->scc_char8, 0x8000);
756 out_be16(&sup->scc_rccm, 0xc0ff);
1da177e4
LT
757
758 /* Send the CPM an initialize command.
759 */
7ae87036 760 cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
1da177e4
LT
761
762 /* Set UART mode, 8 bit, no parity, one stop.
763 * Enable receive and transmit.
764 */
c1dcfd9d
SW
765 out_be32(&scp->scc_gsmrh, 0);
766 out_be32(&scp->scc_gsmrl,
767 SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
1da177e4
LT
768
769 /* Enable rx interrupts and clear all pending events. */
c1dcfd9d
SW
770 out_be16(&scp->scc_sccm, 0);
771 out_be16(&scp->scc_scce, 0xffff);
772 out_be16(&scp->scc_dsr, 0x7e7e);
773 out_be16(&scp->scc_psmr, 0x3000);
1da177e4 774
c1dcfd9d 775 setbits32(&scp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
1da177e4
LT
776}
777
778static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
779{
c1dcfd9d
SW
780 smc_t __iomem *sp;
781 smc_uart_t __iomem *up;
1da177e4
LT
782
783 pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line);
784
785 sp = pinfo->smcp;
786 up = pinfo->smcup;
787
788 /* Store address */
c1dcfd9d
SW
789 out_be16(&pinfo->smcup->smc_rbase,
790 (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE);
791 out_be16(&pinfo->smcup->smc_tbase,
792 (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);
1da177e4
LT
793
794/*
795 * In case SMC1 is being relocated...
796 */
797#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
c1dcfd9d
SW
798 out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase));
799 out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase));
800 out_be32(&up->smc_rstate, 0);
801 out_be32(&up->smc_tstate, 0);
802 out_be16(&up->smc_brkcr, 1); /* number of break chars */
803 out_be16(&up->smc_brkec, 0);
1da177e4
LT
804#endif
805
806 /* Set up the uart parameters in the
807 * parameter ram.
808 */
809 cpm_set_smc_fcr(up);
810
811 /* Using idle charater time requires some additional tuning. */
c1dcfd9d
SW
812 out_be16(&up->smc_mrblr, pinfo->rx_fifosize);
813 out_be16(&up->smc_maxidl, pinfo->rx_fifosize);
814 out_be16(&up->smc_brklen, 0);
815 out_be16(&up->smc_brkec, 0);
816 out_be16(&up->smc_brkcr, 1);
1da177e4 817
7ae87036 818 cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
1da177e4
LT
819
820 /* Set UART mode, 8 bit, no parity, one stop.
821 * Enable receive and transmit.
822 */
c1dcfd9d 823 out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART);
1da177e4
LT
824
825 /* Enable only rx interrupts clear all pending events. */
c1dcfd9d
SW
826 out_8(&sp->smc_smcm, 0);
827 out_8(&sp->smc_smce, 0xff);
1da177e4 828
c1dcfd9d 829 setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
1da177e4
LT
830}
831
832/*
833 * Initialize port. This is called from early_console stuff
834 * so we have to be careful here !
835 */
836static int cpm_uart_request_port(struct uart_port *port)
837{
838 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
839 int ret;
840
841 pr_debug("CPM uart[%d]:request port\n", port->line);
842
843 if (pinfo->flags & FLAG_CONSOLE)
844 return 0;
845
1da177e4 846 if (IS_SMC(pinfo)) {
c1dcfd9d
SW
847 clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
848 clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
1da177e4 849 } else {
c1dcfd9d
SW
850 clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
851 clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
1da177e4
LT
852 }
853
854 ret = cpm_uart_allocbuf(pinfo, 0);
855
856 if (ret)
857 return ret;
858
859 cpm_uart_initbd(pinfo);
311c4627
KG
860 if (IS_SMC(pinfo))
861 cpm_uart_init_smc(pinfo);
862 else
863 cpm_uart_init_scc(pinfo);
1da177e4
LT
864
865 return 0;
866}
867
868static void cpm_uart_release_port(struct uart_port *port)
869{
870 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
871
872 if (!(pinfo->flags & FLAG_CONSOLE))
873 cpm_uart_freebuf(pinfo);
874}
875
876/*
877 * Configure/autoconfigure the port.
878 */
879static void cpm_uart_config_port(struct uart_port *port, int flags)
880{
881 pr_debug("CPM uart[%d]:config_port\n", port->line);
882
883 if (flags & UART_CONFIG_TYPE) {
884 port->type = PORT_CPM;
885 cpm_uart_request_port(port);
886 }
887}
8e21d04c
JW
888
889#ifdef CONFIG_CONSOLE_POLL
890/* Serial polling routines for writing and reading from the uart while
891 * in an interrupt or debug context.
892 */
893
894#define GDB_BUF_SIZE 512 /* power of 2, please */
895
896static char poll_buf[GDB_BUF_SIZE];
897static char *pollp;
898static int poll_chars;
899
900static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
901{
902 u_char c, *cp;
903 volatile cbd_t *bdp;
904 int i;
905
906 /* Get the address of the host memory buffer.
907 */
908 bdp = pinfo->rx_cur;
909 while (bdp->cbd_sc & BD_SC_EMPTY)
910 ;
911
912 /* If the buffer address is in the CPM DPRAM, don't
913 * convert it.
914 */
915 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
916
917 if (obuf) {
918 i = c = bdp->cbd_datlen;
919 while (i-- > 0)
920 *obuf++ = *cp++;
921 } else
922 c = *cp;
923 bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
924 bdp->cbd_sc |= BD_SC_EMPTY;
925
926 if (bdp->cbd_sc & BD_SC_WRAP)
927 bdp = pinfo->rx_bd_base;
928 else
929 bdp++;
930 pinfo->rx_cur = (cbd_t *)bdp;
931
932 return (int)c;
933}
934
935static int cpm_get_poll_char(struct uart_port *port)
936{
937 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
938
939 if (!serial_polled) {
940 serial_polled = 1;
941 poll_chars = 0;
942 }
943 if (poll_chars <= 0) {
944 poll_chars = poll_wait_key(poll_buf, pinfo);
945 pollp = poll_buf;
946 }
947 poll_chars--;
948 return *pollp++;
949}
950
951static void cpm_put_poll_char(struct uart_port *port,
952 unsigned char c)
953{
954 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
955 static char ch[2];
956
957 ch[0] = (char)c;
958 cpm_uart_early_write(pinfo->port.line, ch, 1);
959}
960#endif /* CONFIG_CONSOLE_POLL */
961
1da177e4
LT
962static struct uart_ops cpm_uart_pops = {
963 .tx_empty = cpm_uart_tx_empty,
964 .set_mctrl = cpm_uart_set_mctrl,
965 .get_mctrl = cpm_uart_get_mctrl,
966 .stop_tx = cpm_uart_stop_tx,
967 .start_tx = cpm_uart_start_tx,
968 .stop_rx = cpm_uart_stop_rx,
969 .enable_ms = cpm_uart_enable_ms,
970 .break_ctl = cpm_uart_break_ctl,
971 .startup = cpm_uart_startup,
972 .shutdown = cpm_uart_shutdown,
973 .set_termios = cpm_uart_set_termios,
974 .type = cpm_uart_type,
975 .release_port = cpm_uart_release_port,
976 .request_port = cpm_uart_request_port,
977 .config_port = cpm_uart_config_port,
978 .verify_port = cpm_uart_verify_port,
8e21d04c
JW
979#ifdef CONFIG_CONSOLE_POLL
980 .poll_get_char = cpm_get_poll_char,
981 .poll_put_char = cpm_put_poll_char,
982#endif
1da177e4
LT
983};
984
7ae87036
SW
985struct uart_cpm_port cpm_uart_ports[UART_NR];
986
c1dcfd9d
SW
987static int cpm_uart_init_port(struct device_node *np,
988 struct uart_cpm_port *pinfo)
7ae87036
SW
989{
990 const u32 *data;
c1dcfd9d 991 void __iomem *mem, *pram;
7ae87036
SW
992 int len;
993 int ret;
994
995 data = of_get_property(np, "fsl,cpm-brg", &len);
996 if (!data || len != 4) {
997 printk(KERN_ERR "CPM UART %s has no/invalid "
998 "fsl,cpm-brg property.\n", np->name);
999 return -EINVAL;
1000 }
1001 pinfo->brg = *data;
1002
1003 data = of_get_property(np, "fsl,cpm-command", &len);
1004 if (!data || len != 4) {
1005 printk(KERN_ERR "CPM UART %s has no/invalid "
1006 "fsl,cpm-command property.\n", np->name);
1007 return -EINVAL;
1008 }
1009 pinfo->command = *data;
1010
1011 mem = of_iomap(np, 0);
1012 if (!mem)
1013 return -ENOMEM;
1014
7ae87036
SW
1015 if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") ||
1016 of_device_is_compatible(np, "fsl,cpm2-scc-uart")) {
1017 pinfo->sccp = mem;
d464df26 1018 pinfo->sccup = pram = cpm_uart_map_pram(pinfo, np);
7ae87036
SW
1019 } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") ||
1020 of_device_is_compatible(np, "fsl,cpm2-smc-uart")) {
1021 pinfo->flags |= FLAG_SMC;
1022 pinfo->smcp = mem;
d464df26 1023 pinfo->smcup = pram = cpm_uart_map_pram(pinfo, np);
7ae87036
SW
1024 } else {
1025 ret = -ENODEV;
d464df26
LP
1026 goto out_mem;
1027 }
1028
1029 if (!pram) {
1030 ret = -ENOMEM;
1031 goto out_mem;
7ae87036
SW
1032 }
1033
1034 pinfo->tx_nrfifos = TX_NUM_FIFO;
1035 pinfo->tx_fifosize = TX_BUF_SIZE;
1036 pinfo->rx_nrfifos = RX_NUM_FIFO;
1037 pinfo->rx_fifosize = RX_BUF_SIZE;
1038
1039 pinfo->port.uartclk = ppc_proc_freq;
1040 pinfo->port.mapbase = (unsigned long)mem;
1041 pinfo->port.type = PORT_CPM;
1042 pinfo->port.ops = &cpm_uart_pops,
1043 pinfo->port.iotype = UPIO_MEM;
dc320815 1044 pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize;
7ae87036
SW
1045 spin_lock_init(&pinfo->port.lock);
1046
1047 pinfo->port.irq = of_irq_to_resource(np, 0, NULL);
1048 if (pinfo->port.irq == NO_IRQ) {
1049 ret = -EINVAL;
1050 goto out_pram;
1051 }
1052
1053 return cpm_uart_request_port(&pinfo->port);
1054
1055out_pram:
d464df26 1056 cpm_uart_unmap_pram(pinfo, pram);
7ae87036
SW
1057out_mem:
1058 iounmap(mem);
1059 return ret;
1060}
1061
1da177e4
LT
1062#ifdef CONFIG_SERIAL_CPM_CONSOLE
1063/*
1064 * Print a string to the serial port trying not to disturb
1065 * any possible real use of the port...
1066 *
1067 * Note that this is called with interrupts already disabled
1068 */
1069static void cpm_uart_console_write(struct console *co, const char *s,
1070 u_int count)
1071{
7ae87036 1072 struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
1da177e4 1073 unsigned int i;
c1dcfd9d
SW
1074 cbd_t __iomem *bdp, *bdbase;
1075 unsigned char *cp;
491a7a43
RT
1076 unsigned long flags;
1077 int nolock = oops_in_progress;
1078
1079 if (unlikely(nolock)) {
1080 local_irq_save(flags);
1081 } else {
1082 spin_lock_irqsave(&pinfo->port.lock, flags);
1083 }
1da177e4
LT
1084
1085 /* Get the address of the host memory buffer.
1086 */
1087 bdp = pinfo->tx_cur;
1088 bdbase = pinfo->tx_bd_base;
1089
1090 /*
1091 * Now, do each character. This is not as bad as it looks
1092 * since this is a holding FIFO and not a transmitting FIFO.
1093 * We could add the complexity of filling the entire transmit
1094 * buffer, but we would just wait longer between accesses......
1095 */
1096 for (i = 0; i < count; i++, s++) {
1097 /* Wait for transmitter fifo to empty.
1098 * Ready indicates output is ready, and xmt is doing
1099 * that, not that it is ready for us to send.
1100 */
c1dcfd9d 1101 while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
1da177e4
LT
1102 ;
1103
1104 /* Send the character out.
1105 * If the buffer address is in the CPM DPRAM, don't
1106 * convert it.
1107 */
c1dcfd9d 1108 cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
1da177e4
LT
1109 *cp = *s;
1110
c1dcfd9d
SW
1111 out_be16(&bdp->cbd_datlen, 1);
1112 setbits16(&bdp->cbd_sc, BD_SC_READY);
1da177e4 1113
c1dcfd9d 1114 if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
1da177e4
LT
1115 bdp = bdbase;
1116 else
1117 bdp++;
1118
1119 /* if a LF, also do CR... */
1120 if (*s == 10) {
c1dcfd9d 1121 while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
1da177e4
LT
1122 ;
1123
c1dcfd9d 1124 cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
1da177e4 1125 *cp = 13;
1da177e4 1126
c1dcfd9d
SW
1127 out_be16(&bdp->cbd_datlen, 1);
1128 setbits16(&bdp->cbd_sc, BD_SC_READY);
1129
1130 if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
1da177e4
LT
1131 bdp = bdbase;
1132 else
1133 bdp++;
1134 }
1135 }
1136
1137 /*
1138 * Finally, Wait for transmitter & holding register to empty
1139 * and restore the IER
1140 */
c1dcfd9d 1141 while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
1da177e4
LT
1142 ;
1143
c1dcfd9d 1144 pinfo->tx_cur = bdp;
491a7a43
RT
1145
1146 if (unlikely(nolock)) {
1147 local_irq_restore(flags);
1148 } else {
1149 spin_unlock_irqrestore(&pinfo->port.lock, flags);
1150 }
1da177e4
LT
1151}
1152
e27987cd 1153
1da177e4
LT
1154static int __init cpm_uart_console_setup(struct console *co, char *options)
1155{
1da177e4
LT
1156 int baud = 38400;
1157 int bits = 8;
1158 int parity = 'n';
1159 int flow = 'n';
1160 int ret;
7ae87036
SW
1161 struct uart_cpm_port *pinfo;
1162 struct uart_port *port;
1163
7ae87036
SW
1164 struct device_node *np = NULL;
1165 int i = 0;
1166
1167 if (co->index >= UART_NR) {
1168 printk(KERN_ERR "cpm_uart: console index %d too high\n",
1169 co->index);
1170 return -ENODEV;
1171 }
1172
1173 do {
1174 np = of_find_node_by_type(np, "serial");
1175 if (!np)
1176 return -ENODEV;
1177
1178 if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") &&
1179 !of_device_is_compatible(np, "fsl,cpm1-scc-uart") &&
1180 !of_device_is_compatible(np, "fsl,cpm2-smc-uart") &&
1181 !of_device_is_compatible(np, "fsl,cpm2-scc-uart"))
1182 i--;
1183 } while (i++ != co->index);
1184
1185 pinfo = &cpm_uart_ports[co->index];
1186
1187 pinfo->flags |= FLAG_CONSOLE;
1188 port = &pinfo->port;
1189
1190 ret = cpm_uart_init_port(np, pinfo);
1191 of_node_put(np);
1192 if (ret)
1193 return ret;
1194
1da177e4
LT
1195 if (options) {
1196 uart_parse_options(options, &baud, &parity, &bits, &flow);
1197 } else {
3dd0dcbe 1198 if ((baud = uart_baudrate()) == -1)
1da177e4
LT
1199 baud = 9600;
1200 }
1201
7ae87036
SW
1202#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
1203 udbg_putc = NULL;
1204#endif
1205
1da177e4 1206 if (IS_SMC(pinfo)) {
ae2d4c39
NL
1207 out_be16(&pinfo->smcup->smc_brkcr, 0);
1208 cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
c1dcfd9d
SW
1209 clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
1210 clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
1da177e4 1211 } else {
ae2d4c39
NL
1212 out_be16(&pinfo->sccup->scc_brkcr, 0);
1213 cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
c1dcfd9d
SW
1214 clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
1215 clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
1da177e4
LT
1216 }
1217
1218 ret = cpm_uart_allocbuf(pinfo, 1);
1219
1220 if (ret)
1221 return ret;
1222
1223 cpm_uart_initbd(pinfo);
1224
1225 if (IS_SMC(pinfo))
1226 cpm_uart_init_smc(pinfo);
1227 else
1228 cpm_uart_init_scc(pinfo);
1229
1230 uart_set_options(port, co, baud, parity, bits, flow);
d948a29e 1231 cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX);
1da177e4
LT
1232
1233 return 0;
1234}
1235
36d2f5a1 1236static struct uart_driver cpm_reg;
1da177e4 1237static struct console cpm_scc_uart_console = {
36d2f5a1
KG
1238 .name = "ttyCPM",
1239 .write = cpm_uart_console_write,
1240 .device = uart_console_device,
1241 .setup = cpm_uart_console_setup,
1242 .flags = CON_PRINTBUFFER,
1243 .index = -1,
1da177e4
LT
1244 .data = &cpm_reg,
1245};
1246
c1dcfd9d 1247static int __init cpm_uart_console_init(void)
1da177e4 1248{
e27987cd
VB
1249 register_console(&cpm_scc_uart_console);
1250 return 0;
1da177e4
LT
1251}
1252
1253console_initcall(cpm_uart_console_init);
1254
1255#define CPM_UART_CONSOLE &cpm_scc_uart_console
1256#else
1257#define CPM_UART_CONSOLE NULL
1258#endif
1259
1260static struct uart_driver cpm_reg = {
1261 .owner = THIS_MODULE,
1262 .driver_name = "ttyCPM",
1263 .dev_name = "ttyCPM",
1264 .major = SERIAL_CPM_MAJOR,
1265 .minor = SERIAL_CPM_MINOR,
1266 .cons = CPM_UART_CONSOLE,
7ae87036
SW
1267 .nr = UART_NR,
1268};
1269
7ae87036
SW
1270static int probe_index;
1271
1272static int __devinit cpm_uart_probe(struct of_device *ofdev,
1273 const struct of_device_id *match)
1274{
1275 int index = probe_index++;
1276 struct uart_cpm_port *pinfo = &cpm_uart_ports[index];
1277 int ret;
1278
1279 pinfo->port.line = index;
1280
1281 if (index >= UART_NR)
1282 return -ENODEV;
1283
1284 dev_set_drvdata(&ofdev->dev, pinfo);
1285
1286 ret = cpm_uart_init_port(ofdev->node, pinfo);
1287 if (ret)
1288 return ret;
1289
1290 return uart_add_one_port(&cpm_reg, &pinfo->port);
1291}
1292
1293static int __devexit cpm_uart_remove(struct of_device *ofdev)
1294{
1295 struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev);
1296 return uart_remove_one_port(&cpm_reg, &pinfo->port);
1297}
1298
1299static struct of_device_id cpm_uart_match[] = {
1300 {
1301 .compatible = "fsl,cpm1-smc-uart",
1302 },
1303 {
1304 .compatible = "fsl,cpm1-scc-uart",
1305 },
1306 {
1307 .compatible = "fsl,cpm2-smc-uart",
1308 },
1309 {
1310 .compatible = "fsl,cpm2-scc-uart",
1311 },
1312 {}
1da177e4 1313};
7ae87036
SW
1314
1315static struct of_platform_driver cpm_uart_driver = {
1316 .name = "cpm_uart",
1317 .match_table = cpm_uart_match,
1318 .probe = cpm_uart_probe,
1319 .remove = cpm_uart_remove,
1320 };
1321
1322static int __init cpm_uart_init(void)
1323{
1324 int ret = uart_register_driver(&cpm_reg);
1325 if (ret)
1326 return ret;
1327
1328 ret = of_register_platform_driver(&cpm_uart_driver);
1329 if (ret)
1330 uart_unregister_driver(&cpm_reg);
1331
1332 return ret;
1333}
1334
1335static void __exit cpm_uart_exit(void)
1336{
1337 of_unregister_platform_driver(&cpm_uart_driver);
1338 uart_unregister_driver(&cpm_reg);
1339}
1da177e4
LT
1340
1341module_init(cpm_uart_init);
1342module_exit(cpm_uart_exit);
1343
1344MODULE_AUTHOR("Kumar Gala/Antoniou Pantelis");
1345MODULE_DESCRIPTION("CPM SCC/SMC port driver $Revision: 0.01 $");
1346MODULE_LICENSE("GPL");
1347MODULE_ALIAS_CHARDEV(SERIAL_CPM_MAJOR, SERIAL_CPM_MINOR);