12 #include <linux/kernel.h>
13 #include <linux/slab.h>
17 #include <linux/module.h>
23 #include <asm/cputime.h>
27 #define CPUFREQ_STATDEVICE_ATTR(_name, _mode, _show) \
28 static struct freq_attr _attr_##_name = {\
29 .attr = {.name = __stringify(_name), .mode = _mode, }, \
42 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
43 unsigned int *trans_table;
54 static int cpufreq_stats_update(
unsigned int cpu)
57 unsigned long long cur_time;
60 spin_lock(&cpufreq_stats_lock);
61 stat =
per_cpu(cpufreq_stats_table, cpu);
66 spin_unlock(&cpufreq_stats_lock);
76 per_cpu(cpufreq_stats_table, stat->
cpu)->total_trans);
86 cpufreq_stats_update(stat->
cpu);
95 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
104 cpufreq_stats_update(stat->
cpu);
145 static struct attribute *default_attrs[] = {
146 &_attr_total_trans.attr,
147 &_attr_time_in_state.attr,
148 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
149 &_attr_trans_table.attr,
154 .attrs = default_attrs,
161 for (index = 0; index < stat->
max_state; index++)
170 static void cpufreq_stats_free_table(
unsigned int cpu)
183 static void cpufreq_stats_free_sysfs(
unsigned int cpu)
186 if (policy && policy->
cpu == cpu)
192 static int cpufreq_stats_create_table(
struct cpufreq_policy *policy,
198 unsigned int alloc_size;
199 unsigned int cpu = policy->
cpu;
200 if (
per_cpu(cpufreq_stats_table, cpu))
228 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
229 alloc_size += count * count *
sizeof(
int);
239 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
247 if (freq_table_get_index(stat, freq) == -1)
251 spin_lock(&cpufreq_stats_lock);
254 spin_unlock(&cpufreq_stats_lock);
265 static int cpufreq_stat_notifier_policy(
struct notifier_block *nb,
266 unsigned long val,
void *data)
271 unsigned int cpu = policy->
cpu;
277 ret = cpufreq_stats_create_table(policy, table);
284 unsigned long val,
void *data)
288 int old_index, new_index;
293 stat =
per_cpu(cpufreq_stats_table, freq->
cpu);
298 new_index = freq_table_get_index(stat, freq->
new);
301 if (old_index == -1 || new_index == -1)
304 cpufreq_stats_update(freq->
cpu);
306 if (old_index == new_index)
309 spin_lock(&cpufreq_stats_lock);
311 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
312 stat->trans_table[old_index * stat->
max_state + new_index]++;
315 spin_unlock(&cpufreq_stats_lock);
323 unsigned int cpu = (
unsigned long)hcpu;
332 cpufreq_stats_free_sysfs(cpu);
336 cpufreq_stats_free_table(cpu);
344 .notifier_call = cpufreq_stat_cpu_callback,
349 .notifier_call = cpufreq_stat_notifier_policy
353 .notifier_call = cpufreq_stat_notifier_trans
356 static int __init cpufreq_stats_init(
void)
381 static void __exit cpufreq_stats_exit(
void)
391 cpufreq_stats_free_table(cpu);
392 cpufreq_stats_free_sysfs(cpu);
398 "through sysfs filesystem");