]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/cpufreq/cpufreq_stats.c
cpufreq: Simplify __cpufreq_remove_dev()
[mirror_ubuntu-artful-kernel.git] / drivers / cpufreq / cpufreq_stats.c
index 9d7732b810445f6b73318e574924b6bed6ac6829..beef6b54382b2982c4d86f6312af5c9e052e3636 100644 (file)
@@ -170,11 +170,13 @@ static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
 static void cpufreq_stats_free_table(unsigned int cpu)
 {
        struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu);
+
        if (stat) {
+               pr_debug("%s: Free stat table\n", __func__);
                kfree(stat->time_in_state);
                kfree(stat);
+               per_cpu(cpufreq_stats_table, cpu) = NULL;
        }
-       per_cpu(cpufreq_stats_table, cpu) = NULL;
 }
 
 /* must be called early in the CPU removal sequence (before
@@ -183,8 +185,10 @@ static void cpufreq_stats_free_table(unsigned int cpu)
 static void cpufreq_stats_free_sysfs(unsigned int cpu)
 {
        struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-       if (policy && policy->cpu == cpu)
+       if (policy && (cpumask_weight(policy->cpus) == 1)) {
+               pr_debug("%s: Free sysfs stat\n", __func__);
                sysfs_remove_group(&policy->kobj, &stats_attr_group);
+       }
        if (policy)
                cpufreq_cpu_put(policy);
 }
@@ -262,6 +266,19 @@ error_get_fail:
        return ret;
 }
 
+static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy)
+{
+       struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table,
+                       policy->last_cpu);
+
+       pr_debug("Updating stats_table for new_cpu %u from last_cpu %u\n",
+                       policy->cpu, policy->last_cpu);
+       per_cpu(cpufreq_stats_table, policy->cpu) = per_cpu(cpufreq_stats_table,
+                       policy->last_cpu);
+       per_cpu(cpufreq_stats_table, policy->last_cpu) = NULL;
+       stat->cpu = policy->cpu;
+}
+
 static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
                unsigned long val, void *data)
 {
@@ -269,6 +286,12 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
        struct cpufreq_policy *policy = data;
        struct cpufreq_frequency_table *table;
        unsigned int cpu = policy->cpu;
+
+       if (val == CPUFREQ_UPDATE_POLICY_CPU) {
+               cpufreq_stats_update_policy_cpu(policy);
+               return 0;
+       }
+
        if (val != CPUFREQ_NOTIFY)
                return 0;
        table = cpufreq_frequency_get_table(cpu);