Loading arch/mips/kernel/time.c +25 −1 Original line number Original line Diff line number Diff line Loading @@ -507,14 +507,38 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; return IRQ_HANDLED; } } int null_perf_irq(struct pt_regs *regs) { return 0; } int (*perf_irq)(struct pt_regs *regs) = null_perf_irq; EXPORT_SYMBOL(null_perf_irq); EXPORT_SYMBOL(perf_irq); asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) { { int r2 = cpu_has_mips_r2; irq_enter(); irq_enter(); kstat_this_cpu.irqs[irq]++; kstat_this_cpu.irqs[irq]++; /* * Suckage alert: * Before R2 of the architecture there was no way to see if a * performance counter interrupt was pending, so we have to run the * performance counter interrupt handler anyway. */ if (!r2 || (read_c0_cause() & (1 << 26))) if (perf_irq(regs)) goto out; /* we keep interrupt disabled all the time */ /* we keep interrupt disabled all the time */ if (!r2 || (read_c0_cause() & (1 << 30))) timer_interrupt(irq, NULL, regs); timer_interrupt(irq, NULL, regs); out: irq_exit(); irq_exit(); } } Loading arch/mips/mips-boards/generic/time.c +17 −3 Original line number Original line Diff line number Diff line Loading @@ -75,16 +75,29 @@ static void mips_timer_dispatch (struct pt_regs *regs) do_IRQ (mips_cpu_timer_irq, regs); do_IRQ (mips_cpu_timer_irq, regs); } } extern int null_perf_irq(struct pt_regs *regs); extern int (*perf_irq)(struct pt_regs *regs); irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { { int r2 = cpu_has_mips_r2; int cpu = smp_processor_id(); int cpu = smp_processor_id(); if (cpu == 0) { if (cpu == 0) { /* /* * CPU 0 handles the global timer interrupt job and process accounting * CPU 0 handles the global timer interrupt job and process * resets count/compare registers to trigger next timer int. * accounting resets count/compare registers to trigger next * timer int. */ */ timer_interrupt(irq, dev_id, regs); if (!r2 || (read_c0_cause() & (1 << 26))) if (perf_irq(regs)) goto out; /* we keep interrupt disabled all the time */ if (!r2 || (read_c0_cause() & (1 << 30))) timer_interrupt(irq, NULL, regs); scroll_display_message(); scroll_display_message(); } else { } else { /* Everyone else needs to reset the timer int here as /* Everyone else needs to reset the timer int here as Loading @@ -101,6 +114,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) local_timer_interrupt (irq, dev_id, regs); local_timer_interrupt (irq, dev_id, regs); } } out: return IRQ_HANDLED; return IRQ_HANDLED; } } Loading arch/mips/oprofile/op_impl.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -12,8 +12,8 @@ struct pt_regs; struct pt_regs; extern void null_perf_irq(struct pt_regs *regs); extern int null_perf_irq(struct pt_regs *regs); extern void (*perf_irq)(struct pt_regs *regs); extern int (*perf_irq)(struct pt_regs *regs); /* Per-counter configuration as set via oprofilefs. */ /* Per-counter configuration as set via oprofilefs. */ struct op_counter_config { struct op_counter_config { Loading arch/mips/oprofile/op_model_mipsxx.c +5 −1 Original line number Original line Diff line number Diff line Loading @@ -114,11 +114,12 @@ static void mipsxx_cpu_stop(void *args) } } } } static void mipsxx_perfcount_handler(struct pt_regs *regs) static int mipsxx_perfcount_handler(struct pt_regs *regs) { { unsigned int counters = op_model_mipsxx.num_counters; unsigned int counters = op_model_mipsxx.num_counters; unsigned int control; unsigned int control; unsigned int counter; unsigned int counter; int handled = 0; switch (counters) { switch (counters) { #define HANDLE_COUNTER(n) \ #define HANDLE_COUNTER(n) \ Loading @@ -129,12 +130,15 @@ static void mipsxx_perfcount_handler(struct pt_regs *regs) (counter & M_COUNTER_OVERFLOW)) { \ (counter & M_COUNTER_OVERFLOW)) { \ oprofile_add_sample(regs, n); \ oprofile_add_sample(regs, n); \ write_c0_perfcntr ## n(reg.counter[n]); \ write_c0_perfcntr ## n(reg.counter[n]); \ handled = 1; \ } } HANDLE_COUNTER(3) HANDLE_COUNTER(3) HANDLE_COUNTER(2) HANDLE_COUNTER(2) HANDLE_COUNTER(1) HANDLE_COUNTER(1) HANDLE_COUNTER(0) HANDLE_COUNTER(0) } } return handled; } } #define M_CONFIG1_PC (1 << 4) #define M_CONFIG1_PC (1 << 4) Loading Loading
arch/mips/kernel/time.c +25 −1 Original line number Original line Diff line number Diff line Loading @@ -507,14 +507,38 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; return IRQ_HANDLED; } } int null_perf_irq(struct pt_regs *regs) { return 0; } int (*perf_irq)(struct pt_regs *regs) = null_perf_irq; EXPORT_SYMBOL(null_perf_irq); EXPORT_SYMBOL(perf_irq); asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) { { int r2 = cpu_has_mips_r2; irq_enter(); irq_enter(); kstat_this_cpu.irqs[irq]++; kstat_this_cpu.irqs[irq]++; /* * Suckage alert: * Before R2 of the architecture there was no way to see if a * performance counter interrupt was pending, so we have to run the * performance counter interrupt handler anyway. */ if (!r2 || (read_c0_cause() & (1 << 26))) if (perf_irq(regs)) goto out; /* we keep interrupt disabled all the time */ /* we keep interrupt disabled all the time */ if (!r2 || (read_c0_cause() & (1 << 30))) timer_interrupt(irq, NULL, regs); timer_interrupt(irq, NULL, regs); out: irq_exit(); irq_exit(); } } Loading
arch/mips/mips-boards/generic/time.c +17 −3 Original line number Original line Diff line number Diff line Loading @@ -75,16 +75,29 @@ static void mips_timer_dispatch (struct pt_regs *regs) do_IRQ (mips_cpu_timer_irq, regs); do_IRQ (mips_cpu_timer_irq, regs); } } extern int null_perf_irq(struct pt_regs *regs); extern int (*perf_irq)(struct pt_regs *regs); irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { { int r2 = cpu_has_mips_r2; int cpu = smp_processor_id(); int cpu = smp_processor_id(); if (cpu == 0) { if (cpu == 0) { /* /* * CPU 0 handles the global timer interrupt job and process accounting * CPU 0 handles the global timer interrupt job and process * resets count/compare registers to trigger next timer int. * accounting resets count/compare registers to trigger next * timer int. */ */ timer_interrupt(irq, dev_id, regs); if (!r2 || (read_c0_cause() & (1 << 26))) if (perf_irq(regs)) goto out; /* we keep interrupt disabled all the time */ if (!r2 || (read_c0_cause() & (1 << 30))) timer_interrupt(irq, NULL, regs); scroll_display_message(); scroll_display_message(); } else { } else { /* Everyone else needs to reset the timer int here as /* Everyone else needs to reset the timer int here as Loading @@ -101,6 +114,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) local_timer_interrupt (irq, dev_id, regs); local_timer_interrupt (irq, dev_id, regs); } } out: return IRQ_HANDLED; return IRQ_HANDLED; } } Loading
arch/mips/oprofile/op_impl.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -12,8 +12,8 @@ struct pt_regs; struct pt_regs; extern void null_perf_irq(struct pt_regs *regs); extern int null_perf_irq(struct pt_regs *regs); extern void (*perf_irq)(struct pt_regs *regs); extern int (*perf_irq)(struct pt_regs *regs); /* Per-counter configuration as set via oprofilefs. */ /* Per-counter configuration as set via oprofilefs. */ struct op_counter_config { struct op_counter_config { Loading
arch/mips/oprofile/op_model_mipsxx.c +5 −1 Original line number Original line Diff line number Diff line Loading @@ -114,11 +114,12 @@ static void mipsxx_cpu_stop(void *args) } } } } static void mipsxx_perfcount_handler(struct pt_regs *regs) static int mipsxx_perfcount_handler(struct pt_regs *regs) { { unsigned int counters = op_model_mipsxx.num_counters; unsigned int counters = op_model_mipsxx.num_counters; unsigned int control; unsigned int control; unsigned int counter; unsigned int counter; int handled = 0; switch (counters) { switch (counters) { #define HANDLE_COUNTER(n) \ #define HANDLE_COUNTER(n) \ Loading @@ -129,12 +130,15 @@ static void mipsxx_perfcount_handler(struct pt_regs *regs) (counter & M_COUNTER_OVERFLOW)) { \ (counter & M_COUNTER_OVERFLOW)) { \ oprofile_add_sample(regs, n); \ oprofile_add_sample(regs, n); \ write_c0_perfcntr ## n(reg.counter[n]); \ write_c0_perfcntr ## n(reg.counter[n]); \ handled = 1; \ } } HANDLE_COUNTER(3) HANDLE_COUNTER(3) HANDLE_COUNTER(2) HANDLE_COUNTER(2) HANDLE_COUNTER(1) HANDLE_COUNTER(1) HANDLE_COUNTER(0) HANDLE_COUNTER(0) } } return handled; } } #define M_CONFIG1_PC (1 << 4) #define M_CONFIG1_PC (1 << 4) Loading