]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/cpufreq/acpi-cpufreq.c
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[karo-tx-linux.git] / drivers / cpufreq / acpi-cpufreq.c
index 297e9128fe9fe11948352f16984a3a85e5e0cdb5..3a98702b7445f747d9a710f16753d29e312b17a6 100644 (file)
@@ -84,7 +84,6 @@ static inline struct acpi_processor_performance *to_perf_data(struct acpi_cpufre
 static struct cpufreq_driver acpi_cpufreq_driver;
 
 static unsigned int acpi_pstate_strict;
-static struct msr __percpu *msrs;
 
 static bool boost_state(unsigned int cpu)
 {
@@ -104,11 +103,10 @@ static bool boost_state(unsigned int cpu)
        return false;
 }
 
-static void boost_set_msrs(bool enable, const struct cpumask *cpumask)
+static int boost_set_msr(bool enable)
 {
-       u32 cpu;
        u32 msr_addr;
-       u64 msr_mask;
+       u64 msr_mask, val;
 
        switch (boot_cpu_data.x86_vendor) {
        case X86_VENDOR_INTEL:
@@ -120,26 +118,31 @@ static void boost_set_msrs(bool enable, const struct cpumask *cpumask)
                msr_mask = MSR_K7_HWCR_CPB_DIS;
                break;
        default:
-               return;
+               return -EINVAL;
        }
 
-       rdmsr_on_cpus(cpumask, msr_addr, msrs);
+       rdmsrl(msr_addr, val);
 
-       for_each_cpu(cpu, cpumask) {
-               struct msr *reg = per_cpu_ptr(msrs, cpu);
-               if (enable)
-                       reg->q &= ~msr_mask;
-               else
-                       reg->q |= msr_mask;
-       }
+       if (enable)
+               val &= ~msr_mask;
+       else
+               val |= msr_mask;
+
+       wrmsrl(msr_addr, val);
+       return 0;
+}
+
+static void boost_set_msr_each(void *p_en)
+{
+       bool enable = (bool) p_en;
 
-       wrmsr_on_cpus(cpumask, msr_addr, msrs);
+       boost_set_msr(enable);
 }
 
 static int set_boost(int val)
 {
        get_online_cpus();
-       boost_set_msrs(val, cpu_online_mask);
+       on_each_cpu(boost_set_msr_each, (void *)(long)val, 1);
        put_online_cpus();
        pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis");
 
@@ -536,46 +539,24 @@ static void free_acpi_perf_data(void)
        free_percpu(acpi_perf_data);
 }
 
-static int boost_notify(struct notifier_block *nb, unsigned long action,
-                     void *hcpu)
+static int cpufreq_boost_online(unsigned int cpu)
 {
-       unsigned cpu = (long)hcpu;
-       const struct cpumask *cpumask;
-
-       cpumask = get_cpu_mask(cpu);
+       /*
+        * On the CPU_UP path we simply keep the boost-disable flag
+        * in sync with the current global state.
+        */
+       return boost_set_msr(acpi_cpufreq_driver.boost_enabled);
+}
 
+static int cpufreq_boost_down_prep(unsigned int cpu)
+{
        /*
         * Clear the boost-disable bit on the CPU_DOWN path so that
-        * this cpu cannot block the remaining ones from boosting. On
-        * the CPU_UP path we simply keep the boost-disable flag in
-        * sync with the current global state.
+        * this cpu cannot block the remaining ones from boosting.
         */
-
-       switch (action) {
-       case CPU_DOWN_FAILED:
-       case CPU_DOWN_FAILED_FROZEN:
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask);
-               break;
-
-       case CPU_DOWN_PREPARE:
-       case CPU_DOWN_PREPARE_FROZEN:
-               boost_set_msrs(1, cpumask);
-               break;
-
-       default:
-               break;
-       }
-
-       return NOTIFY_OK;
+       return boost_set_msr(1);
 }
 
-
-static struct notifier_block boost_nb = {
-       .notifier_call          = boost_notify,
-};
-
 /*
  * acpi_cpufreq_early_init - initialize ACPI P-States library
  *
@@ -922,37 +903,35 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
        .attr           = acpi_cpufreq_attr,
 };
 
+static enum cpuhp_state acpi_cpufreq_online;
+
 static void __init acpi_cpufreq_boost_init(void)
 {
-       if (boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA)) {
-               msrs = msrs_alloc();
-
-               if (!msrs)
-                       return;
-
-               acpi_cpufreq_driver.set_boost = set_boost;
-               acpi_cpufreq_driver.boost_enabled = boost_state(0);
-
-               cpu_notifier_register_begin();
+       int ret;
 
-               /* Force all MSRs to the same value */
-               boost_set_msrs(acpi_cpufreq_driver.boost_enabled,
-                              cpu_online_mask);
+       if (!(boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA)))
+               return;
 
-               __register_cpu_notifier(&boost_nb);
+       acpi_cpufreq_driver.set_boost = set_boost;
+       acpi_cpufreq_driver.boost_enabled = boost_state(0);
 
-               cpu_notifier_register_done();
+       /*
+        * This calls the online callback on all online cpu and forces all
+        * MSRs to the same value.
+        */
+       ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "cpufreq/acpi:online",
+                               cpufreq_boost_online, cpufreq_boost_down_prep);
+       if (ret < 0) {
+               pr_err("acpi_cpufreq: failed to register hotplug callbacks\n");
+               return;
        }
+       acpi_cpufreq_online = ret;
 }
 
 static void acpi_cpufreq_boost_exit(void)
 {
-       if (msrs) {
-               unregister_cpu_notifier(&boost_nb);
-
-               msrs_free(msrs);
-               msrs = NULL;
-       }
+       if (acpi_cpufreq_online >= 0)
+               cpuhp_remove_state_nocalls(acpi_cpufreq_online);
 }
 
 static int __init acpi_cpufreq_init(void)