diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq_stats.c')
-rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 591b6fb641b2..a276fb8a8c8f 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -21,6 +21,7 @@ #include <linux/spinlock.h> #include <linux/notifier.h> #include <asm/cputime.h> +#include <asm/bL_switcher.h> static spinlock_t cpufreq_stats_lock; @@ -341,6 +342,27 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb, return 0; } +static int cpufreq_stats_create_table_cpu(unsigned int cpu) +{ + struct cpufreq_policy *policy; + struct cpufreq_frequency_table *table; + int ret = -ENODEV; + + policy = cpufreq_cpu_get(cpu); + if (!policy) + return -ENODEV; + + table = cpufreq_frequency_get_table(cpu); + if (!table) + goto out; + + ret = cpufreq_stats_create_table(policy, table); + +out: + cpufreq_cpu_put(policy); + return ret; +} + static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -362,6 +384,10 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, cpufreq_stats_free_sysfs(cpu); cpufreq_stats_free_table(cpu); break; + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: + cpufreq_stats_create_table_cpu(cpu); + break; } return NOTIFY_OK; } @@ -380,7 +406,7 @@ static struct notifier_block notifier_trans_block = { .notifier_call = cpufreq_stat_notifier_trans }; -static int __init cpufreq_stats_init(void) +static int cpufreq_stats_setup(void) { int ret; unsigned int cpu; @@ -408,7 +434,8 @@ static int __init cpufreq_stats_init(void) return 0; } -static void __exit cpufreq_stats_exit(void) + +static void cpufreq_stats_cleanup(void) { unsigned int cpu; @@ -423,6 +450,49 @@ static void __exit cpufreq_stats_exit(void) } } +static int cpufreq_stats_switcher_notifier(struct notifier_block *nfb, + unsigned long action, void *_arg) +{ + switch (action) { + case BL_NOTIFY_PRE_ENABLE: + case BL_NOTIFY_PRE_DISABLE: + cpufreq_stats_cleanup(); + break; + + case BL_NOTIFY_POST_ENABLE: + case BL_NOTIFY_POST_DISABLE: + cpufreq_stats_setup(); + break; + + default: + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static struct notifier_block switcher_notifier = { + .notifier_call = cpufreq_stats_switcher_notifier, +}; + +static int __init cpufreq_stats_init(void) +{ + int ret; + spin_lock_init(&cpufreq_stats_lock); + + ret = cpufreq_stats_setup(); + if (!ret) + bL_switcher_register_notifier(&switcher_notifier); + + return ret; +} + +static void __exit cpufreq_stats_exit(void) +{ + bL_switcher_unregister_notifier(&switcher_notifier); + cpufreq_stats_cleanup(); +} + MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats " "through sysfs filesystem"); |