aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/prom.c
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/sparc64/kernel/prom.c
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/sparc64/kernel/prom.c')
-rw-r--r--arch/sparc64/kernel/prom.c56
1 files changed, 56 insertions, 0 deletions
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