diff options
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/process.c | 8 | ||||
-rw-r--r-- | arch/sparc/kernel/prom.c | 131 | ||||
-rw-r--r-- | arch/sparc/kernel/setup.c | 65 |
3 files changed, 137 insertions, 67 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) | |||
179 | void machine_power_off(void) | 180 | void 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 | ||
400 | struct device_node *of_console_device; | ||
401 | EXPORT_SYMBOL(of_console_device); | ||
402 | |||
403 | char *of_console_path; | ||
404 | EXPORT_SYMBOL(of_console_path); | ||
405 | |||
406 | char *of_console_options; | ||
407 | EXPORT_SYMBOL(of_console_options); | ||
408 | |||
409 | extern void restore_current(void); | ||
410 | |||
411 | static 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 | |||
400 | void __init prom_build_devicetree(void) | 529 | void __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 | ||
149 | static 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 | |||
174 | static void __init boot_flags_init(char *commands) | 149 | static 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 | ||
344 | static 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 | } | ||
377 | console_initcall(set_preferred_console); | ||
378 | |||
379 | extern char *sparc_cpu_type; | 317 | extern char *sparc_cpu_type; |
380 | extern char *sparc_fpu_type; | 318 | extern 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 | ||
464 | int serial_console = -1; | ||
465 | int stop_a_enabled = 1; | 402 | int stop_a_enabled = 1; |
466 | 403 | ||
467 | static int __init topology_init(void) | 404 | static int __init topology_init(void) |