diff options
Diffstat (limited to 'arch/sparc64/kernel/prom.c')
-rw-r--r-- | arch/sparc64/kernel/prom.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index e21cd6afa70..0917c24c4f0 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -793,7 +793,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, return virt_irq; } -static void schizo_irq_trans_init(struct device_node *dp) +static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) { struct linux_prom64_registers *regs; struct schizo_irq_data *irq_data; @@ -807,11 +807,24 @@ static void schizo_irq_trans_init(struct device_node *dp) dp->irq_trans->data = irq_data; irq_data->pbm_regs = regs[0].phys_addr; - irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; + if (is_tomatillo) + irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; + else + irq_data->sync_reg = 0UL; irq_data->portid = of_getintprop_default(dp, "portid", 0); irq_data->chip_version = of_getintprop_default(dp, "version#", 0); } +static void schizo_irq_trans_init(struct device_node *dp) +{ + __schizo_irq_trans_init(dp, 0); +} + +static void tomatillo_irq_trans_init(struct device_node *dp) +{ + __schizo_irq_trans_init(dp, 1); +} + static unsigned int pci_sun4v_irq_build(struct device_node *dp, unsigned int devino, void *_data) @@ -1050,8 +1063,8 @@ static struct irq_trans pci_irq_trans_table[] = { { "pci108e,8001", schizo_irq_trans_init }, { "SUNW,schizo+", schizo_irq_trans_init }, { "pci108e,8002", schizo_irq_trans_init }, - { "SUNW,tomatillo", schizo_irq_trans_init }, - { "pci108e,a801", schizo_irq_trans_init }, + { "SUNW,tomatillo", tomatillo_irq_trans_init }, + { "pci108e,a801", tomatillo_irq_trans_init }, { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, }; #endif @@ -1079,23 +1092,22 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp) static void irq_trans_init(struct device_node *dp) { - const char *model; #ifdef CONFIG_PCI + const char *model; int i; #endif +#ifdef CONFIG_PCI model = of_get_property(dp, "model", NULL); if (!model) model = of_get_property(dp, "compatible", NULL); - if (!model) - return; - -#ifdef CONFIG_PCI - for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) { - struct irq_trans *t = &pci_irq_trans_table[i]; + if (model) { + for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) { + struct irq_trans *t = &pci_irq_trans_table[i]; - if (!strcmp(model, t->name)) - return t->init(dp); + if (!strcmp(model, t->name)) + return t->init(dp); + } } #endif #ifdef CONFIG_SBUS @@ -1103,8 +1115,9 @@ static void irq_trans_init(struct device_node *dp) !strcmp(dp->name, "sbi")) return sbus_irq_trans_init(dp); #endif - if (!strcmp(dp->name, "central")) - return central_irq_trans_init(dp->child); + if (!strcmp(dp->name, "fhc") && + !strcmp(dp->parent->name, "central")) + return central_irq_trans_init(dp); if (!strcmp(dp->name, "virtual-devices")) return sun4v_vdev_irq_trans_init(dp); } @@ -1516,7 +1529,7 @@ static char * __init get_one_property(phandle node, const char *name) return buf; } -static struct device_node * __init create_node(phandle node) +static struct device_node * __init create_node(phandle node, struct device_node *parent) { struct device_node *dp; @@ -1525,6 +1538,7 @@ static struct device_node * __init create_node(phandle node) dp = prom_early_alloc(sizeof(*dp)); dp->unique_id = unique_id++; + dp->parent = parent; kref_init(&dp->kref); @@ -1543,12 +1557,11 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl { struct device_node *dp; - dp = create_node(node); + dp = create_node(node, parent); if (dp) { *(*nextp) = dp; *nextp = &dp->allnext; - dp->parent = parent; dp->path_component_name = build_path_component(dp); dp->full_name = build_full_name(dp); @@ -1564,7 +1577,7 @@ void __init prom_build_devicetree(void) { struct device_node **nextp; - allnodes = create_node(prom_root_node); + allnodes = create_node(prom_root_node, NULL); allnodes->path_component_name = ""; allnodes->full_name = "/"; |