aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/prom.c')
-rw-r--r--arch/sparc/kernel/prom.c131
1 files changed, 131 insertions, 0 deletions
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}