aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/prom.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-10-26 01:31:06 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-10-26 01:39:15 -0400
commit4130a4b206e7c628482aa12ec30949382c8cdc5e (patch)
treebae99205682ec6db943fc8271dddc980646254d8 /arch/sparc64/kernel/prom.c
parent291b58d663862c3d42d2e8092f8b0dd3f15a94f8 (diff)
[SPARC64]: Fix central/FHC bus handling on Ex000 systems.
1) probe_other_fhcs() wants to see only non-central FHC busses, so skip FHCs that don't sit off the root 2) Like SBUS, FHC can lack the appropriate address and size cell count properties, so add an of_busses[] entry and handlers for that. 3) Central FHC irq translator probing was buggy. We were trying to use dp->child in irq_trans_init but that linkage is not setup at this point. So instead, pass in the parent of "dp" and look for the child "fhc" with parent "central". Thanks to the tireless assistence of Ben Collins in tracking down these problems and testing out these fixes. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/prom.c')
-rw-r--r--arch/sparc64/kernel/prom.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index e21cd6afa709..c60efb3cb22e 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -1079,23 +1079,22 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp)
1079 1079
1080static void irq_trans_init(struct device_node *dp) 1080static void irq_trans_init(struct device_node *dp)
1081{ 1081{
1082 const char *model;
1083#ifdef CONFIG_PCI 1082#ifdef CONFIG_PCI
1083 const char *model;
1084 int i; 1084 int i;
1085#endif 1085#endif
1086 1086
1087#ifdef CONFIG_PCI
1087 model = of_get_property(dp, "model", NULL); 1088 model = of_get_property(dp, "model", NULL);
1088 if (!model) 1089 if (!model)
1089 model = of_get_property(dp, "compatible", NULL); 1090 model = of_get_property(dp, "compatible", NULL);
1090 if (!model) 1091 if (model) {
1091 return; 1092 for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
1092 1093 struct irq_trans *t = &pci_irq_trans_table[i];
1093#ifdef CONFIG_PCI
1094 for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
1095 struct irq_trans *t = &pci_irq_trans_table[i];
1096 1094
1097 if (!strcmp(model, t->name)) 1095 if (!strcmp(model, t->name))
1098 return t->init(dp); 1096 return t->init(dp);
1097 }
1099 } 1098 }
1100#endif 1099#endif
1101#ifdef CONFIG_SBUS 1100#ifdef CONFIG_SBUS
@@ -1103,8 +1102,9 @@ static void irq_trans_init(struct device_node *dp)
1103 !strcmp(dp->name, "sbi")) 1102 !strcmp(dp->name, "sbi"))
1104 return sbus_irq_trans_init(dp); 1103 return sbus_irq_trans_init(dp);
1105#endif 1104#endif
1106 if (!strcmp(dp->name, "central")) 1105 if (!strcmp(dp->name, "fhc") &&
1107 return central_irq_trans_init(dp->child); 1106 !strcmp(dp->parent->name, "central"))
1107 return central_irq_trans_init(dp);
1108 if (!strcmp(dp->name, "virtual-devices")) 1108 if (!strcmp(dp->name, "virtual-devices"))
1109 return sun4v_vdev_irq_trans_init(dp); 1109 return sun4v_vdev_irq_trans_init(dp);
1110} 1110}
@@ -1516,7 +1516,7 @@ static char * __init get_one_property(phandle node, const char *name)
1516 return buf; 1516 return buf;
1517} 1517}
1518 1518
1519static struct device_node * __init create_node(phandle node) 1519static struct device_node * __init create_node(phandle node, struct device_node *parent)
1520{ 1520{
1521 struct device_node *dp; 1521 struct device_node *dp;
1522 1522
@@ -1525,6 +1525,7 @@ static struct device_node * __init create_node(phandle node)
1525 1525
1526 dp = prom_early_alloc(sizeof(*dp)); 1526 dp = prom_early_alloc(sizeof(*dp));
1527 dp->unique_id = unique_id++; 1527 dp->unique_id = unique_id++;
1528 dp->parent = parent;
1528 1529
1529 kref_init(&dp->kref); 1530 kref_init(&dp->kref);
1530 1531
@@ -1543,12 +1544,11 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl
1543{ 1544{
1544 struct device_node *dp; 1545 struct device_node *dp;
1545 1546
1546 dp = create_node(node); 1547 dp = create_node(node, parent);
1547 if (dp) { 1548 if (dp) {
1548 *(*nextp) = dp; 1549 *(*nextp) = dp;
1549 *nextp = &dp->allnext; 1550 *nextp = &dp->allnext;
1550 1551
1551 dp->parent = parent;
1552 dp->path_component_name = build_path_component(dp); 1552 dp->path_component_name = build_path_component(dp);
1553 dp->full_name = build_full_name(dp); 1553 dp->full_name = build_full_name(dp);
1554 1554
@@ -1564,7 +1564,7 @@ void __init prom_build_devicetree(void)
1564{ 1564{
1565 struct device_node **nextp; 1565 struct device_node **nextp;
1566 1566
1567 allnodes = create_node(prom_root_node); 1567 allnodes = create_node(prom_root_node, NULL);
1568 allnodes->path_component_name = ""; 1568 allnodes->path_component_name = "";
1569 allnodes->full_name = "/"; 1569 allnodes->full_name = "/";
1570 1570