on_each_cpu(): kill unused 'retry' parameter
[safe/jmp/linux-2.6] / arch / powerpc / oprofile / common.c
index cc2535b..17807ac 100644 (file)
 #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;
 
+static int op_per_cpu_rc;
+
 static void op_handle_interrupt(struct pt_regs *regs)
 {
        model->handle_interrupt(regs, ctr);
 }
 
+static void op_powerpc_cpu_setup(void *dummy)
+{
+       int ret;
+
+       ret = model->cpu_setup(ctr);
+
+       if (ret != 0)
+               op_per_cpu_rc = ret;
+}
+
 static int op_powerpc_setup(void)
 {
        int err;
 
+       op_per_cpu_rc = 0;
+
        /* 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);
+       op_per_cpu_rc = model->reg_setup(ctr, &sys, model->num_counters);
 
-       /* Configure the registers on all cpus.  */
-       on_each_cpu(model->cpu_setup, NULL, 0, 1);
+       if (op_per_cpu_rc)
+               goto out;
 
-       return 0;
+       /* Configure the registers on all cpus.  If an error occurs on one
+        * of the cpus, op_per_cpu_rc will be set to the error */
+       on_each_cpu(op_powerpc_cpu_setup, NULL, 1);
+
+out:   if (op_per_cpu_rc) {
+               /* error on setup release the performance counter hardware */
+               release_pmc_hardware();
+       }
+
+       return op_per_cpu_rc;
 }
 
 static void op_powerpc_shutdown(void)
@@ -58,13 +82,29 @@ static void op_powerpc_shutdown(void)
 
 static void op_powerpc_cpu_start(void *dummy)
 {
-       model->start(ctr);
+       /* If any of the cpus have return an error, set the
+        * global flag to the error so it can be returned
+        * to the generic OProfile caller.
+        */
+       int ret;
+
+       ret = model->start(ctr);
+       if (ret != 0)
+               op_per_cpu_rc = ret;
 }
 
 static int op_powerpc_start(void)
 {
-       on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
-       return 0;
+       op_per_cpu_rc = 0;
+
+       if (model->global_start)
+               return model->global_start(ctr);
+       if (model->start) {
+               on_each_cpu(op_powerpc_cpu_start, NULL, 1);
+               return op_per_cpu_rc;
+       }
+       return -EIO; /* No start function is defined for this
+                       power architecture */
 }
 
 static inline void op_powerpc_cpu_stop(void *dummy)
@@ -74,7 +114,10 @@ static inline void op_powerpc_cpu_stop(void *dummy)
 
 static void op_powerpc_stop(void)
 {
-       on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1);
+       if (model->stop)
+               on_each_cpu(op_powerpc_cpu_stop, NULL, 1);
+        if (model->global_stop)
+                model->global_stop();
 }
 
 static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
@@ -93,7 +136,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
 
        for (i = 0; i < model->num_counters; ++i) {
                struct dentry *dir;
-               char buf[3];
+               char buf[4];
 
                snprintf(buf, sizeof buf, "%d", i);
                dir = oprofilefs_mkdir(sb, root, buf);
@@ -117,18 +160,10 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
 
        oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
        oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
-#ifdef CONFIG_PPC64
-       oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
-                               &sys.backtrace_spinlocks);
-#endif
 
        /* Default to tracing both kernel and user */
        sys.enable_kernel = 1;
        sys.enable_user = 1;
-#ifdef CONFIG_PPC64
-       /* Turn on backtracing through spinlocks by default */
-       sys.backtrace_spinlocks = 1;
-#endif
 
        return 0;
 }
@@ -138,22 +173,38 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        if (!cur_cpu_spec->oprofile_cpu_type)
                return -ENODEV;
 
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return -ENODEV;
+
        switch (cur_cpu_spec->oprofile_type) {
 #ifdef CONFIG_PPC64
+#ifdef CONFIG_OPROFILE_CELL
+               case PPC_OPROFILE_CELL:
+                       if (firmware_has_feature(FW_FEATURE_LPAR))
+                               return -ENODEV;
+                       model = &op_model_cell;
+                       ops->sync_start = model->sync_start;
+                       ops->sync_stop = model->sync_stop;
+                       break;
+#endif
                case PPC_OPROFILE_RS64:
                        model = &op_model_rs64;
                        break;
                case PPC_OPROFILE_POWER4:
                        model = &op_model_power4;
                        break;
-#else
+               case PPC_OPROFILE_PA6T:
+                       model = &op_model_pa6t;
+                       break;
+#endif
+#ifdef CONFIG_6xx
                case PPC_OPROFILE_G4:
                        model = &op_model_7450;
                        break;
 #endif
-#ifdef CONFIG_FSL_BOOKE
-               case PPC_OPROFILE_BOOKE:
-                       model = &op_model_fsl_booke;
+#if defined(CONFIG_FSL_EMB_PERFMON)
+               case PPC_OPROFILE_FSL_EMB:
+                       model = &op_model_fsl_emb;
                        break;
 #endif
                default:
@@ -168,8 +219,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        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;