diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-24 13:38:30 +1100 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-24 13:38:30 +1100 |
commit | 9e41d9597e7825ec20d690013d32bcec5f3fe16a (patch) | |
tree | ac6fea59e9a4a1c2183d6bbd6ffa760680673afb /arch/sparc | |
parent | 77ecfe8d427f554fabbf258e9d789f1d4c3afd63 (diff) | |
parent | 8e0ee43bc2c3e19db56a4adaa9a9b04ce885cd84 (diff) |
Merge commit 'origin/master' into next
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/include/asm/pil.h | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/irq_64.c | 29 | ||||
-rw-r--r-- | arch/sparc/kernel/kgdb_64.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/pci_common.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/ttable.S | 7 | ||||
-rw-r--r-- | arch/sparc/mm/ultra.S | 24 |
6 files changed, 30 insertions, 35 deletions
diff --git a/arch/sparc/include/asm/pil.h b/arch/sparc/include/asm/pil.h index 32a7efe76d0..26693703054 100644 --- a/arch/sparc/include/asm/pil.h +++ b/arch/sparc/include/asm/pil.h @@ -24,6 +24,7 @@ #define PIL_DEVICE_IRQ 5 #define PIL_SMP_CALL_FUNC_SNGL 6 #define PIL_DEFERRED_PCR_WORK 7 +#define PIL_KGDB_CAPTURE 8 #define PIL_NORMAL_MAX 14 #define PIL_NMI 15 diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index e289376198e..1c378d8e90c 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -323,17 +323,25 @@ static void sun4u_set_affinity(unsigned int virt_irq, sun4u_irq_enable(virt_irq); } +/* Don't do anything. The desc->status check for IRQ_DISABLED in + * handler_irq() will skip the handler call and that will leave the + * interrupt in the sent state. The next ->enable() call will hit the + * ICLR register to reset the state machine. + * + * This scheme is necessary, instead of clearing the Valid bit in the + * IMAP register, to handle the case of IMAP registers being shared by + * multiple INOs (and thus ICLR registers). Since we use a different + * virtual IRQ for each shared IMAP instance, the generic code thinks + * there is only one user so it prematurely calls ->disable() on + * free_irq(). + * + * We have to provide an explicit ->disable() method instead of using + * NULL to get the default. The reason is that if the generic code + * sees that, it also hooks up a default ->shutdown method which + * invokes ->mask() which we do not want. See irq_chip_set_defaults(). + */ static void sun4u_irq_disable(unsigned int virt_irq) { - struct irq_handler_data *data = get_irq_chip_data(virt_irq); - - if (likely(data)) { - unsigned long imap = data->imap; - unsigned long tmp = upa_readq(imap); - - tmp &= ~IMAP_VALID; - upa_writeq(tmp, imap); - } } static void sun4u_irq_eoi(unsigned int virt_irq) @@ -746,7 +754,8 @@ void handler_irq(int irq, struct pt_regs *regs) desc = irq_desc + virt_irq; - desc->handle_irq(virt_irq, desc); + if (!(desc->status & IRQ_DISABLED)) + desc->handle_irq(virt_irq, desc); bucket_pa = next_pa; } diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index fefbe6dc51b..f5a0fd490b5 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c @@ -108,7 +108,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) } #ifdef CONFIG_SMP -void smp_kgdb_capture_client(struct pt_regs *regs) +void smp_kgdb_capture_client(int irq, struct pt_regs *regs) { unsigned long flags; diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 64e6edf17b9..b775658a927 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -368,7 +368,7 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); if (vdma) { - struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); + struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); if (!rp) { prom_printf("Cannot allocate IOMMU resource.\n"); diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable.S index d9bdfb9d5c1..76d837fc47d 100644 --- a/arch/sparc/kernel/ttable.S +++ b/arch/sparc/kernel/ttable.S @@ -64,7 +64,12 @@ tl0_irq6: TRAP_IRQ(smp_call_function_single_client, 6) tl0_irq6: BTRAP(0x46) #endif tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7) -tl0_irq8: BTRAP(0x48) BTRAP(0x49) +#ifdef CONFIG_KGDB +tl0_irq8: TRAP_IRQ(smp_kgdb_capture_client, 8) +#else +tl0_irq8: BTRAP(0x48) +#endif +tl0_irq9: BTRAP(0x49) tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) tl0_irq14: TRAP_IRQ(timer_interrupt, 14) tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15) diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index 80c788ec7c3..b57a5942ba6 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S @@ -679,28 +679,8 @@ xcall_new_mmu_context_version: #ifdef CONFIG_KGDB .globl xcall_kgdb_capture xcall_kgdb_capture: -661: rdpr %pstate, %g2 - wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate - .section .sun4v_2insn_patch, "ax" - .word 661b - nop - nop - .previous - - rdpr %pil, %g2 - wrpr %g0, PIL_NORMAL_MAX, %pil - sethi %hi(109f), %g7 - ba,pt %xcc, etrap_irq -109: or %g7, %lo(109b), %g7 -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_off - nop -#endif - call smp_kgdb_capture_client - add %sp, PTREGS_OFF, %o0 - /* Has to be a non-v9 branch due to the large distance. */ - ba rtrap_xcall - ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 + wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint + retry #endif #endif /* CONFIG_SMP */ |