Subject: powerpc: MPIC init get address from From: Benjamin Herrenschmidt This patch applies on top of the MPIC DCR support. It makes the MPIC driver capable of a lot more auto-configuration based on the device-tree, for example, it can retreive it's own physical address if not passed as an argument, find out if it's DCR or MMIO mapped, and set the BIG_ENDIAN flag automatically in the presence of a "big-endian" property in the device-tree node. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Arnd Bergmann Index: linux-2.6/arch/powerpc/sysdev/mpic.c =================================================================== --- linux-2.6.orig/arch/powerpc/sysdev/mpic.c +++ linux-2.6/arch/powerpc/sysdev/mpic.c @@ -943,6 +943,11 @@ struct mpic * __init mpic_alloc(struct d mpic->irq_count = irq_count; mpic->num_sources = 0; /* so far */ + /* Check for "big-endian" in device-tree */ + if (node && get_property(node, "big-endian", NULL) != NULL) + mpic->flags |= MPIC_BIG_ENDIAN; + + #ifdef CONFIG_MPIC_WEIRD mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; #endif @@ -951,11 +956,17 @@ struct mpic * __init mpic_alloc(struct d mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ? mpic_access_mmio_be : mpic_access_mmio_le; + /* If no physical address is passed in, a device-node is mandatory */ + BUG_ON(phys_addr == 0 && node == NULL); + + /* If no physical address passed in, check if it's dcr based */ + if (phys_addr == 0 && get_property(node, "dcr-reg", NULL) != NULL) + mpic->flags |= MPIC_USES_DCR; + #ifdef CONFIG_PPC_DCR if (mpic->flags & MPIC_USES_DCR) { const u32 *dbasep; - BUG_ON(mpic->of_node == NULL); - dbasep = get_property(mpic->of_node, "dcr-reg", NULL); + dbasep = get_property(node, "dcr-reg", NULL); BUG_ON(dbasep == NULL); mpic->dcr_base = *dbasep; mpic->reg_type = mpic_access_dcr; @@ -964,6 +975,17 @@ struct mpic * __init mpic_alloc(struct d BUG_ON (mpic->flags & MPIC_USES_DCR); #endif /* CONFIG_PPC_DCR */ + /* If the MPIC is not DCR based, and no physical address was passed + * in, try to obtain one + */ + if (phys_addr == 0 && !(mpic->flags & MPIC_USES_DCR)) { + const u32 *reg; + reg = get_property(node, "reg", NULL); + BUG_ON(reg == NULL); + phys_addr = of_translate_address(node, reg); + BUG_ON(phys_addr == OF_BAD_ADDR); + } + /* Map the global registers */ mpic_map(mpic, phys_addr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); mpic_map(mpic, phys_addr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);