diff options
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 32a7efe76d00..266937030546 100644 --- a/arch/sparc/include/asm/pil.h +++ b/arch/sparc/include/asm/pil.h | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #define PIL_DEVICE_IRQ 5 | 24 | #define PIL_DEVICE_IRQ 5 |
| 25 | #define PIL_SMP_CALL_FUNC_SNGL 6 | 25 | #define PIL_SMP_CALL_FUNC_SNGL 6 |
| 26 | #define PIL_DEFERRED_PCR_WORK 7 | 26 | #define PIL_DEFERRED_PCR_WORK 7 |
| 27 | #define PIL_KGDB_CAPTURE 8 | ||
| 27 | #define PIL_NORMAL_MAX 14 | 28 | #define PIL_NORMAL_MAX 14 |
| 28 | #define PIL_NMI 15 | 29 | #define PIL_NMI 15 |
| 29 | 30 | ||
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index e289376198eb..1c378d8e90c5 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, | |||
| 323 | sun4u_irq_enable(virt_irq); | 323 | sun4u_irq_enable(virt_irq); |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | /* Don't do anything. The desc->status check for IRQ_DISABLED in | ||
| 327 | * handler_irq() will skip the handler call and that will leave the | ||
| 328 | * interrupt in the sent state. The next ->enable() call will hit the | ||
| 329 | * ICLR register to reset the state machine. | ||
| 330 | * | ||
| 331 | * This scheme is necessary, instead of clearing the Valid bit in the | ||
| 332 | * IMAP register, to handle the case of IMAP registers being shared by | ||
| 333 | * multiple INOs (and thus ICLR registers). Since we use a different | ||
| 334 | * virtual IRQ for each shared IMAP instance, the generic code thinks | ||
| 335 | * there is only one user so it prematurely calls ->disable() on | ||
| 336 | * free_irq(). | ||
| 337 | * | ||
| 338 | * We have to provide an explicit ->disable() method instead of using | ||
| 339 | * NULL to get the default. The reason is that if the generic code | ||
| 340 | * sees that, it also hooks up a default ->shutdown method which | ||
| 341 | * invokes ->mask() which we do not want. See irq_chip_set_defaults(). | ||
| 342 | */ | ||
| 326 | static void sun4u_irq_disable(unsigned int virt_irq) | 343 | static void sun4u_irq_disable(unsigned int virt_irq) |
| 327 | { | 344 | { |
| 328 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); | ||
| 329 | |||
| 330 | if (likely(data)) { | ||
| 331 | unsigned long imap = data->imap; | ||
| 332 | unsigned long tmp = upa_readq(imap); | ||
| 333 | |||
| 334 | tmp &= ~IMAP_VALID; | ||
| 335 | upa_writeq(tmp, imap); | ||
| 336 | } | ||
| 337 | } | 345 | } |
| 338 | 346 | ||
| 339 | static void sun4u_irq_eoi(unsigned int virt_irq) | 347 | static void sun4u_irq_eoi(unsigned int virt_irq) |
| @@ -746,7 +754,8 @@ void handler_irq(int irq, struct pt_regs *regs) | |||
| 746 | 754 | ||
| 747 | desc = irq_desc + virt_irq; | 755 | desc = irq_desc + virt_irq; |
| 748 | 756 | ||
| 749 | desc->handle_irq(virt_irq, desc); | 757 | if (!(desc->status & IRQ_DISABLED)) |
| 758 | desc->handle_irq(virt_irq, desc); | ||
| 750 | 759 | ||
| 751 | bucket_pa = next_pa; | 760 | bucket_pa = next_pa; |
| 752 | } | 761 | } |
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index fefbe6dc51be..f5a0fd490b59 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) | |||
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | #ifdef CONFIG_SMP | 110 | #ifdef CONFIG_SMP |
| 111 | void smp_kgdb_capture_client(struct pt_regs *regs) | 111 | void smp_kgdb_capture_client(int irq, struct pt_regs *regs) |
| 112 | { | 112 | { |
| 113 | unsigned long flags; | 113 | unsigned long flags; |
| 114 | 114 | ||
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 64e6edf17b9d..b775658a927d 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) | |||
| 368 | const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); | 368 | const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); |
| 369 | 369 | ||
| 370 | if (vdma) { | 370 | if (vdma) { |
| 371 | struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); | 371 | struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); |
| 372 | 372 | ||
| 373 | if (!rp) { | 373 | if (!rp) { |
| 374 | prom_printf("Cannot allocate IOMMU resource.\n"); | 374 | prom_printf("Cannot allocate IOMMU resource.\n"); |
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable.S index d9bdfb9d5c18..76d837fc47d3 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) | |||
| 64 | tl0_irq6: BTRAP(0x46) | 64 | tl0_irq6: BTRAP(0x46) |
| 65 | #endif | 65 | #endif |
| 66 | tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7) | 66 | tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7) |
| 67 | tl0_irq8: BTRAP(0x48) BTRAP(0x49) | 67 | #ifdef CONFIG_KGDB |
| 68 | tl0_irq8: TRAP_IRQ(smp_kgdb_capture_client, 8) | ||
| 69 | #else | ||
| 70 | tl0_irq8: BTRAP(0x48) | ||
| 71 | #endif | ||
| 72 | tl0_irq9: BTRAP(0x49) | ||
| 68 | tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) | 73 | tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) |
| 69 | tl0_irq14: TRAP_IRQ(timer_interrupt, 14) | 74 | tl0_irq14: TRAP_IRQ(timer_interrupt, 14) |
| 70 | tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15) | 75 | tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15) |
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index 80c788ec7c32..b57a5942ba64 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S | |||
| @@ -679,28 +679,8 @@ xcall_new_mmu_context_version: | |||
| 679 | #ifdef CONFIG_KGDB | 679 | #ifdef CONFIG_KGDB |
| 680 | .globl xcall_kgdb_capture | 680 | .globl xcall_kgdb_capture |
| 681 | xcall_kgdb_capture: | 681 | xcall_kgdb_capture: |
| 682 | 661: rdpr %pstate, %g2 | 682 | wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint |
| 683 | wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate | 683 | retry |
| 684 | .section .sun4v_2insn_patch, "ax" | ||
| 685 | .word 661b | ||
| 686 | nop | ||
| 687 | nop | ||
| 688 | .previous | ||
| 689 | |||
| 690 | rdpr %pil, %g2 | ||
| 691 | wrpr %g0, PIL_NORMAL_MAX, %pil | ||
| 692 | sethi %hi(109f), %g7 | ||
| 693 | ba,pt %xcc, etrap_irq | ||
| 694 | 109: or %g7, %lo(109b), %g7 | ||
| 695 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 696 | call trace_hardirqs_off | ||
| 697 | nop | ||
| 698 | #endif | ||
| 699 | call smp_kgdb_capture_client | ||
| 700 | add %sp, PTREGS_OFF, %o0 | ||
| 701 | /* Has to be a non-v9 branch due to the large distance. */ | ||
| 702 | ba rtrap_xcall | ||
| 703 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 | ||
| 704 | #endif | 684 | #endif |
| 705 | 685 | ||
| 706 | #endif /* CONFIG_SMP */ | 686 | #endif /* CONFIG_SMP */ |
