diff options
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index c315ec9d5686..c136b787c5af 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -59,7 +59,7 @@ static int cpufreq_stats_update(unsigned int cpu) cur_time = get_jiffies_64(); spin_lock(&cpufreq_stats_lock); stat = per_cpu(cpufreq_stats_table, cpu); - if (stat->time_in_state) + if (stat->time_in_state && stat->last_index >= 0) stat->time_in_state[stat->last_index] = cputime64_add(stat->time_in_state[stat->last_index], cputime_sub(cur_time, stat->last_time)); @@ -159,10 +159,10 @@ static struct attribute_group stats_attr_group = { static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) { int index; - for (index = 0; index < stat->max_state; index++) - if (stat->freq_table[index] == freq) - return index; - return -1; + for (index = 0; index < stat->state_num; index++) + if (stat->freq_table[index] > freq) + break; + return index - 1; /* below lowest freq in table: return -1 */ } /* should be called late in the CPU removal sequence so that the stats @@ -193,7 +193,7 @@ static void cpufreq_stats_free_sysfs(unsigned int cpu) static int cpufreq_stats_create_table(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table) { - unsigned int i, j, count = 0, ret = 0; + unsigned int i, j, k, l, count = 0, ret = 0; struct cpufreq_stats *stat; struct cpufreq_policy *data; unsigned int alloc_size; @@ -245,8 +245,16 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, unsigned int freq = table[i].frequency; if (freq == CPUFREQ_ENTRY_INVALID) continue; - if (freq_table_get_index(stat, freq) == -1) - stat->freq_table[j++] = freq; + + /* Insert in sorted stat->freq_table */ + for (k = 0; k < j && stat->freq_table[k] < freq; k++) + ; + if (stat->freq_table[k] == freq) + continue; + for (l = j; l > k; l--) + stat->freq_table[l] = stat->freq_table[l - 1]; + stat->freq_table[k] = freq; + j++; } stat->state_num = j; spin_lock(&cpufreq_stats_lock); @@ -298,10 +306,6 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, old_index = stat->last_index; new_index = freq_table_get_index(stat, freq->new); - /* We can't do stat->time_in_state[-1]= .. */ - if (old_index == -1 || new_index == -1) - return 0; - cpufreq_stats_update(freq->cpu); if (old_index == new_index) @@ -310,7 +314,8 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, spin_lock(&cpufreq_stats_lock); stat->last_index = new_index; #ifdef CONFIG_CPU_FREQ_STAT_DETAILS - stat->trans_table[old_index * stat->max_state + new_index]++; + if (old_index >= 0 && new_index >= 0) + stat->trans_table[old_index * stat->max_state + new_index]++; #endif stat->total_trans++; spin_unlock(&cpufreq_stats_lock); |