diff options
Diffstat (limited to 'arch/sparc/kernel/irq_64.c')
| -rw-r--r-- | arch/sparc/kernel/irq_64.c | 68 |
1 files changed, 5 insertions, 63 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index cab8e0286871..e289376198eb 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
| @@ -196,6 +196,11 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 196 | seq_putc(p, '\n'); | 196 | seq_putc(p, '\n'); |
| 197 | skip: | 197 | skip: |
| 198 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 198 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
| 199 | } else if (i == NR_IRQS) { | ||
| 200 | seq_printf(p, "NMI: "); | ||
| 201 | for_each_online_cpu(j) | ||
| 202 | seq_printf(p, "%10u ", cpu_data(j).__nmi_count); | ||
| 203 | seq_printf(p, " Non-maskable interrupts\n"); | ||
| 199 | } | 204 | } |
| 200 | return 0; | 205 | return 0; |
| 201 | } | 206 | } |
| @@ -778,69 +783,6 @@ void do_softirq(void) | |||
| 778 | local_irq_restore(flags); | 783 | local_irq_restore(flags); |
| 779 | } | 784 | } |
| 780 | 785 | ||
| 781 | static void unhandled_perf_irq(struct pt_regs *regs) | ||
| 782 | { | ||
| 783 | unsigned long pcr, pic; | ||
| 784 | |||
| 785 | read_pcr(pcr); | ||
| 786 | read_pic(pic); | ||
| 787 | |||
| 788 | write_pcr(0); | ||
| 789 | |||
| 790 | printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n", | ||
| 791 | smp_processor_id()); | ||
| 792 | printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n", | ||
| 793 | smp_processor_id(), pcr, pic); | ||
| 794 | } | ||
| 795 | |||
| 796 | /* Almost a direct copy of the powerpc PMC code. */ | ||
| 797 | static DEFINE_SPINLOCK(perf_irq_lock); | ||
| 798 | static void *perf_irq_owner_caller; /* mostly for debugging */ | ||
| 799 | static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq; | ||
| 800 | |||
| 801 | /* Invoked from level 15 PIL handler in trap table. */ | ||
| 802 | void perfctr_irq(int irq, struct pt_regs *regs) | ||
| 803 | { | ||
| 804 | clear_softint(1 << irq); | ||
| 805 | perf_irq(regs); | ||
| 806 | } | ||
| 807 | |||
| 808 | int register_perfctr_intr(void (*handler)(struct pt_regs *)) | ||
| 809 | { | ||
| 810 | int ret; | ||
| 811 | |||
| 812 | if (!handler) | ||
| 813 | return -EINVAL; | ||
| 814 | |||
| 815 | spin_lock(&perf_irq_lock); | ||
| 816 | if (perf_irq != unhandled_perf_irq) { | ||
| 817 | printk(KERN_WARNING "register_perfctr_intr: " | ||
| 818 | "perf IRQ busy (reserved by caller %p)\n", | ||
| 819 | perf_irq_owner_caller); | ||
| 820 | ret = -EBUSY; | ||
| 821 | goto out; | ||
| 822 | } | ||
| 823 | |||
| 824 | perf_irq_owner_caller = __builtin_return_address(0); | ||
| 825 | perf_irq = handler; | ||
| 826 | |||
| 827 | ret = 0; | ||
| 828 | out: | ||
| 829 | spin_unlock(&perf_irq_lock); | ||
| 830 | |||
| 831 | return ret; | ||
| 832 | } | ||
| 833 | EXPORT_SYMBOL_GPL(register_perfctr_intr); | ||
| 834 | |||
| 835 | void release_perfctr_intr(void (*handler)(struct pt_regs *)) | ||
| 836 | { | ||
| 837 | spin_lock(&perf_irq_lock); | ||
| 838 | perf_irq_owner_caller = NULL; | ||
| 839 | perf_irq = unhandled_perf_irq; | ||
| 840 | spin_unlock(&perf_irq_lock); | ||
| 841 | } | ||
| 842 | EXPORT_SYMBOL_GPL(release_perfctr_intr); | ||
| 843 | |||
| 844 | #ifdef CONFIG_HOTPLUG_CPU | 786 | #ifdef CONFIG_HOTPLUG_CPU |
| 845 | void fixup_irqs(void) | 787 | void fixup_irqs(void) |
| 846 | { | 788 | { |
