aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorKyle Moffett <Kyle.D.Moffett@boeing.com>2011-12-02 01:27:59 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-12-06 21:43:06 -0500
commit8bf41568969e003c3d5410124e27bbdce7852e1b (patch)
tree684fee8aa54797e2482afd66b94f9633fcbd5061 /arch/powerpc/sysdev
parent582d3e099413c3741a88bdee9e3ff3cc2f9d3329 (diff)
powerpc: Consolidate mpic_alloc() OF address translation
Instead of using the open-coded "reg" property lookup and address translation in mpic_alloc(), directly call of_address_to_resource(). This includes various workarounds for special cases which the naive of_address_translate() does not. Afterwards it is possible to remove the copiously copy-pasted calls to of_address_translate() from the 85xx/86xx/powermac platforms. Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/mpic.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index b3fa3d7d4ab6..8f24c6e8f535 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1142,7 +1142,24 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1142 const char *vers; 1142 const char *vers;
1143 int i; 1143 int i;
1144 int intvec_top; 1144 int intvec_top;
1145 u64 paddr = phys_addr; 1145
1146 /*
1147 * If no phyiscal address was specified then all of the phyiscal
1148 * addressing parameters must come from the device-tree.
1149 */
1150 if (!phys_addr) {
1151 BUG_ON(!node);
1152
1153 /* Check if it is DCR-based */
1154 if (of_get_property(node, "dcr-reg", NULL)) {
1155 flags |= MPIC_USES_DCR;
1156 } else {
1157 struct resource r;
1158 if (of_address_to_resource(node, 0, &r))
1159 return NULL;
1160 phys_addr = r.start;
1161 }
1162 }
1146 1163
1147 mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL); 1164 mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
1148 if (mpic == NULL) 1165 if (mpic == NULL)
@@ -1224,35 +1241,25 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1224#endif 1241#endif
1225 1242
1226 /* default register type */ 1243 /* default register type */
1227 mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ? 1244 if (flags & MPIC_BIG_ENDIAN)
1228 mpic_access_mmio_be : mpic_access_mmio_le; 1245 mpic->reg_type = mpic_access_mmio_be;
1229 1246 else
1230 /* If no physical address is passed in, a device-node is mandatory */ 1247 mpic->reg_type = mpic_access_mmio_le;
1231 BUG_ON(paddr == 0 && node == NULL);
1232 1248
1233 /* If no physical address passed in, check if it's dcr based */ 1249 /*
1234 if (paddr == 0 && of_get_property(node, "dcr-reg", NULL) != NULL) { 1250 * An MPIC with a "dcr-reg" property must be accessed that way, but
1251 * only if the kernel includes DCR support.
1252 */
1235#ifdef CONFIG_PPC_DCR 1253#ifdef CONFIG_PPC_DCR
1236 mpic->flags |= MPIC_USES_DCR; 1254 if (flags & MPIC_USES_DCR)
1237 mpic->reg_type = mpic_access_dcr; 1255 mpic->reg_type = mpic_access_dcr;
1238#else 1256#else
1239 BUG(); 1257 BUG_ON(flags & MPIC_USES_DCR);
1240#endif /* CONFIG_PPC_DCR */ 1258#endif
1241 }
1242
1243 /* If the MPIC is not DCR based, and no physical address was passed
1244 * in, try to obtain one
1245 */
1246 if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) {
1247 const u32 *reg = of_get_property(node, "reg", NULL);
1248 BUG_ON(reg == NULL);
1249 paddr = of_translate_address(node, reg);
1250 BUG_ON(paddr == OF_BAD_ADDR);
1251 }
1252 1259
1253 /* Map the global registers */ 1260 /* Map the global registers */
1254 mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); 1261 mpic_map(mpic, node, phys_addr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
1255 mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); 1262 mpic_map(mpic, node, phys_addr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
1256 1263
1257 /* Reset */ 1264 /* Reset */
1258 1265
@@ -1307,7 +1314,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1307 for_each_possible_cpu(i) { 1314 for_each_possible_cpu(i) {
1308 unsigned int cpu = get_hard_smp_processor_id(i); 1315 unsigned int cpu = get_hard_smp_processor_id(i);
1309 1316
1310 mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu], 1317 mpic_map(mpic, node, phys_addr, &mpic->cpuregs[cpu],
1311 MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE), 1318 MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
1312 0x1000); 1319 0x1000);
1313 } 1320 }
@@ -1315,7 +1322,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1315 /* Initialize main ISU if none provided */ 1322 /* Initialize main ISU if none provided */
1316 if (mpic->isu_size == 0) { 1323 if (mpic->isu_size == 0) {
1317 mpic->isu_size = mpic->num_sources; 1324 mpic->isu_size = mpic->num_sources;
1318 mpic_map(mpic, node, paddr, &mpic->isus[0], 1325 mpic_map(mpic, node, phys_addr, &mpic->isus[0],
1319 MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); 1326 MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
1320 } 1327 }
1321 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); 1328 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -1347,7 +1354,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1347 } 1354 }
1348 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," 1355 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
1349 " max %d CPUs\n", 1356 " max %d CPUs\n",
1350 name, vers, (unsigned long long)paddr, num_possible_cpus()); 1357 name, vers, (unsigned long long)phys_addr, num_possible_cpus());
1351 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", 1358 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
1352 mpic->isu_size, mpic->isu_shift, mpic->isu_mask); 1359 mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
1353 1360