#include <asm/cputime.h>
-static void (*pm_idle_old)(void);
static atomic_t active_count = ATOMIC_INIT(0);
struct cpufreq_interactive_cpuinfo {
return;
}
-static void cpufreq_interactive_idle(void)
+static void cpufreq_interactive_idle_start(void)
{
struct cpufreq_interactive_cpuinfo *pcpu =
&per_cpu(cpuinfo, smp_processor_id());
int pending;
if (!pcpu->governor_enabled) {
- pm_idle_old();
return;
}
}
}
- pm_idle_old();
+}
+
+static void cpufreq_interactive_idle_end(void)
+{
+ struct cpufreq_interactive_cpuinfo *pcpu =
+ &per_cpu(cpuinfo, smp_processor_id());
+
pcpu->idling = 0;
smp_wmb();
if (rc)
return rc;
- pm_idle_old = pm_idle;
- pm_idle = cpufreq_interactive_idle;
break;
case CPUFREQ_GOV_STOP:
sysfs_remove_group(cpufreq_global_kobject,
&interactive_attr_group);
- pm_idle = pm_idle_old;
break;
case CPUFREQ_GOV_LIMITS:
return 0;
}
+static int cpufreq_interactive_idle_notifier(struct notifier_block *nb,
+ unsigned long val,
+ void *data)
+{
+ switch (val) {
+ case IDLE_START:
+ cpufreq_interactive_idle_start();
+ break;
+ case IDLE_END:
+ cpufreq_interactive_idle_end();
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block cpufreq_interactive_idle_nb = {
+ .notifier_call = cpufreq_interactive_idle_notifier,
+};
+
static int __init cpufreq_interactive_init(void)
{
unsigned int i;
spin_lock_init(&up_cpumask_lock);
spin_lock_init(&down_cpumask_lock);
+ idle_notifier_register(&cpufreq_interactive_idle_nb);
+
return cpufreq_register_governor(&cpufreq_gov_interactive);
err_freeuptask: