#include <linux/errno.h>
#include <asm/ptrace.h>
#include <asm/system.h>
+#include <asm/pmc.h>
#include "op_impl.h"
extern struct op_ppc64_model op_model_power4;
static struct op_ppc64_model *model;
-extern void (*perf_irq)(struct pt_regs *);
-static void (*save_perf_irq)(struct pt_regs *);
-
static struct op_counter_config ctr[OP_MAX_COUNTER];
static struct op_system_config sys;
static int op_ppc64_setup(void)
{
- /* Install our interrupt handler into the existing hook. */
- save_perf_irq = perf_irq;
- perf_irq = op_handle_interrupt;
+ int err;
- mb();
+ /* Grab the hardware */
+ err = reserve_pmc_hardware(op_handle_interrupt);
+ if (err)
+ return err;
/* Pre-compute the values to stuff in the hardware registers. */
model->reg_setup(ctr, &sys, model->num_counters);
static void op_ppc64_shutdown(void)
{
- mb();
-
- /* Remove our interrupt handler. We may be removing this module. */
- perf_irq = save_perf_irq;
+ release_pmc_hardware();
}
static void op_ppc64_cpu_start(void *dummy)
return 0;
}
-static struct oprofile_operations oprof_ppc64_ops = {
- .create_files = op_ppc64_create_files,
- .setup = op_ppc64_setup,
- .shutdown = op_ppc64_shutdown,
- .start = op_ppc64_start,
- .stop = op_ppc64_stop,
- .cpu_type = NULL /* To be filled in below. */
-};
-
-int __init oprofile_arch_init(struct oprofile_operations **ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
{
unsigned int pvr;
case PV_630p:
model = &op_model_rs64;
model->num_counters = 8;
- oprof_ppc64_ops.cpu_type = "ppc64/power3";
+ ops->cpu_type = "ppc64/power3";
break;
case PV_NORTHSTAR:
case PV_SSTAR:
model = &op_model_rs64;
model->num_counters = 8;
- oprof_ppc64_ops.cpu_type = "ppc64/rs64";
+ ops->cpu_type = "ppc64/rs64";
break;
case PV_POWER4:
case PV_POWER4p:
model = &op_model_power4;
model->num_counters = 8;
- oprof_ppc64_ops.cpu_type = "ppc64/power4";
+ ops->cpu_type = "ppc64/power4";
break;
case PV_970:
case PV_970FX:
model = &op_model_power4;
model->num_counters = 8;
- oprof_ppc64_ops.cpu_type = "ppc64/970";
+ ops->cpu_type = "ppc64/970";
break;
case PV_POWER5:
case PV_POWER5p:
model = &op_model_power4;
model->num_counters = 6;
- oprof_ppc64_ops.cpu_type = "ppc64/power5";
+ ops->cpu_type = "ppc64/power5";
break;
default:
return -ENODEV;
}
- *ops = &oprof_ppc64_ops;
+ ops->create_files = op_ppc64_create_files;
+ ops->setup = op_ppc64_setup;
+ ops->shutdown = op_ppc64_shutdown;
+ ops->start = op_ppc64_start;
+ ops->stop = op_ppc64_stop;
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
- oprof_ppc64_ops.cpu_type);
+ ops->cpu_type);
return 0;
}