]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - arch/powerpc/oprofile/common.c
[POWERPC] re-enable OProfile for iSeries, using timer interrupt
[linux-2.6.git] / arch / powerpc / oprofile / common.c
index af2c05d20ba57aaf3c39e06da889f97ad974c403..27ad56bd227e7af5215c6803c40e860a778364bd 100644 (file)
@@ -14,9 +14,6 @@
  */
 
 #include <linux/oprofile.h>
-#ifndef __powerpc64__
-#include <linux/slab.h>
-#endif /* ! __powerpc64__ */
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/errno.h>
 #include <asm/pmc.h>
 #include <asm/cputable.h>
 #include <asm/oprofile_impl.h>
+#include <asm/firmware.h>
 
 static struct op_powerpc_model *model;
 
 static struct op_counter_config ctr[OP_MAX_COUNTER];
 static struct op_system_config sys;
 
-#ifndef __powerpc64__
-static char *cpu_type;
-#endif /* ! __powerpc64__ */
-
 static void op_handle_interrupt(struct pt_regs *regs)
 {
        model->handle_interrupt(regs, ctr);
@@ -53,14 +47,7 @@ static int op_powerpc_setup(void)
        model->reg_setup(ctr, &sys, model->num_counters);
 
        /* Configure the registers on all cpus.  */
-#ifdef __powerpc64__
        on_each_cpu(model->cpu_setup, NULL, 0, 1);
-#else /* __powerpc64__ */
-#if 0
-       /* FIXME: Make multi-cpu work */
-       on_each_cpu(model->reg_setup, NULL, 0, 1);
-#endif
-#endif /* __powerpc64__ */
 
        return 0;
 }
@@ -95,7 +82,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
 {
        int i;
 
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
        /*
         * There is one mmcr0, mmcr1 and mmcra for setting the events for
         * all of the counters.
@@ -103,7 +90,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
        oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
        oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
        oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
-#endif /* __powerpc64__ */
+#endif
 
        for (i = 0; i < model->num_counters; ++i) {
                struct dentry *dir;
@@ -115,72 +102,71 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
                oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
                oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
                oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
-#ifdef __powerpc64__
+
                /*
-                * We dont support per counter user/kernel selection, but
-                * we leave the entries because userspace expects them
+                * Classic PowerPC doesn't support per-counter
+                * control like this, but the options are
+                * expected, so they remain.  For Freescale
+                * Book-E style performance monitors, we do
+                * support them.
                 */
-#endif /* __powerpc64__ */
                oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
                oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
 
-#ifndef __powerpc64__
-               /* FIXME: Not sure if this is used */
-#endif /* ! __powerpc64__ */
                oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
        }
 
        oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
        oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
-#ifdef __powerpc64__
-       oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
-                               &sys.backtrace_spinlocks);
-#endif /* __powerpc64__ */
 
        /* Default to tracing both kernel and user */
        sys.enable_kernel = 1;
        sys.enable_user = 1;
-#ifdef __powerpc64__
-       /* Turn on backtracing through spinlocks by default */
-       sys.backtrace_spinlocks = 1;
-#endif /* __powerpc64__ */
 
        return 0;
 }
 
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
-#ifndef __powerpc64__
-#ifdef CONFIG_FSL_BOOKE
-       model = &op_model_fsl_booke;
-#else
-       return -ENODEV;
-#endif
-
-       cpu_type = kmalloc(32, GFP_KERNEL);
-       if (NULL == cpu_type)
-               return -ENOMEM;
+       if (!cur_cpu_spec->oprofile_cpu_type)
+               return -ENODEV;
 
-       sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name);
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return -ENODEV;
 
-       model->num_counters = cur_cpu_spec->num_pmcs;
+       switch (cur_cpu_spec->oprofile_type) {
+#ifdef CONFIG_PPC64
+               case PPC_OPROFILE_RS64:
+                       model = &op_model_rs64;
+                       break;
+               case PPC_OPROFILE_POWER4:
+                       model = &op_model_power4;
+                       break;
+#else
+               case PPC_OPROFILE_G4:
+                       model = &op_model_7450;
+                       break;
+#endif
+#ifdef CONFIG_FSL_BOOKE
+               case PPC_OPROFILE_BOOKE:
+                       model = &op_model_fsl_booke;
+                       break;
+#endif
+               default:
+                       return -ENODEV;
+       }
 
-       ops->cpu_type = cpu_type;
-#else /* __powerpc64__ */
-       if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
-               return -ENODEV;
-       model = cur_cpu_spec->oprofile_model;
        model->num_counters = cur_cpu_spec->num_pmcs;
 
        ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
-#endif /* __powerpc64__ */
        ops->create_files = op_powerpc_create_files;
        ops->setup = op_powerpc_setup;
        ops->shutdown = op_powerpc_shutdown;
        ops->start = op_powerpc_start;
        ops->stop = op_powerpc_stop;
+       ops->backtrace = op_powerpc_backtrace;
 
-       printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+       printk(KERN_DEBUG "oprofile: using %s performance monitoring.\n",
               ops->cpu_type);
 
        return 0;
@@ -188,8 +174,4 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 
 void oprofile_arch_exit(void)
 {
-#ifndef __powerpc64__
-       kfree(cpu_type);
-       cpu_type = NULL;
-#endif /* ! __powerpc64__ */
 }