Blame view

arch/powerpc/boot/serial.c 3.55 KB
0c176fa80   Mark A. Greer   [POWERPC] Add non...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  /*
   * Generic serial console support
   *
   * Author: Mark A. Greer <mgreer@mvista.com>
   *
   * Code in serial_edit_cmdline() copied from <file:arch/ppc/boot/simple/misc.c>
   * and was written by Matt Porter <mporter@kernel.crashing.org>.
   *
   * 2001,2006 (c) MontaVista Software, Inc.  This file is licensed under
   * the terms of the GNU General Public License version 2.  This program
   * is licensed "as is" without any warranty of any kind, whether express
   * or implied.
   */
  #include <stdarg.h>
  #include <stddef.h>
  #include "types.h"
  #include "string.h"
  #include "stdio.h"
  #include "io.h"
  #include "ops.h"
0c176fa80   Mark A. Greer   [POWERPC] Add non...
21
22
23
24
25
  static int serial_open(void)
  {
  	struct serial_console_data *scdp = console_ops.data;
  	return scdp->open();
  }
b96fbb6e1   Geoff Levand   [POWERPC] Fix con...
26
  static void serial_write(const char *buf, int len)
0c176fa80   Mark A. Greer   [POWERPC] Add non...
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  {
  	struct serial_console_data *scdp = console_ops.data;
  
  	while (*buf != '\0')
  		scdp->putc(*buf++);
  }
  
  static void serial_edit_cmdline(char *buf, int len)
  {
  	int timer = 0, count;
  	char ch, *cp;
  	struct serial_console_data *scdp = console_ops.data;
  
  	cp = buf;
  	count = strlen(buf);
  	cp = &buf[count];
  	count++;
  
  	while (timer++ < 5*1000) {
  		if (scdp->tstc()) {
  			while (((ch = scdp->getc()) != '
  ') && (ch != '\r')) {
  				/* Test for backspace/delete */
  				if ((ch == '\b') || (ch == '\177')) {
  					if (cp != buf) {
  						cp--;
  						count--;
  						printf("\b \b");
  					}
  				/* Test for ^x/^u (and wipe the line) */
  				} else if ((ch == '\030') || (ch == '\025')) {
  					while (cp != buf) {
  						cp--;
  						count--;
  						printf("\b \b");
  					}
  				} else if (count < len) {
  						*cp++ = ch;
  						count++;
  						scdp->putc(ch);
  				}
  			}
  			break;  /* Exit 'timer' loop */
  		}
  		udelay(1000);  /* 1 msec */
  	}
  	*cp = 0;
  }
  
  static void serial_close(void)
  {
  	struct serial_console_data *scdp = console_ops.data;
  
  	if (scdp->close)
  		scdp->close();
  }
  
  static void *serial_get_stdout_devp(void)
  {
  	void *devp;
  	char devtype[MAX_PROP_LEN];
  	char path[MAX_PATH_LEN];
  
  	devp = finddevice("/chosen");
  	if (devp == NULL)
  		goto err_out;
  
  	if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) {
  		devp = finddevice(path);
  		if (devp == NULL)
  			goto err_out;
  
  		if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0)
  				&& !strcmp(devtype, "serial"))
  			return devp;
  	}
  err_out:
  	return NULL;
  }
  
  static struct serial_console_data serial_cd;
  
  /* Node's "compatible" property determines which serial driver to use */
  int serial_console_init(void)
  {
  	void *devp;
  	int rc = -1;
0c176fa80   Mark A. Greer   [POWERPC] Add non...
114
115
116
117
  
  	devp = serial_get_stdout_devp();
  	if (devp == NULL)
  		goto err_out;
8f23735d8   Gerhard Pircher   powerpc/amigaone:...
118
119
  	if (dt_is_compatible(devp, "ns16550") ||
  	    dt_is_compatible(devp, "pnpPNP,501"))
0c176fa80   Mark A. Greer   [POWERPC] Add non...
120
  		rc = ns16550_console_init(devp, &serial_cd);
a1810b44c   Mark A. Greer   [POWERPC] mv64x60...
121
  	else if (dt_is_compatible(devp, "marvell,mv64360-mpsc"))
e12deb840   Mark A. Greer   [POWERPC] Add boo...
122
  		rc = mpsc_console_init(devp, &serial_cd);
d0f53fafc   Scott Wood   [POWERPC] bootwra...
123
124
125
126
127
  	else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") ||
  	         dt_is_compatible(devp, "fsl,cpm1-smc-uart") ||
  	         dt_is_compatible(devp, "fsl,cpm2-scc-uart") ||
  	         dt_is_compatible(devp, "fsl,cpm2-smc-uart"))
  		rc = cpm_console_init(devp, &serial_cd);
24ce6bc4a   Grant Likely   [POWERPC] mpc5200...
128
  	else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart"))
85498ae87   Grant Likely   [POWERPC] mpc5200...
129
  		rc = mpc5200_psc_console_init(devp, &serial_cd);
c35a8fb2f   Stephen Neuendorffer   [POWERPC] Xilinx:...
130
131
  	else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") ||
  		 dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a"))
7ddc5f978   Grant Likely   [POWERPC] Virtex:...
132
  		rc = uartlite_console_init(devp, &serial_cd);
0c176fa80   Mark A. Greer   [POWERPC] Add non...
133
134
135
136
137
138
  
  	/* Add other serial console driver calls here */
  
  	if (!rc) {
  		console_ops.open = serial_open;
  		console_ops.write = serial_write;
0c176fa80   Mark A. Greer   [POWERPC] Add non...
139
140
  		console_ops.close = serial_close;
  		console_ops.data = &serial_cd;
dc4f397d6   Scott Wood   [POWERPC] bootwra...
141
142
  		if (serial_cd.getc)
  			console_ops.edit_cmdline = serial_edit_cmdline;
0c176fa80   Mark A. Greer   [POWERPC] Add non...
143
144
145
146
147
  		return 0;
  	}
  err_out:
  	return -1;
  }