MIPS: Oprofile: Fixup the loose ends in the plumbing. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Ralf Baechle and committed by
ba339c03 0401572a

+50 -8
+26 -2
arch/mips/kernel/time.c
··· 507 return IRQ_HANDLED; 508 } 509 510 asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) 511 { 512 irq_enter(); 513 kstat_this_cpu.irqs[irq]++; 514 515 - /* we keep interrupt disabled all the time */ 516 - timer_interrupt(irq, NULL, regs); 517 518 irq_exit(); 519 } 520
··· 507 return IRQ_HANDLED; 508 } 509 510 + 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 + 520 asmlinkage 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]++; 526 527 + /* 528 + * Suckage alert: 529 + * Before R2 of the architecture there was no way to see if a 530 + * performance counter interrupt was pending, so we have to run the 531 + * performance counter interrupt handler anyway. 532 + */ 533 + if (!r2 || (read_c0_cause() & (1 << 26))) 534 + if (perf_irq(regs)) 535 + goto out; 536 537 + /* 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 } 77 78 irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 79 { 80 int cpu = smp_processor_id(); 81 82 if (cpu == 0) { 83 /* 84 - * CPU 0 handles the global timer interrupt job and process accounting 85 - * resets count/compare registers to trigger next timer int. 86 */ 87 - timer_interrupt(irq, dev_id, regs); 88 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 } 116 117 return IRQ_HANDLED; 118 } 119
··· 75 do_IRQ (mips_cpu_timer_irq, regs); 76 } 77 78 + extern int null_perf_irq(struct pt_regs *regs); 79 + 80 + extern int (*perf_irq)(struct pt_regs *regs); 81 + 82 irqreturn_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(); 86 87 if (cpu == 0) { 88 /* 89 + * CPU 0 handles the global timer interrupt job and process 90 + * accounting resets count/compare registers to trigger next 91 + * 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 } 103 104 + out: 105 return IRQ_HANDLED; 106 } 107
+2 -2
arch/mips/oprofile/op_impl.h
··· 12 13 struct pt_regs; 14 15 - extern void null_perf_irq(struct pt_regs *regs); 16 - extern void (*perf_irq)(struct pt_regs *regs); 17 18 /* Per-counter configuration as set via oprofilefs. */ 19 struct op_counter_config {
··· 12 13 struct pt_regs; 14 15 + extern int null_perf_irq(struct pt_regs *regs); 16 + extern int (*perf_irq)(struct pt_regs *regs); 17 18 /* Per-counter configuration as set via oprofilefs. */ 19 struct op_counter_config {
+5 -1
arch/mips/oprofile/op_model_mipsxx.c
··· 114 } 115 } 116 117 - static void mipsxx_perfcount_handler(struct pt_regs *regs) 118 { 119 unsigned int counters = op_model_mipsxx.num_counters; 120 unsigned int control; 121 unsigned int counter; 122 123 switch (counters) { 124 #define HANDLE_COUNTER(n) \ ··· 130 (counter & M_COUNTER_OVERFLOW)) { \ 131 oprofile_add_sample(regs, n); \ 132 write_c0_perfcntr ## n(reg.counter[n]); \ 133 } 134 HANDLE_COUNTER(3) 135 HANDLE_COUNTER(2) 136 HANDLE_COUNTER(1) 137 HANDLE_COUNTER(0) 138 } 139 } 140 141 #define M_CONFIG1_PC (1 << 4)
··· 114 } 115 } 116 117 + static int mipsxx_perfcount_handler(struct pt_regs *regs) 118 { 119 unsigned int counters = op_model_mipsxx.num_counters; 120 unsigned int control; 121 unsigned int counter; 122 + int handled = 0; 123 124 switch (counters) { 125 #define HANDLE_COUNTER(n) \ ··· 129 (counter & M_COUNTER_OVERFLOW)) { \ 130 oprofile_add_sample(regs, n); \ 131 write_c0_perfcntr ## n(reg.counter[n]); \ 132 + handled = 1; \ 133 } 134 HANDLE_COUNTER(3) 135 HANDLE_COUNTER(2) 136 HANDLE_COUNTER(1) 137 HANDLE_COUNTER(0) 138 } 139 + 140 + return handled; 141 } 142 143 #define M_CONFIG1_PC (1 << 4)