These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / cpufreq / acpi-cpufreq.c
index b0c18ed..cec1ee2 100644 (file)
@@ -65,18 +65,21 @@ enum {
 #define MSR_K7_HWCR_CPB_DIS    (1ULL << 25)
 
 struct acpi_cpufreq_data {
-       struct acpi_processor_performance *acpi_data;
        struct cpufreq_frequency_table *freq_table;
        unsigned int resume;
        unsigned int cpu_feature;
+       unsigned int acpi_perf_cpu;
        cpumask_var_t freqdomain_cpus;
 };
 
-static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
-
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance __percpu *acpi_perf_data;
 
+static inline struct acpi_processor_performance *to_perf_data(struct acpi_cpufreq_data *data)
+{
+       return per_cpu_ptr(acpi_perf_data, data->acpi_perf_cpu);
+}
+
 static struct cpufreq_driver acpi_cpufreq_driver;
 
 static unsigned int acpi_pstate_strict;
@@ -144,7 +147,10 @@ static int _store_boost(int val)
 
 static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
 {
-       struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+       struct acpi_cpufreq_data *data = policy->driver_data;
+
+       if (unlikely(!data))
+               return -ENODEV;
 
        return cpufreq_show_cpus(data->freqdomain_cpus, buf);
 }
@@ -202,7 +208,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
        struct acpi_processor_performance *perf;
        int i;
 
-       perf = data->acpi_data;
+       perf = to_perf_data(data);
 
        for (i = 0; i < perf->state_count; i++) {
                if (value == perf->states[i].status)
@@ -221,7 +227,7 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
        else
                msr &= INTEL_MSR_RANGE;
 
-       perf = data->acpi_data;
+       perf = to_perf_data(data);
 
        cpufreq_for_each_entry(pos, data->freq_table)
                if (msr == perf->states[pos->driver_data].status)
@@ -327,7 +333,8 @@ static void drv_write(struct drv_cmd *cmd)
        put_cpu();
 }
 
-static u32 get_cur_val(const struct cpumask *mask)
+static u32
+get_cur_val(const struct cpumask *mask, struct acpi_cpufreq_data *data)
 {
        struct acpi_processor_performance *perf;
        struct drv_cmd cmd;
@@ -335,7 +342,7 @@ static u32 get_cur_val(const struct cpumask *mask)
        if (unlikely(cpumask_empty(mask)))
                return 0;
 
-       switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) {
+       switch (data->cpu_feature) {
        case SYSTEM_INTEL_MSR_CAPABLE:
                cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
                cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
@@ -346,7 +353,7 @@ static u32 get_cur_val(const struct cpumask *mask)
                break;
        case SYSTEM_IO_CAPABLE:
                cmd.type = SYSTEM_IO_CAPABLE;
-               perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data;
+               perf = to_perf_data(data);
                cmd.addr.io.port = perf->control_register.address;
                cmd.addr.io.bit_width = perf->control_register.bit_width;
                break;
@@ -364,19 +371,23 @@ static u32 get_cur_val(const struct cpumask *mask)
 
 static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
 {
-       struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);
+       struct acpi_cpufreq_data *data;
+       struct cpufreq_policy *policy;
        unsigned int freq;
        unsigned int cached_freq;
 
        pr_debug("get_cur_freq_on_cpu (%d)\n", cpu);
 
-       if (unlikely(data == NULL ||
-                    data->acpi_data == NULL || data->freq_table == NULL)) {
+       policy = cpufreq_cpu_get_raw(cpu);
+       if (unlikely(!policy))
+               return 0;
+
+       data = policy->driver_data;
+       if (unlikely(!data || !data->freq_table))
                return 0;
-       }
 
-       cached_freq = data->freq_table[data->acpi_data->state].frequency;
-       freq = extract_freq(get_cur_val(cpumask_of(cpu)), data);
+       cached_freq = data->freq_table[to_perf_data(data)->state].frequency;
+       freq = extract_freq(get_cur_val(cpumask_of(cpu), data), data);
        if (freq != cached_freq) {
                /*
                 * The dreaded BIOS frequency change behind our back.
@@ -397,7 +408,7 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
        unsigned int i;
 
        for (i = 0; i < 100; i++) {
-               cur_freq = extract_freq(get_cur_val(mask), data);
+               cur_freq = extract_freq(get_cur_val(mask, data), data);
                if (cur_freq == freq)
                        return 1;
                udelay(10);
@@ -408,18 +419,17 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
 static int acpi_cpufreq_target(struct cpufreq_policy *policy,
                               unsigned int index)
 {
-       struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+       struct acpi_cpufreq_data *data = policy->driver_data;
        struct acpi_processor_performance *perf;
        struct drv_cmd cmd;
        unsigned int next_perf_state = 0; /* Index into perf table */
        int result = 0;
 
-       if (unlikely(data == NULL ||
-            data->acpi_data == NULL || data->freq_table == NULL)) {
+       if (unlikely(data == NULL || data->freq_table == NULL)) {
                return -ENODEV;
        }
 
-       perf = data->acpi_data;
+       perf = to_perf_data(data);
        next_perf_state = data->freq_table[index].driver_data;
        if (perf->state == next_perf_state) {
                if (unlikely(data->resume)) {
@@ -482,8 +492,9 @@ out:
 static unsigned long
 acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
 {
-       struct acpi_processor_performance *perf = data->acpi_data;
+       struct acpi_processor_performance *perf;
 
+       perf = to_perf_data(data);
        if (cpu_khz) {
                /* search the closest match to cpu_khz */
                unsigned int i;
@@ -672,17 +683,17 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
                goto err_free;
        }
 
-       data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
-       per_cpu(acfreq_data, cpu) = data;
+       perf = per_cpu_ptr(acpi_perf_data, cpu);
+       data->acpi_perf_cpu = cpu;
+       policy->driver_data = data;
 
        if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
                acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
 
-       result = acpi_processor_register_performance(data->acpi_data, cpu);
+       result = acpi_processor_register_performance(perf, cpu);
        if (result)
                goto err_free_mask;
 
-       perf = data->acpi_data;
        policy->shared_type = perf->shared_type;
 
        /*
@@ -699,13 +710,14 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        dmi_check_system(sw_any_bug_dmi_table);
        if (bios_with_sw_any_bug && !policy_is_shared(policy)) {
                policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
-               cpumask_copy(policy->cpus, cpu_core_mask(cpu));
+               cpumask_copy(policy->cpus, topology_core_cpumask(cpu));
        }
 
        if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) {
                cpumask_clear(policy->cpus);
                cpumask_set_cpu(cpu, policy->cpus);
-               cpumask_copy(data->freqdomain_cpus, cpu_sibling_mask(cpu));
+               cpumask_copy(data->freqdomain_cpus,
+                            topology_sibling_cpumask(cpu));
                policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
                pr_info_once(PFX "overriding BIOS provided _PSD data\n");
        }
@@ -837,26 +849,25 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 err_freqfree:
        kfree(data->freq_table);
 err_unreg:
-       acpi_processor_unregister_performance(perf, cpu);
+       acpi_processor_unregister_performance(cpu);
 err_free_mask:
        free_cpumask_var(data->freqdomain_cpus);
 err_free:
        kfree(data);
-       per_cpu(acfreq_data, cpu) = NULL;
+       policy->driver_data = NULL;
 
        return result;
 }
 
 static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
-       struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+       struct acpi_cpufreq_data *data = policy->driver_data;
 
        pr_debug("acpi_cpufreq_cpu_exit\n");
 
        if (data) {
-               per_cpu(acfreq_data, policy->cpu) = NULL;
-               acpi_processor_unregister_performance(data->acpi_data,
-                                                     policy->cpu);
+               policy->driver_data = NULL;
+               acpi_processor_unregister_performance(data->acpi_perf_cpu);
                free_cpumask_var(data->freqdomain_cpus);
                kfree(data->freq_table);
                kfree(data);
@@ -867,7 +878,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 
 static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
 {
-       struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+       struct acpi_cpufreq_data *data = policy->driver_data;
 
        pr_debug("acpi_cpufreq_resume\n");
 
@@ -879,7 +890,9 @@ static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
 static struct freq_attr *acpi_cpufreq_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
        &freqdomain_cpus,
-       NULL,   /* this is a placeholder for cpb, do not remove */
+#ifdef CONFIG_X86_ACPI_CPUFREQ_CPB
+       &cpb,
+#endif
        NULL,
 };
 
@@ -952,17 +965,16 @@ static int __init acpi_cpufreq_init(void)
         * only if configured. This is considered legacy code, which
         * will probably be removed at some point in the future.
         */
-       if (check_amd_hwpstate_cpu(0)) {
-               struct freq_attr **iter;
+       if (!check_amd_hwpstate_cpu(0)) {
+               struct freq_attr **attr;
 
-               pr_debug("adding sysfs entry for cpb\n");
+               pr_debug("CPB unsupported, do not expose it\n");
 
-               for (iter = acpi_cpufreq_attr; *iter != NULL; iter++)
-                       ;
-
-               /* make sure there is a terminator behind it */
-               if (iter[1] == NULL)
-                       *iter = &cpb;
+               for (attr = acpi_cpufreq_attr; *attr; attr++)
+                       if (*attr == &cpb) {
+                               *attr = NULL;
+                               break;
+                       }
        }
 #endif
        acpi_cpufreq_boost_init();