diff options
-rw-r--r-- | arch/sparc64/kernel/central.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 33 | ||||
-rw-r--r-- | arch/sparc64/kernel/prom.c | 30 |
3 files changed, 43 insertions, 24 deletions
diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c index b66336db00ee..e724c54af029 100644 --- a/arch/sparc64/kernel/central.c +++ b/arch/sparc64/kernel/central.c | |||
@@ -126,6 +126,10 @@ static void probe_other_fhcs(void) | |||
126 | int board; | 126 | int board; |
127 | u32 tmp; | 127 | u32 tmp; |
128 | 128 | ||
129 | if (dp->parent && | ||
130 | dp->parent->parent != NULL) | ||
131 | continue; | ||
132 | |||
129 | fhc = (struct linux_fhc *) | 133 | fhc = (struct linux_fhc *) |
130 | central_alloc_bootmem(sizeof(struct linux_fhc)); | 134 | central_alloc_bootmem(sizeof(struct linux_fhc)); |
131 | if (fhc == NULL) | 135 | if (fhc == NULL) |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index d3dfb2a36d47..983ca5f485cf 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -402,16 +402,22 @@ static void of_bus_sbus_count_cells(struct device_node *child, | |||
402 | *sizec = 1; | 402 | *sizec = 1; |
403 | } | 403 | } |
404 | 404 | ||
405 | static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) | 405 | /* |
406 | { | 406 | * FHC/Central bus specific translator. |
407 | return of_bus_default_map(addr, range, na, ns, pna); | 407 | * |
408 | } | 408 | * This is just needed to hard-code the address and size cell |
409 | 409 | * counts. 'fhc' and 'central' nodes lack the #address-cells and | |
410 | static unsigned int of_bus_sbus_get_flags(u32 *addr) | 410 | * #size-cells properties, and if you walk to the root on such |
411 | * Enterprise boxes all you'll get is a #size-cells of 2 which is | ||
412 | * not what we want to use. | ||
413 | */ | ||
414 | static int of_bus_fhc_match(struct device_node *np) | ||
411 | { | 415 | { |
412 | return IORESOURCE_MEM; | 416 | return !strcmp(np->name, "fhc") || |
417 | !strcmp(np->name, "central"); | ||
413 | } | 418 | } |
414 | 419 | ||
420 | #define of_bus_fhc_count_cells of_bus_sbus_count_cells | ||
415 | 421 | ||
416 | /* | 422 | /* |
417 | * Array of bus specific translators | 423 | * Array of bus specific translators |
@@ -433,8 +439,17 @@ static struct of_bus of_busses[] = { | |||
433 | .addr_prop_name = "reg", | 439 | .addr_prop_name = "reg", |
434 | .match = of_bus_sbus_match, | 440 | .match = of_bus_sbus_match, |
435 | .count_cells = of_bus_sbus_count_cells, | 441 | .count_cells = of_bus_sbus_count_cells, |
436 | .map = of_bus_sbus_map, | 442 | .map = of_bus_default_map, |
437 | .get_flags = of_bus_sbus_get_flags, | 443 | .get_flags = of_bus_default_get_flags, |
444 | }, | ||
445 | /* FHC */ | ||
446 | { | ||
447 | .name = "fhc", | ||
448 | .addr_prop_name = "reg", | ||
449 | .match = of_bus_fhc_match, | ||
450 | .count_cells = of_bus_fhc_count_cells, | ||
451 | .map = of_bus_default_map, | ||
452 | .get_flags = of_bus_default_get_flags, | ||
438 | }, | 453 | }, |
439 | /* Default */ | 454 | /* Default */ |
440 | { | 455 | { |
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 | ||
1080 | static void irq_trans_init(struct device_node *dp) | 1080 | static 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 | ||
1519 | static struct device_node * __init create_node(phandle node) | 1519 | static 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 | ||