cpufreq: cpufreq_stats: Register for bL_switcher notifiers
authorViresh Kumar <viresh.kumar@linaro.org>
Tue, 11 Dec 2012 11:00:01 +0000 (16:30 +0530)
committerJon Medhurst <tixy@linaro.org>
Fri, 19 Jul 2013 12:43:15 +0000 (13:43 +0100)
cpufreq_stat has registered notifiers with both cpufreq and cpu core. It adds
cpu/cpu0/cpufreq/stats/ directory with a notifier of cpufreq CPUFREQ_NOTIFY and
removes this directory with a notifier to cpu core.

On bL_switcher enable/disable, cpufreq drivers notifiers gets called and they
call cpufreq_unregister(), followed by cpufreq_register(). For unregister stats
directories per cpu aren't removed, because cpu never went to dead state and cpu
notifier isn't called.

When cpufreq_register() is called, we try to add these directories again and
that simply fails, as directories were already present.

Fix these issues by registering cpufreq_stats too with bL_switcher notifiers, so
that they get unregistered and registered on switcher enable/disable.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
drivers/cpufreq/cpufreq_stats.c

index fb65decffa28128ded8817441b2e5eff8ecad8e3..cd98e162a23eeb7cdcffa455fb872757a3ca0c8e 100644 (file)
@@ -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;
 
@@ -379,7 +380,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;
@@ -407,7 +408,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;
 
@@ -422,6 +424,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");