aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-20 19:59:26 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-20 19:59:26 -0400
commitc73fcc846c91f53fd2c67fd9c6c04888a9e5892e (patch)
tree31faa68b4176636756926535a0f50ff780973275 /arch
parentede13d81b4dda409a6d271b34b8e2ec9383e255d (diff)
[SPARC]: Fix serial console device detection.
The current scheme works on static interpretation of text names, which is wrong. The output-device setting, for example, must be resolved via an alias or similar to a full path name to the console device. Paths also contain an optional set of 'options', which starts with a colon at the end of the path. The option area is used to specify which of two serial ports ('a' or 'b') the path refers to when a device node drives multiple ports. 'a' is assumed if the option specification is missing. This was caught by the UltraSPARC-T1 simulator. The 'output-device' property was set to 'ttya' and we didn't pick upon the fact that this is an OBP alias set to '/virtual-devices/console'. Instead we saw it as the first serial console device, instead of the hypervisor console. The infrastructure is now there to take advantage of this to resolve the console correctly even in multi-head situations in fbcon too. Thanks to Greg Onufer for the bug report. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/kernel/process.c8
-rw-r--r--arch/sparc/kernel/prom.c131
-rw-r--r--arch/sparc/kernel/setup.c65
-rw-r--r--arch/sparc/prom/console.c116
-rw-r--r--arch/sparc/prom/misc.c4
-rw-r--r--arch/sparc64/kernel/power.c2
-rw-r--r--arch/sparc64/kernel/process.c6
-rw-r--r--arch/sparc64/kernel/prom.c56
-rw-r--r--arch/sparc64/kernel/setup.c70
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c1
-rw-r--r--arch/sparc64/prom/console.c85
-rw-r--r--arch/sparc64/prom/misc.c4
-rw-r--r--arch/sparc64/prom/tree.c8
13 files changed, 210 insertions, 346 deletions
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 8c37f8f5adb7..33f7a3ddb104 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -39,6 +39,7 @@
39#include <asm/processor.h> 39#include <asm/processor.h>
40#include <asm/psr.h> 40#include <asm/psr.h>
41#include <asm/elf.h> 41#include <asm/elf.h>
42#include <asm/prom.h>
42#include <asm/unistd.h> 43#include <asm/unistd.h>
43 44
44/* 45/*
@@ -150,7 +151,7 @@ void machine_halt(void)
150 local_irq_enable(); 151 local_irq_enable();
151 mdelay(8); 152 mdelay(8);
152 local_irq_disable(); 153 local_irq_disable();
153 if (!serial_console && prom_palette) 154 if (prom_palette)
154 prom_palette (1); 155 prom_palette (1);
155 prom_halt(); 156 prom_halt();
156 panic("Halt failed!"); 157 panic("Halt failed!");
@@ -166,7 +167,7 @@ void machine_restart(char * cmd)
166 167
167 p = strchr (reboot_command, '\n'); 168 p = strchr (reboot_command, '\n');
168 if (p) *p = 0; 169 if (p) *p = 0;
169 if (!serial_console && prom_palette) 170 if (prom_palette)
170 prom_palette (1); 171 prom_palette (1);
171 if (cmd) 172 if (cmd)
172 prom_reboot(cmd); 173 prom_reboot(cmd);
@@ -179,7 +180,8 @@ void machine_restart(char * cmd)
179void machine_power_off(void) 180void machine_power_off(void)
180{ 181{
181#ifdef CONFIG_SUN_AUXIO 182#ifdef CONFIG_SUN_AUXIO
182 if (auxio_power_register && (!serial_console || scons_pwroff)) 183 if (auxio_power_register &&
184 (strcmp(of_console_device->type, "serial") || scons_pwroff))
183 *auxio_power_register |= AUXIO_POWER_OFF; 185 *auxio_power_register |= AUXIO_POWER_OFF;
184#endif 186#endif
185 machine_halt(); 187 machine_halt();
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
index 012f98346bcd..e3a537650db1 100644
--- a/arch/sparc/kernel/prom.c
+++ b/arch/sparc/kernel/prom.c
@@ -397,6 +397,135 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl
397 return dp; 397 return dp;
398} 398}
399 399
400struct device_node *of_console_device;
401EXPORT_SYMBOL(of_console_device);
402
403char *of_console_path;
404EXPORT_SYMBOL(of_console_path);
405
406char *of_console_options;
407EXPORT_SYMBOL(of_console_options);
408
409extern void restore_current(void);
410
411static void __init of_console_init(void)
412{
413 char *msg = "OF stdout device is: %s\n";
414 struct device_node *dp;
415 unsigned long flags;
416 const char *type;
417 phandle node;
418 int skip, fd;
419
420 of_console_path = prom_early_alloc(256);
421
422 switch (prom_vers) {
423 case PROM_V0:
424 case PROM_SUN4:
425 skip = 0;
426 switch (*romvec->pv_stdout) {
427 case PROMDEV_SCREEN:
428 type = "display";
429 break;
430
431 case PROMDEV_TTYB:
432 skip = 1;
433 /* FALLTHRU */
434
435 case PROMDEV_TTYA:
436 type = "serial";
437 break;
438
439 default:
440 prom_printf("Invalid PROM_V0 stdout value %u\n",
441 *romvec->pv_stdout);
442 prom_halt();
443 }
444
445 for_each_node_by_type(dp, type) {
446 if (!skip--)
447 break;
448 }
449 if (!dp) {
450 prom_printf("Cannot find PROM_V0 console node.\n");
451 prom_halt();
452 }
453 of_console_device = dp;
454
455 strcpy(of_console_path, dp->full_name);
456 if (!strcmp(type, "serial")) {
457 strcat(of_console_path,
458 (skip ? ":b" : ":a"));
459 }
460 break;
461
462 default:
463 case PROM_V2:
464 case PROM_V3:
465 fd = *romvec->pv_v2bootargs.fd_stdout;
466
467 spin_lock_irqsave(&prom_lock, flags);
468 node = (*romvec->pv_v2devops.v2_inst2pkg)(fd);
469 restore_current();
470 spin_unlock_irqrestore(&prom_lock, flags);
471
472 if (!node) {
473 prom_printf("Cannot resolve stdout node from "
474 "instance %08x.\n", fd);
475 prom_halt();
476 }
477 dp = of_find_node_by_phandle(node);
478 type = of_get_property(dp, "device_type", NULL);
479
480 if (!type) {
481 prom_printf("Console stdout lacks "
482 "device_type property.\n");
483 prom_halt();
484 }
485
486 if (strcmp(type, "display") && strcmp(type, "serial")) {
487 prom_printf("Console device_type is neither display "
488 "nor serial.\n");
489 prom_halt();
490 }
491
492 of_console_device = dp;
493
494 if (prom_vers == PROM_V2) {
495 strcpy(of_console_path, dp->full_name);
496 switch (*romvec->pv_stdout) {
497 case PROMDEV_TTYA:
498 strcat(of_console_path, ":a");
499 break;
500 case PROMDEV_TTYB:
501 strcat(of_console_path, ":b");
502 break;
503 }
504 } else {
505 const char *path;
506
507 dp = of_find_node_by_path("/");
508 path = of_get_property(dp, "stdout-path", NULL);
509 if (!path) {
510 prom_printf("No stdout-path in root node.\n");
511 prom_halt();
512 }
513 strcpy(of_console_path, path);
514 }
515 break;
516 }
517
518 of_console_options = strrchr(of_console_path, ':');
519 if (of_console_options) {
520 of_console_options++;
521 if (*of_console_options == '\0')
522 of_console_options = NULL;
523 }
524
525 prom_printf(msg, of_console_path);
526 printk(msg, of_console_path);
527}
528
400void __init prom_build_devicetree(void) 529void __init prom_build_devicetree(void)
401{ 530{
402 struct device_node **nextp; 531 struct device_node **nextp;
@@ -409,6 +538,8 @@ void __init prom_build_devicetree(void)
409 allnodes->child = build_tree(allnodes, 538 allnodes->child = build_tree(allnodes,
410 prom_getchild(allnodes->node), 539 prom_getchild(allnodes->node),
411 &nextp); 540 &nextp);
541 of_console_init();
542
412 printk("PROM: Built device tree with %u bytes of memory.\n", 543 printk("PROM: Built device tree with %u bytes of memory.\n",
413 prom_early_allocated); 544 prom_early_allocated);
414} 545}
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 64c0ed98820a..f8228383895a 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -146,31 +146,6 @@ static void __init process_switch(char c)
146 } 146 }
147} 147}
148 148
149static void __init process_console(char *commands)
150{
151 serial_console = 0;
152 commands += 8;
153 /* Linux-style serial */
154 if (!strncmp(commands, "ttyS", 4))
155 serial_console = simple_strtoul(commands + 4, NULL, 10) + 1;
156 else if (!strncmp(commands, "tty", 3)) {
157 char c = *(commands + 3);
158 /* Solaris-style serial */
159 if (c == 'a' || c == 'b')
160 serial_console = c - 'a' + 1;
161 /* else Linux-style fbcon, not serial */
162 }
163#if defined(CONFIG_PROM_CONSOLE)
164 if (!strncmp(commands, "prom", 4)) {
165 char *p;
166
167 for (p = commands - 8; *p && *p != ' '; p++)
168 *p = ' ';
169 conswitchp = &prom_con;
170 }
171#endif
172}
173
174static void __init boot_flags_init(char *commands) 149static void __init boot_flags_init(char *commands)
175{ 150{
176 while (*commands) { 151 while (*commands) {
@@ -187,9 +162,7 @@ static void __init boot_flags_init(char *commands)
187 process_switch(*commands++); 162 process_switch(*commands++);
188 continue; 163 continue;
189 } 164 }
190 if (!strncmp(commands, "console=", 8)) { 165 if (!strncmp(commands, "mem=", 4)) {
191 process_console(commands);
192 } else if (!strncmp(commands, "mem=", 4)) {
193 /* 166 /*
194 * "mem=XXX[kKmM] overrides the PROM-reported 167 * "mem=XXX[kKmM] overrides the PROM-reported
195 * memory size. 168 * memory size.
@@ -341,41 +314,6 @@ void __init setup_arch(char **cmdline_p)
341 smp_setup_cpu_possible_map(); 314 smp_setup_cpu_possible_map();
342} 315}
343 316
344static int __init set_preferred_console(void)
345{
346 int idev, odev;
347
348 /* The user has requested a console so this is already set up. */
349 if (serial_console >= 0)
350 return -EBUSY;
351
352 idev = prom_query_input_device();
353 odev = prom_query_output_device();
354 if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
355 serial_console = 0;
356 } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
357 serial_console = 1;
358 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
359 serial_console = 2;
360 } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) {
361 prom_printf("MrCoffee ttya\n");
362 serial_console = 1;
363 } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) {
364 serial_console = 0;
365 prom_printf("MrCoffee keyboard\n");
366 } else {
367 prom_printf("Confusing console (idev %d, odev %d)\n",
368 idev, odev);
369 serial_console = 1;
370 }
371
372 if (serial_console)
373 return add_preferred_console("ttyS", serial_console - 1, NULL);
374
375 return -ENODEV;
376}
377console_initcall(set_preferred_console);
378
379extern char *sparc_cpu_type; 317extern char *sparc_cpu_type;
380extern char *sparc_fpu_type; 318extern char *sparc_fpu_type;
381 319
@@ -461,7 +399,6 @@ void sun_do_break(void)
461 prom_cmdline(); 399 prom_cmdline();
462} 400}
463 401
464int serial_console = -1;
465int stop_a_enabled = 1; 402int stop_a_enabled = 1;
466 403
467static int __init topology_init(void) 404static int __init topology_init(void)
diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c
index 4e6e41d3291d..8d1cfb0d5068 100644
--- a/arch/sparc/prom/console.c
+++ b/arch/sparc/prom/console.c
@@ -102,119 +102,3 @@ prom_putchar(char c)
102 while(prom_nbputchar(c) == -1) ; 102 while(prom_nbputchar(c) == -1) ;
103 return; 103 return;
104} 104}
105
106/* Query for input device type */
107enum prom_input_device
108prom_query_input_device(void)
109{
110 unsigned long flags;
111 int st_p;
112 char propb[64];
113 char *p;
114 int propl;
115
116 switch(prom_vers) {
117 case PROM_V0:
118 case PROM_V2:
119 case PROM_SUN4:
120 default:
121 switch(*romvec->pv_stdin) {
122 case PROMDEV_KBD: return PROMDEV_IKBD;
123 case PROMDEV_TTYA: return PROMDEV_ITTYA;
124 case PROMDEV_TTYB: return PROMDEV_ITTYB;
125 default:
126 return PROMDEV_I_UNK;
127 };
128 case PROM_V3:
129 spin_lock_irqsave(&prom_lock, flags);
130 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
131 restore_current();
132 spin_unlock_irqrestore(&prom_lock, flags);
133 if(prom_node_has_property(st_p, "keyboard"))
134 return PROMDEV_IKBD;
135 if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
136 if(strncmp(propb, "keyboard", sizeof("serial")) == 0)
137 return PROMDEV_IKBD;
138 }
139 if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) {
140 if(strncmp(propb, "serial", sizeof("serial")))
141 return PROMDEV_I_UNK;
142 }
143 propl = prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
144 if(propl > 2) {
145 p = propb;
146 while(*p) p++; p -= 2;
147 if(p[0] == ':') {
148 if(p[1] == 'a')
149 return PROMDEV_ITTYA;
150 else if(p[1] == 'b')
151 return PROMDEV_ITTYB;
152 }
153 }
154 return PROMDEV_I_UNK;
155 }
156}
157
158/* Query for output device type */
159
160enum prom_output_device
161prom_query_output_device(void)
162{
163 unsigned long flags;
164 int st_p;
165 char propb[64];
166 char *p;
167 int propl;
168
169 switch(prom_vers) {
170 case PROM_V0:
171 case PROM_SUN4:
172 switch(*romvec->pv_stdin) {
173 case PROMDEV_SCREEN: return PROMDEV_OSCREEN;
174 case PROMDEV_TTYA: return PROMDEV_OTTYA;
175 case PROMDEV_TTYB: return PROMDEV_OTTYB;
176 };
177 break;
178 case PROM_V2:
179 case PROM_V3:
180 spin_lock_irqsave(&prom_lock, flags);
181 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
182 restore_current();
183 spin_unlock_irqrestore(&prom_lock, flags);
184 propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
185 if (propl == sizeof("display") &&
186 strncmp("display", propb, sizeof("display")) == 0)
187 {
188 return PROMDEV_OSCREEN;
189 }
190 if(prom_vers == PROM_V3) {
191 if(propl >= 0 &&
192 strncmp("serial", propb, sizeof("serial")) != 0)
193 return PROMDEV_O_UNK;
194 propl = prom_getproperty(prom_root_node, "stdout-path",
195 propb, sizeof(propb));
196 if(propl == CON_SIZE_JMC &&
197 strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
198 return PROMDEV_OTTYA;
199 if(propl > 2) {
200 p = propb;
201 while(*p) p++; p-= 2;
202 if(p[0]==':') {
203 if(p[1] == 'a')
204 return PROMDEV_OTTYA;
205 else if(p[1] == 'b')
206 return PROMDEV_OTTYB;
207 }
208 }
209 } else {
210 switch(*romvec->pv_stdin) {
211 case PROMDEV_TTYA: return PROMDEV_OTTYA;
212 case PROMDEV_TTYB: return PROMDEV_OTTYB;
213 };
214 }
215 break;
216 default:
217 ;
218 };
219 return PROMDEV_O_UNK;
220}
diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
index 1942c7c05cb1..37cff5f54704 100644
--- a/arch/sparc/prom/misc.c
+++ b/arch/sparc/prom/misc.c
@@ -58,7 +58,7 @@ prom_cmdline(void)
58 extern void install_linux_ticker(void); 58 extern void install_linux_ticker(void);
59 unsigned long flags; 59 unsigned long flags;
60 60
61 if(!serial_console && prom_palette) 61 if (prom_palette)
62 prom_palette (1); 62 prom_palette (1);
63 spin_lock_irqsave(&prom_lock, flags); 63 spin_lock_irqsave(&prom_lock, flags);
64 install_obp_ticker(); 64 install_obp_ticker();
@@ -69,7 +69,7 @@ prom_cmdline(void)
69#ifdef CONFIG_SUN_AUXIO 69#ifdef CONFIG_SUN_AUXIO
70 set_auxio(AUXIO_LED, 0); 70 set_auxio(AUXIO_LED, 0);
71#endif 71#endif
72 if(!serial_console && prom_palette) 72 if (prom_palette)
73 prom_palette (0); 73 prom_palette (0);
74} 74}
75 75
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index b00feb01c16f..881a09ee4c4c 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -46,7 +46,7 @@ static void (*poweroff_method)(void) = machine_alt_power_off;
46void machine_power_off(void) 46void machine_power_off(void)
47{ 47{
48 sstate_poweroff(); 48 sstate_poweroff();
49 if (!serial_console || scons_pwroff) { 49 if (strcmp(of_console_device->type, "serial") || scons_pwroff) {
50 if (power_reg) { 50 if (power_reg) {
51 /* Both register bits seem to have the 51 /* Both register bits seem to have the
52 * same effect, so until I figure out 52 * same effect, so until I figure out
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 93557507ec9f..fd7899ba1d70 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -119,7 +119,7 @@ extern void (*prom_keyboard)(void);
119void machine_halt(void) 119void machine_halt(void)
120{ 120{
121 sstate_halt(); 121 sstate_halt();
122 if (!serial_console && prom_palette) 122 if (prom_palette)
123 prom_palette (1); 123 prom_palette (1);
124 if (prom_keyboard) 124 if (prom_keyboard)
125 prom_keyboard(); 125 prom_keyboard();
@@ -130,7 +130,7 @@ void machine_halt(void)
130void machine_alt_power_off(void) 130void machine_alt_power_off(void)
131{ 131{
132 sstate_poweroff(); 132 sstate_poweroff();
133 if (!serial_console && prom_palette) 133 if (prom_palette)
134 prom_palette(1); 134 prom_palette(1);
135 if (prom_keyboard) 135 if (prom_keyboard)
136 prom_keyboard(); 136 prom_keyboard();
@@ -145,7 +145,7 @@ void machine_restart(char * cmd)
145 sstate_reboot(); 145 sstate_reboot();
146 p = strchr (reboot_command, '\n'); 146 p = strchr (reboot_command, '\n');
147 if (p) *p = 0; 147 if (p) *p = 0;
148 if (!serial_console && prom_palette) 148 if (prom_palette)
149 prom_palette (1); 149 prom_palette (1);
150 if (prom_keyboard) 150 if (prom_keyboard)
151 prom_keyboard(); 151 prom_keyboard();
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 2b2017ce2267..f4e0a9ad9be3 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -1646,6 +1646,60 @@ static void __init of_fill_in_cpu_data(void)
1646 smp_fill_in_sib_core_maps(); 1646 smp_fill_in_sib_core_maps();
1647} 1647}
1648 1648
1649struct device_node *of_console_device;
1650EXPORT_SYMBOL(of_console_device);
1651
1652char *of_console_path;
1653EXPORT_SYMBOL(of_console_path);
1654
1655char *of_console_options;
1656EXPORT_SYMBOL(of_console_options);
1657
1658static void __init of_console_init(void)
1659{
1660 char *msg = "OF stdout device is: %s\n";
1661 struct device_node *dp;
1662 const char *type;
1663 phandle node;
1664
1665 of_console_path = prom_early_alloc(256);
1666 if (prom_ihandle2path(prom_stdout, of_console_path, 256) < 0) {
1667 prom_printf("Cannot obtain path of stdout.\n");
1668 prom_halt();
1669 }
1670 of_console_options = strrchr(of_console_path, ':');
1671 if (of_console_options) {
1672 of_console_options++;
1673 if (*of_console_options == '\0')
1674 of_console_options = NULL;
1675 }
1676
1677 node = prom_inst2pkg(prom_stdout);
1678 if (!node) {
1679 prom_printf("Cannot resolve stdout node from "
1680 "instance %08x.\n", prom_stdout);
1681 prom_halt();
1682 }
1683
1684 dp = of_find_node_by_phandle(node);
1685 type = of_get_property(dp, "device_type", NULL);
1686 if (!type) {
1687 prom_printf("Console stdout lacks device_type property.\n");
1688 prom_halt();
1689 }
1690
1691 if (strcmp(type, "display") && strcmp(type, "serial")) {
1692 prom_printf("Console device_type is neither display "
1693 "nor serial.\n");
1694 prom_halt();
1695 }
1696
1697 of_console_device = dp;
1698
1699 prom_printf(msg, of_console_path);
1700 printk(msg, of_console_path);
1701}
1702
1649void __init prom_build_devicetree(void) 1703void __init prom_build_devicetree(void)
1650{ 1704{
1651 struct device_node **nextp; 1705 struct device_node **nextp;
@@ -1658,6 +1712,8 @@ void __init prom_build_devicetree(void)
1658 allnodes->child = build_tree(allnodes, 1712 allnodes->child = build_tree(allnodes,
1659 prom_getchild(allnodes->node), 1713 prom_getchild(allnodes->node),
1660 &nextp); 1714 &nextp);
1715 of_console_init();
1716
1661 printk("PROM: Built device tree with %u bytes of memory.\n", 1717 printk("PROM: Built device tree with %u bytes of memory.\n",
1662 prom_early_allocated); 1718 prom_early_allocated);
1663 1719
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index aafde3dd9fd4..0f5be828ee92 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -133,33 +133,6 @@ static void __init process_switch(char c)
133 } 133 }
134} 134}
135 135
136static void __init process_console(char *commands)
137{
138 serial_console = 0;
139 commands += 8;
140 /* Linux-style serial */
141 if (!strncmp(commands, "ttyS", 4))
142 serial_console = simple_strtoul(commands + 4, NULL, 10) + 1;
143 else if (!strncmp(commands, "tty", 3)) {
144 char c = *(commands + 3);
145 /* Solaris-style serial */
146 if (c == 'a' || c == 'b') {
147 serial_console = c - 'a' + 1;
148 prom_printf ("Using /dev/tty%c as console.\n", c);
149 }
150 /* else Linux-style fbcon, not serial */
151 }
152#if defined(CONFIG_PROM_CONSOLE)
153 if (!strncmp(commands, "prom", 4)) {
154 char *p;
155
156 for (p = commands - 8; *p && *p != ' '; p++)
157 *p = ' ';
158 conswitchp = &prom_con;
159 }
160#endif
161}
162
163static void __init boot_flags_init(char *commands) 136static void __init boot_flags_init(char *commands)
164{ 137{
165 while (*commands) { 138 while (*commands) {
@@ -176,9 +149,7 @@ static void __init boot_flags_init(char *commands)
176 process_switch(*commands++); 149 process_switch(*commands++);
177 continue; 150 continue;
178 } 151 }
179 if (!strncmp(commands, "console=", 8)) { 152 if (!strncmp(commands, "mem=", 4)) {
180 process_console(commands);
181 } else if (!strncmp(commands, "mem=", 4)) {
182 /* 153 /*
183 * "mem=XXX[kKmM]" overrides the PROM-reported 154 * "mem=XXX[kKmM]" overrides the PROM-reported
184 * memory size. 155 * memory size.
@@ -378,44 +349,6 @@ void __init setup_arch(char **cmdline_p)
378 paging_init(); 349 paging_init();
379} 350}
380 351
381static int __init set_preferred_console(void)
382{
383 int idev, odev;
384
385 /* The user has requested a console so this is already set up. */
386 if (serial_console >= 0)
387 return -EBUSY;
388
389 idev = prom_query_input_device();
390 odev = prom_query_output_device();
391 if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
392 serial_console = 0;
393 } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
394 serial_console = 1;
395 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
396 serial_console = 2;
397 } else if (idev == PROMDEV_IRSC && odev == PROMDEV_ORSC) {
398 serial_console = 3;
399 } else if (idev == PROMDEV_IVCONS && odev == PROMDEV_OVCONS) {
400 /* sunhv_console_init() doesn't check the serial_console
401 * value anyways...
402 */
403 serial_console = 4;
404 return add_preferred_console("ttyHV", 0, NULL);
405 } else {
406 prom_printf("Inconsistent console: "
407 "input %d, output %d\n",
408 idev, odev);
409 prom_halt();
410 }
411
412 if (serial_console)
413 return add_preferred_console("ttyS", serial_console - 1, NULL);
414
415 return -ENODEV;
416}
417console_initcall(set_preferred_console);
418
419/* BUFFER is PAGE_SIZE bytes long. */ 352/* BUFFER is PAGE_SIZE bytes long. */
420 353
421extern char *sparc_cpu_type; 354extern char *sparc_cpu_type;
@@ -508,5 +441,4 @@ void sun_do_break(void)
508 prom_cmdline(); 441 prom_cmdline();
509} 442}
510 443
511int serial_console = -1;
512int stop_a_enabled = 1; 444int stop_a_enabled = 1;
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 719d676c2ddc..7d36531aa5b9 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -330,7 +330,6 @@ EXPORT_SYMBOL(VISenter);
330 330
331/* for input/keybdev */ 331/* for input/keybdev */
332EXPORT_SYMBOL(sun_do_break); 332EXPORT_SYMBOL(sun_do_break);
333EXPORT_SYMBOL(serial_console);
334EXPORT_SYMBOL(stop_a_enabled); 333EXPORT_SYMBOL(stop_a_enabled);
335 334
336#ifdef CONFIG_DEBUG_BUGVERBOSE 335#ifdef CONFIG_DEBUG_BUGVERBOSE
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c
index 7c25c54cefdc..3fafa9a8b50b 100644
--- a/arch/sparc64/prom/console.c
+++ b/arch/sparc64/prom/console.c
@@ -73,88 +73,3 @@ prom_puts(const char *s, int len)
73 P1275_INOUT(3,1), 73 P1275_INOUT(3,1),
74 prom_stdout, s, P1275_SIZE(len)); 74 prom_stdout, s, P1275_SIZE(len));
75} 75}
76
77/* Query for input device type */
78enum prom_input_device
79prom_query_input_device(void)
80{
81 int st_p;
82 char propb[64];
83
84 st_p = prom_inst2pkg(prom_stdin);
85 if(prom_node_has_property(st_p, "keyboard"))
86 return PROMDEV_IKBD;
87 prom_getproperty(st_p, "device_type", propb, sizeof(propb));
88 if(strncmp(propb, "serial", 6))
89 return PROMDEV_I_UNK;
90 /* FIXME: Is there any better way how to find out? */
91 memset(propb, 0, sizeof(propb));
92 st_p = prom_finddevice ("/options");
93 prom_getproperty(st_p, "input-device", propb, sizeof(propb));
94
95 /*
96 * If we get here with propb == 'keyboard', we are on ttya, as
97 * the PROM defaulted to this due to 'no input device'.
98 */
99 if (!strncmp(propb, "keyboard", 8))
100 return PROMDEV_ITTYA;
101
102 if (!strncmp (propb, "rsc", 3))
103 return PROMDEV_IRSC;
104
105 if (!strncmp (propb, "virtual-console", 3))
106 return PROMDEV_IVCONS;
107
108 if (strncmp (propb, "tty", 3) || !propb[3])
109 return PROMDEV_I_UNK;
110
111 switch (propb[3]) {
112 case 'a': return PROMDEV_ITTYA;
113 case 'b': return PROMDEV_ITTYB;
114 default: return PROMDEV_I_UNK;
115 }
116}
117
118/* Query for output device type */
119
120enum prom_output_device
121prom_query_output_device(void)
122{
123 int st_p;
124 char propb[64];
125 int propl;
126
127 st_p = prom_inst2pkg(prom_stdout);
128 propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
129 if (propl >= 0 && propl == sizeof("display") &&
130 strncmp("display", propb, sizeof("display")) == 0)
131 return PROMDEV_OSCREEN;
132 if(strncmp("serial", propb, 6))
133 return PROMDEV_O_UNK;
134 /* FIXME: Is there any better way how to find out? */
135 memset(propb, 0, sizeof(propb));
136 st_p = prom_finddevice ("/options");
137 prom_getproperty(st_p, "output-device", propb, sizeof(propb));
138
139 /*
140 * If we get here with propb == 'screen', we are on ttya, as
141 * the PROM defaulted to this due to 'no input device'.
142 */
143 if (!strncmp(propb, "screen", 6))
144 return PROMDEV_OTTYA;
145
146 if (!strncmp (propb, "rsc", 3))
147 return PROMDEV_ORSC;
148
149 if (!strncmp (propb, "virtual-console", 3))
150 return PROMDEV_OVCONS;
151
152 if (strncmp (propb, "tty", 3) || !propb[3])
153 return PROMDEV_O_UNK;
154
155 switch (propb[3]) {
156 case 'a': return PROMDEV_OTTYA;
157 case 'b': return PROMDEV_OTTYB;
158 default: return PROMDEV_O_UNK;
159 }
160}
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
index 33c5b7da31e5..68c83ad04ad9 100644
--- a/arch/sparc64/prom/misc.c
+++ b/arch/sparc64/prom/misc.c
@@ -72,7 +72,7 @@ void prom_cmdline(void)
72 72
73 local_irq_save(flags); 73 local_irq_save(flags);
74 74
75 if (!serial_console && prom_palette) 75 if (prom_palette)
76 prom_palette(1); 76 prom_palette(1);
77 77
78#ifdef CONFIG_SMP 78#ifdef CONFIG_SMP
@@ -85,7 +85,7 @@ void prom_cmdline(void)
85 smp_release(); 85 smp_release();
86#endif 86#endif
87 87
88 if (!serial_console && prom_palette) 88 if (prom_palette)
89 prom_palette(0); 89 prom_palette(0);
90 90
91 local_irq_restore(flags); 91 local_irq_restore(flags);
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c
index 17b7ecfe7ca9..b2c5b12c9818 100644
--- a/arch/sparc64/prom/tree.c
+++ b/arch/sparc64/prom/tree.c
@@ -304,3 +304,11 @@ prom_pathtoinode(const char *path)
304 if (node == -1) return 0; 304 if (node == -1) return 0;
305 return node; 305 return node;
306} 306}
307
308int prom_ihandle2path(int handle, char *buffer, int bufsize)
309{
310 return p1275_cmd("instance-to-path",
311 P1275_ARG(1,P1275_ARG_OUT_BUF)|
312 P1275_INOUT(3, 1),
313 handle, buffer, P1275_SIZE(bufsize));
314}