aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-22 12:47:59 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-26 00:37:22 -0400
commit5a2642f620eb6e40792822fa0eafe23046fbb55e (patch)
tree639c2697e07ca65c970837281239bcbb41f202e5 /arch/powerpc/sysdev/mpic.c
parent6f0b1c6094b3e8eeeb13f8f16c1b2ef452a6f519 (diff)
powerpc/mpic: Fix mapping of "DCR" based MPIC variants
Commit 31207dab7d2e63795eb15823947bd2f7025b08e2 "Fix incorrect allocation of interrupt rev-map" introduced a regression crashing on boot on machines using a "DCR" based MPIC, such as the Cell blades. The reason is that the irq host data structure is initialized much later as a result of that patch, causing our calls to mpic_map() do be done before we have a host setup. Unfortunately, this breaks _mpic_map_dcr() which uses the mpic->irqhost to get to the device node. This fixes it by, instead, passing the device node explicitely to mpic_map(). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Akira Tsukamoto <akirat@rd.scei.sony.co.jp>
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 9c3af5045495..32a2e950f563 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -279,28 +279,29 @@ static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr,
279} 279}
280 280
281#ifdef CONFIG_PPC_DCR 281#ifdef CONFIG_PPC_DCR
282static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, 282static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node,
283 struct mpic_reg_bank *rb,
283 unsigned int offset, unsigned int size) 284 unsigned int offset, unsigned int size)
284{ 285{
285 const u32 *dbasep; 286 const u32 *dbasep;
286 287
287 dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL); 288 dbasep = of_get_property(node, "dcr-reg", NULL);
288 289
289 rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size); 290 rb->dhost = dcr_map(node, *dbasep + offset, size);
290 BUG_ON(!DCR_MAP_OK(rb->dhost)); 291 BUG_ON(!DCR_MAP_OK(rb->dhost));
291} 292}
292 293
293static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr, 294static inline void mpic_map(struct mpic *mpic, struct device_node *node,
294 struct mpic_reg_bank *rb, unsigned int offset, 295 phys_addr_t phys_addr, struct mpic_reg_bank *rb,
295 unsigned int size) 296 unsigned int offset, unsigned int size)
296{ 297{
297 if (mpic->flags & MPIC_USES_DCR) 298 if (mpic->flags & MPIC_USES_DCR)
298 _mpic_map_dcr(mpic, rb, offset, size); 299 _mpic_map_dcr(mpic, node, rb, offset, size);
299 else 300 else
300 _mpic_map_mmio(mpic, phys_addr, rb, offset, size); 301 _mpic_map_mmio(mpic, phys_addr, rb, offset, size);
301} 302}
302#else /* CONFIG_PPC_DCR */ 303#else /* CONFIG_PPC_DCR */
303#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) 304#define mpic_map(m,n,p,b,o,s) _mpic_map_mmio(m,p,b,o,s)
304#endif /* !CONFIG_PPC_DCR */ 305#endif /* !CONFIG_PPC_DCR */
305 306
306 307
@@ -1152,8 +1153,8 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1152 } 1153 }
1153 1154
1154 /* Map the global registers */ 1155 /* Map the global registers */
1155 mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); 1156 mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
1156 mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); 1157 mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
1157 1158
1158 /* Reset */ 1159 /* Reset */
1159 if (flags & MPIC_WANTS_RESET) { 1160 if (flags & MPIC_WANTS_RESET) {
@@ -1194,7 +1195,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1194 1195
1195 /* Map the per-CPU registers */ 1196 /* Map the per-CPU registers */
1196 for (i = 0; i < mpic->num_cpus; i++) { 1197 for (i = 0; i < mpic->num_cpus; i++) {
1197 mpic_map(mpic, paddr, &mpic->cpuregs[i], 1198 mpic_map(mpic, node, paddr, &mpic->cpuregs[i],
1198 MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 1199 MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
1199 0x1000); 1200 0x1000);
1200 } 1201 }
@@ -1202,7 +1203,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1202 /* Initialize main ISU if none provided */ 1203 /* Initialize main ISU if none provided */
1203 if (mpic->isu_size == 0) { 1204 if (mpic->isu_size == 0) {
1204 mpic->isu_size = mpic->num_sources; 1205 mpic->isu_size = mpic->num_sources;
1205 mpic_map(mpic, paddr, &mpic->isus[0], 1206 mpic_map(mpic, node, paddr, &mpic->isus[0],
1206 MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); 1207 MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
1207 } 1208 }
1208 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); 1209 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -1256,8 +1257,10 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
1256 1257
1257 BUG_ON(isu_num >= MPIC_MAX_ISU); 1258 BUG_ON(isu_num >= MPIC_MAX_ISU);
1258 1259
1259 mpic_map(mpic, paddr, &mpic->isus[isu_num], 0, 1260 mpic_map(mpic, mpic->irqhost->of_node,
1261 paddr, &mpic->isus[isu_num], 0,
1260 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); 1262 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
1263
1261 if ((isu_first + mpic->isu_size) > mpic->num_sources) 1264 if ((isu_first + mpic->isu_size) > mpic->num_sources)
1262 mpic->num_sources = isu_first + mpic->isu_size; 1265 mpic->num_sources = isu_first + mpic->isu_size;
1263} 1266}