From 5a2642f620eb6e40792822fa0eafe23046fbb55e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 22 Jun 2009 16:47:59 +0000 Subject: 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 Acked-by: Akira Tsukamoto --- arch/powerpc/sysdev/mpic.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'arch/powerpc/sysdev/mpic.c') 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, } #ifdef CONFIG_PPC_DCR -static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, +static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node, + struct mpic_reg_bank *rb, unsigned int offset, unsigned int size) { const u32 *dbasep; - dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL); + dbasep = of_get_property(node, "dcr-reg", NULL); - rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size); + rb->dhost = dcr_map(node, *dbasep + offset, size); BUG_ON(!DCR_MAP_OK(rb->dhost)); } -static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr, - struct mpic_reg_bank *rb, unsigned int offset, - unsigned int size) +static inline void mpic_map(struct mpic *mpic, struct device_node *node, + phys_addr_t phys_addr, struct mpic_reg_bank *rb, + unsigned int offset, unsigned int size) { if (mpic->flags & MPIC_USES_DCR) - _mpic_map_dcr(mpic, rb, offset, size); + _mpic_map_dcr(mpic, node, rb, offset, size); else _mpic_map_mmio(mpic, phys_addr, rb, offset, size); } #else /* CONFIG_PPC_DCR */ -#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) +#define mpic_map(m,n,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) #endif /* !CONFIG_PPC_DCR */ @@ -1152,8 +1153,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, } /* Map the global registers */ - mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); - mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); + mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); + mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); /* Reset */ if (flags & MPIC_WANTS_RESET) { @@ -1194,7 +1195,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { - mpic_map(mpic, paddr, &mpic->cpuregs[i], + mpic_map(mpic, node, paddr, &mpic->cpuregs[i], MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 0x1000); } @@ -1202,7 +1203,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Initialize main ISU if none provided */ if (mpic->isu_size == 0) { mpic->isu_size = mpic->num_sources; - mpic_map(mpic, paddr, &mpic->isus[0], + mpic_map(mpic, node, paddr, &mpic->isus[0], MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); } 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, BUG_ON(isu_num >= MPIC_MAX_ISU); - mpic_map(mpic, paddr, &mpic->isus[isu_num], 0, + mpic_map(mpic, mpic->irqhost->of_node, + paddr, &mpic->isus[isu_num], 0, MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); + if ((isu_first + mpic->isu_size) > mpic->num_sources) mpic->num_sources = isu_first + mpic->isu_size; } -- cgit v1.2.3 From 85355bb272db31a3f2dd99d547eef794805e1319 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 18 Jun 2009 22:01:20 +0000 Subject: powerpc: Fix mpic alloc warning Since we can use kmalloc earlier we are getting the following since the mpic_alloc() code calls alloc_bootmem(). Move to using kzalloc() to remove the warning. ------------[ cut here ]------------ Badness at c0583248 [verbose debug info unavailable] NIP: c0583248 LR: c0583210 CTR: 00000004 REGS: c0741de0 TRAP: 0700 Not tainted (2.6.30-06736-g12a31df) MSR: 00021000 CR: 22024024 XER: 00000000 TASK = c070d3b8[0] 'swapper' THREAD: c0740000 CPU: 0 <6>GPR00: 00000001 c0741e90 c070d3b8 00000001 00000210 00000020 3fffffff 00000000 <6>GPR08: 00000000 c0c85700 c04f8c40 0000002d 22044022 1004a388 7ffd9400 00000000 <6>GPR16: 00000000 7ffcd100 7ffcd100 7ffcd100 c04f8c40 00000000 c059f62c c075a0c0 <6>GPR24: c059f648 00000000 0000000f 00000210 00000020 00000000 3fffffff 00000210 NIP [c0583248] alloc_arch_preferred_bootmem+0x50/0x80 LR [c0583210] alloc_arch_preferred_bootmem+0x18/0x80 Call Trace: [c0741e90] [c07343b0] devtree_lock+0x0/0x24 (unreliable) [c0741ea0] [c0583b14] ___alloc_bootmem_nopanic+0x54/0x108 [c0741ee0] [c0583e18] ___alloc_bootmem+0x18/0x50 [c0741ef0] [c057b9cc] mpic_alloc+0x48/0x710 [c0741f40] [c057ecf4] mpc85xx_ds_pic_init+0x190/0x1b8 [c0741f90] [c057633c] init_IRQ+0x24/0x34 [c0741fa0] [c05738b8] start_kernel+0x260/0x3dc [c0741ff0] [c00003c8] skpinv+0x2e0/0x31c Instruction dump: 409e001c 7c030378 80010014 83e1000c 38210010 7c0803a6 4e800020 3d20c0c8 39295700 80090004 7c000034 5400d97e <0f000000> 2f800000 409e001c 38800000 BenH: Changed to use GFP_KERNEL, the allocator will do the right thing Signed-off-by: Kumar Gala Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/sysdev/mpic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/sysdev/mpic.c') diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 32a2e950f563..d46de1f0f3ee 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1053,11 +1053,10 @@ struct mpic * __init mpic_alloc(struct device_node *node, int intvec_top; u64 paddr = phys_addr; - mpic = alloc_bootmem(sizeof(struct mpic)); + mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL); if (mpic == NULL) return NULL; - - memset(mpic, 0, sizeof(struct mpic)); + mpic->name = name; mpic->hc_irq = mpic_irq_chip; -- cgit v1.2.3 From ea96025a26ab8949adab1a8e81419202f92f3f7f Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 1 Jul 2009 10:59:57 +0000 Subject: powerpc: Don't use alloc_bootmem() in init_IRQ() path This patch fixes various badnesses like this for all interrupt controllers: ------------[ cut here ]------------ Badness at c04db9dc [verbose debug info unavailable] NIP: c04db9dc LR: c04db9ac CTR: 00000000 REGS: c053de30 TRAP: 0700 Not tainted (2.6.31-rc1-00432-ge69b2b5-dirty) MSR: 00021000 CR: 22020084 XER: 00000000 TASK = c0500480[0] 'swapper' THREAD: c053c000 GPR00: 00000001 c053dee0 c0500480 00000000 00000050 00000020 3fffffff 00000000 GPR08: 00000001 c0540000 e0080080 00000000 22000084 64183600 3ff8f800 00000000 GPR16: 841b0240 449a0303 00000000 00000000 00000000 00000000 00000000 c04f5bf4 GPR24: 00000000 00000000 00000000 00000050 00000020 00000000 3fffffff 00000050 NIP [c04db9dc] alloc_arch_preferred_bootmem+0x48/0x74 LR [c04db9ac] alloc_arch_preferred_bootmem+0x18/0x74 Call Trace: [c053dee0] [c000a5a4] __of_address_to_resource+0x44/0xd0 (unreliable) [c053def0] [c04dba58] ___alloc_bootmem_nopanic+0x50/0x108 [c053df20] [c04dbb28] ___alloc_bootmem+0x18/0x50 [c053df30] [c04d5de0] qe_ic_init+0x5c/0x1b0 [c053df70] [c04d77b0] mpc85xx_mds_pic_init+0xb8/0x10c [c053dfb0] [c04cf374] init_IRQ+0x28/0x3c p.s. commit 85355bb272db31a3f2dd99d547eef794805e1319 ("powerpc: Fix mpic alloc warning") missed some alloc_bootmem() instances, this is now fixed. Signed-off-by: Anton Vorontsov Acked-by: Timur Tabi Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/sysdev/mpic.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch/powerpc/sysdev/mpic.c') diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index d46de1f0f3ee..3981ae4cb58e 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -508,9 +508,8 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n"); /* Allocate fixups array */ - mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup)); + mpic->fixups = kzalloc(128 * sizeof(*mpic->fixups), GFP_KERNEL); BUG_ON(mpic->fixups == NULL); - memset(mpic->fixups, 0, 128 * sizeof(struct mpic_irq_fixup)); /* Init spinlock */ spin_lock_init(&mpic->fixup_lock); @@ -1109,9 +1108,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, psize /= 4; bits = intvec_top + 1; mapsize = BITS_TO_LONGS(bits) * sizeof(unsigned long); - mpic->protected = alloc_bootmem(mapsize); + mpic->protected = kzalloc(mapsize, GFP_KERNEL); BUG_ON(mpic->protected == NULL); - memset(mpic->protected, 0, mapsize); for (i = 0; i < psize; i++) { if (psrc[i] > intvec_top) continue; @@ -1353,7 +1351,8 @@ void __init mpic_init(struct mpic *mpic) #ifdef CONFIG_PM /* allocate memory to save mpic state */ - mpic->save_data = alloc_bootmem(mpic->num_sources * sizeof(struct mpic_irq_save)); + mpic->save_data = kmalloc(mpic->num_sources * sizeof(*mpic->save_data), + GFP_KERNEL); BUG_ON(mpic->save_data == NULL); #endif } -- cgit v1.2.3