Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[sfrench/cifs-2.6.git] / arch / x86 / oprofile / op_model_p4.c
index e6a160a4684a4a9d96914acc161122d6c7f8c208..182558dd5515add420a27dfa58304d04b6a6f71a 100644 (file)
@@ -385,8 +385,26 @@ static unsigned int get_stagger(void)
 
 static unsigned long reset_value[NUM_COUNTERS_NON_HT];
 
+static void p4_shutdown(struct op_msrs const * const msrs)
+{
+       int i;
 
-static void p4_fill_in_addresses(struct op_msrs * const msrs)
+       for (i = 0; i < num_counters; ++i) {
+               if (msrs->counters[i].addr)
+                       release_perfctr_nmi(msrs->counters[i].addr);
+       }
+       /*
+        * some of the control registers are specially reserved in
+        * conjunction with the counter registers (hence the starting offset).
+        * This saves a few bits.
+        */
+       for (i = num_counters; i < num_controls; ++i) {
+               if (msrs->controls[i].addr)
+                       release_evntsel_nmi(msrs->controls[i].addr);
+       }
+}
+
+static int p4_fill_in_addresses(struct op_msrs * const msrs)
 {
        unsigned int i;
        unsigned int addr, cccraddr, stag;
@@ -468,6 +486,18 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
                        msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
                }
        }
+
+       for (i = 0; i < num_counters; ++i) {
+               if (!counter_config[i].enabled)
+                       continue;
+               if (msrs->controls[i].addr)
+                       continue;
+               op_x86_warn_reserved(i);
+               p4_shutdown(msrs);
+               return -EBUSY;
+       }
+
+       return 0;
 }
 
 
@@ -668,26 +698,6 @@ static void p4_stop(struct op_msrs const * const msrs)
        }
 }
 
-static void p4_shutdown(struct op_msrs const * const msrs)
-{
-       int i;
-
-       for (i = 0; i < num_counters; ++i) {
-               if (msrs->counters[i].addr)
-                       release_perfctr_nmi(msrs->counters[i].addr);
-       }
-       /*
-        * some of the control registers are specially reserved in
-        * conjunction with the counter registers (hence the starting offset).
-        * This saves a few bits.
-        */
-       for (i = num_counters; i < num_controls; ++i) {
-               if (msrs->controls[i].addr)
-                       release_evntsel_nmi(msrs->controls[i].addr);
-       }
-}
-
-
 #ifdef CONFIG_SMP
 struct op_x86_model_spec op_p4_ht2_spec = {
        .num_counters           = NUM_COUNTERS_HT2,