diff options
author | Kyle Moffett <Kyle.D.Moffett@boeing.com> | 2011-12-02 01:27:59 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-12-06 21:43:06 -0500 |
commit | 8bf41568969e003c3d5410124e27bbdce7852e1b (patch) | |
tree | 684fee8aa54797e2482afd66b94f9633fcbd5061 /arch/powerpc/sysdev/mpic.c | |
parent | 582d3e099413c3741a88bdee9e3ff3cc2f9d3329 (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/mpic.c')
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 61 |
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 | ||