--- drivers/cpufreq/cpufreq_governor.c | 40 +++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) Index: linux-pm/drivers/cpufreq/cpufreq_governor.c =================================================================== --- linux-pm.orig/drivers/cpufreq/cpufreq_governor.c +++ linux-pm/drivers/cpufreq/cpufreq_governor.c @@ -379,8 +379,8 @@ static int cpufreq_governor_init(struct struct dbs_governor *gov = dbs_governor_of(policy); struct dbs_data *dbs_data; struct policy_dbs_info *policy_dbs; - unsigned int latency; - int ret = 0; + unsigned int latency, io_busy; + int j, ret = 0; /* State should be equivalent to EXIT */ if (policy->governor_data) @@ -439,9 +439,22 @@ static int cpufreq_governor_init(struct ret = kobject_init_and_add(&dbs_data->attr_set.kobj, &gov->kobj_type, get_governor_parent_kobj(policy), "%s", gov->gov.name); - if (!ret) - goto out; + if (ret) + goto fail; + + io_busy = dbs_data->io_is_busy; + for_each_cpu(j, policy->cpus) { + struct cpu_dbs_info *j_cdbs = &per_cpu(cpu_dbs, j); + + j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, &j_cdbs->prev_cpu_wall, io_busy); + } + +out: + mutex_unlock(&gov_dbs_data_mutex); + return ret; + +fail: /* Failure, so roll back. */ pr_err("cpufreq: Governor initialization failed (dbs_data kobject init error %d)\n", ret); @@ -454,10 +467,7 @@ static int cpufreq_governor_init(struct free_policy_dbs_info: free_policy_dbs_info(policy_dbs, gov); - -out: - mutex_unlock(&gov_dbs_data_mutex); - return ret; + goto out; } static int cpufreq_governor_exit(struct cpufreq_policy *policy) @@ -508,12 +518,18 @@ static int cpufreq_governor_start(struct for_each_cpu(j, policy->cpus) { struct cpu_dbs_info *j_cdbs = &per_cpu(cpu_dbs, j); - unsigned int prev_load; + u64 cur_uptime, cur_idle_time; + unsigned int uptime, idle_time; - j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, &j_cdbs->prev_cpu_wall, io_busy); + cur_idle_time = get_cpu_idle_time(j, &cur_uptime, io_busy); + + uptime = cur_uptime - j_cdbs->prev_cpu_wall; + j_cdbs->prev_cpu_wall = cur_uptime; + + idle_time = cur_idle_time - j_cdbs->prev_cpu_idle; + j_cdbs->prev_cpu_idle = cur_idle_time; - prev_load = j_cdbs->prev_cpu_wall - j_cdbs->prev_cpu_idle; - j_cdbs->prev_load = 100 * prev_load / (unsigned int)j_cdbs->prev_cpu_wall; + j_cdbs->prev_load = 100 * idle_time / uptime; if (ignore_nice) j_cdbs->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE];