Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[pandora-kernel.git] / drivers / cpufreq / cpufreq_ondemand.c
index 8532bb7..d2af20d 100644 (file)
@@ -47,7 +47,7 @@ static unsigned int def_sampling_rate;
                        (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
 #define MAX_SAMPLING_RATE                      (500 * def_sampling_rate)
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER   (1000)
-#define TRANSITION_LATENCY_LIMIT               (10 * 1000)
+#define TRANSITION_LATENCY_LIMIT               (10 * 1000 * 1000)
 
 static void do_dbs_timer(struct work_struct *work);
 
@@ -96,15 +96,25 @@ static struct dbs_tuners {
 
 static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
 {
-       cputime64_t retval;
+       cputime64_t idle_time;
+       cputime64_t cur_jiffies;
+       cputime64_t busy_time;
 
-       retval = cputime64_add(kstat_cpu(cpu).cpustat.idle,
-                       kstat_cpu(cpu).cpustat.iowait);
+       cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
+       busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user,
+                       kstat_cpu(cpu).cpustat.system);
 
-       if (dbs_tuners_ins.ignore_nice)
-               retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice);
+       busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
+       busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
+       busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
 
-       return retval;
+       if (!dbs_tuners_ins.ignore_nice) {
+               busy_time = cputime64_add(busy_time,
+                               kstat_cpu(cpu).cpustat.nice);
+       }
+
+       idle_time = cputime64_sub(cur_jiffies, busy_time);
+       return idle_time;
 }
 
 /*
@@ -325,7 +335,7 @@ static struct attribute_group dbs_attr_group = {
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 {
        unsigned int idle_ticks, total_ticks;
-       unsigned int load;
+       unsigned int load = 0;
        cputime64_t cur_jiffies;
 
        struct cpufreq_policy *policy;
@@ -339,7 +349,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
        cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
        total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
                        this_dbs_info->prev_cpu_wall);
-       this_dbs_info->prev_cpu_wall = cur_jiffies;
+       this_dbs_info->prev_cpu_wall = get_jiffies_64();
+
        if (!total_ticks)
                return;
        /*
@@ -370,7 +381,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                if (tmp_idle_ticks < idle_ticks)
                        idle_ticks = tmp_idle_ticks;
        }
-       load = (100 * (total_ticks - idle_ticks)) / total_ticks;
+       if (likely(total_ticks > idle_ticks))
+               load = (100 * (total_ticks - idle_ticks)) / total_ticks;
 
        /* Check for frequency increase */
        if (load > dbs_tuners_ins.up_threshold) {
@@ -496,12 +508,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                if ((!cpu_online(cpu)) || (!policy->cur))
                        return -EINVAL;
 
-               if (policy->cpuinfo.transition_latency >
-                               (TRANSITION_LATENCY_LIMIT * 1000)) {
-                       printk(KERN_WARNING "ondemand governor failed to load "
-                              "due to too long transition latency\n");
-                       return -EINVAL;
-               }
                if (this_dbs_info->enable) /* Already enabled */
                        break;
 
@@ -573,11 +579,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
        return 0;
 }
 
-static struct cpufreq_governor cpufreq_gov_dbs = {
-       .name = "ondemand",
-       .governor = cpufreq_governor_dbs,
-       .owner = THIS_MODULE,
+struct cpufreq_governor cpufreq_gov_ondemand = {
+       .name                   = "ondemand",
+       .governor               = cpufreq_governor_dbs,
+       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+       .owner                  = THIS_MODULE,
 };
+EXPORT_SYMBOL(cpufreq_gov_ondemand);
 
 static int __init cpufreq_gov_dbs_init(void)
 {
@@ -586,12 +594,12 @@ static int __init cpufreq_gov_dbs_init(void)
                printk(KERN_ERR "Creation of kondemand failed\n");
                return -EFAULT;
        }
-       return cpufreq_register_governor(&cpufreq_gov_dbs);
+       return cpufreq_register_governor(&cpufreq_gov_ondemand);
 }
 
 static void __exit cpufreq_gov_dbs_exit(void)
 {
-       cpufreq_unregister_governor(&cpufreq_gov_dbs);
+       cpufreq_unregister_governor(&cpufreq_gov_ondemand);
        destroy_workqueue(kondemand_wq);
 }
 
@@ -602,6 +610,9 @@ MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
                    "Low Latency Frequency Transition capable processors");
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
+fs_initcall(cpufreq_gov_dbs_init);
+#else
 module_init(cpufreq_gov_dbs_init);
+#endif
 module_exit(cpufreq_gov_dbs_exit);
-