···507 return IRQ_HANDLED;508}5090000000000510asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)511{00512 irq_enter();513 kstat_this_cpu.irqs[irq]++;514515- /* we keep interrupt disabled all the time */516- timer_interrupt(irq, NULL, regs);000000051700000518 irq_exit();519}520
···507 return IRQ_HANDLED;508}509510+int null_perf_irq(struct pt_regs *regs)511+{512+ return 0;513+}514+515+int (*perf_irq)(struct pt_regs *regs) = null_perf_irq;516+517+EXPORT_SYMBOL(null_perf_irq);518+EXPORT_SYMBOL(perf_irq);519+520asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)521{522+ int r2 = cpu_has_mips_r2;523+524 irq_enter();525 kstat_this_cpu.irqs[irq]++;526527+ /*528+ * Suckage alert:529+ * Before R2 of the architecture there was no way to see if a530+ * performance counter interrupt was pending, so we have to run the531+ * performance counter interrupt handler anyway.532+ */533+ if (!r2 || (read_c0_cause() & (1 << 26)))534+ if (perf_irq(regs))535+ goto out;536537+ /* we keep interrupt disabled all the time */538+ if (!r2 || (read_c0_cause() & (1 << 30)))539+ timer_interrupt(irq, NULL, regs);540+541+out:542 irq_exit();543}544
+17-3
arch/mips/mips-boards/generic/time.c
···75 do_IRQ (mips_cpu_timer_irq, regs);76}77000078irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)79{080 int cpu = smp_processor_id();8182 if (cpu == 0) {83 /*84- * CPU 0 handles the global timer interrupt job and process accounting85- * resets count/compare registers to trigger next timer int.086 */87- timer_interrupt(irq, dev_id, regs);000000088 scroll_display_message();89 } else {90 /* Everyone else needs to reset the timer int here as···114 local_timer_interrupt (irq, dev_id, regs);115 }1160117 return IRQ_HANDLED;118}119
···75 do_IRQ (mips_cpu_timer_irq, regs);76}7778+extern int null_perf_irq(struct pt_regs *regs);79+80+extern int (*perf_irq)(struct pt_regs *regs);81+82irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)83{84+ int r2 = cpu_has_mips_r2;85 int cpu = smp_processor_id();8687 if (cpu == 0) {88 /*89+ * CPU 0 handles the global timer interrupt job and process90+ * accounting resets count/compare registers to trigger next91+ * timer int.92 */93+ if (!r2 || (read_c0_cause() & (1 << 26)))94+ if (perf_irq(regs))95+ goto out;96+97+ /* we keep interrupt disabled all the time */98+ if (!r2 || (read_c0_cause() & (1 << 30)))99+ timer_interrupt(irq, NULL, regs);100+101 scroll_display_message();102 } else {103 /* Everyone else needs to reset the timer int here as···101 local_timer_interrupt (irq, dev_id, regs);102 }103104+out:105 return IRQ_HANDLED;106}107
+2-2
arch/mips/oprofile/op_impl.h
···1213struct pt_regs;1415-extern void null_perf_irq(struct pt_regs *regs);16-extern void (*perf_irq)(struct pt_regs *regs);1718/* Per-counter configuration as set via oprofilefs. */19struct op_counter_config {
···1213struct pt_regs;1415+extern int null_perf_irq(struct pt_regs *regs);16+extern int (*perf_irq)(struct pt_regs *regs);1718/* Per-counter configuration as set via oprofilefs. */19struct op_counter_config {