aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-10-25 23:38:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-10-25 23:38:47 -0400
commit20582e34c8c1364bce15d776bce3c9c0f108132f (patch)
tree101f16c7406df25ba6dc4683741bec4cfebda007
parentd255c59aab2a3fdf0bb8a5db75e50d9c926c3bb9 (diff)
parent75c0758137c7ac647927b4b12bb5cfca96a0e4e6 (diff)
Merge tag 'pm+acpi-3.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from "These fix two bugs in the intel_pstate driver, a hibernate bug leading to nasty resume failures sometimes and acpi-cpufreq initialization bug that causes problems to happen during module unload when intel_pstate is in use. Specifics: - Fix for rounding errors in intel_pstate causing CPU utilization to be underestimated from Brennan Shacklett. - intel_pstate fix to always use the correct max pstate value when computing the min pstate from Dirk Brandewie. - Hibernation fix for deadlocking resume in cases when the probing of the device containing the image is deferred from Russ Dill. - acpi-cpufreq fix to prevent the module from staying in memory when the driver cannot be registered and then attempting to unregister things that have never been registered on exit" * tag 'pm+acpi-3.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: acpi-cpufreq: Fail initialization if driver cannot be registered PM / hibernate: Move software_resume to late_initcall_sync intel_pstate: Correct calculation of min pstate value intel_pstate: Improve accuracy by not truncating until final result
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c8
-rw-r--r--drivers/cpufreq/intel_pstate.c38
-rw-r--r--kernel/power/hibernate.c2
3 files changed, 23 insertions, 25 deletions
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index d2c3253e015e..506fd23c7550 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -986,12 +986,12 @@ static int __init acpi_cpufreq_init(void)
986{ 986{
987 int ret; 987 int ret;
988 988
989 if (acpi_disabled)
990 return -ENODEV;
991
989 /* don't keep reloading if cpufreq_driver exists */ 992 /* don't keep reloading if cpufreq_driver exists */
990 if (cpufreq_get_current_driver()) 993 if (cpufreq_get_current_driver())
991 return 0; 994 return -EEXIST;
992
993 if (acpi_disabled)
994 return 0;
995 995
996 pr_debug("acpi_cpufreq_init\n"); 996 pr_debug("acpi_cpufreq_init\n");
997 997
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index badf6206b2b2..eb3fdc755000 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -48,7 +48,7 @@ static inline int32_t div_fp(int32_t x, int32_t y)
48} 48}
49 49
50struct sample { 50struct sample {
51 int core_pct_busy; 51 int32_t core_pct_busy;
52 u64 aperf; 52 u64 aperf;
53 u64 mperf; 53 u64 mperf;
54 int freq; 54 int freq;
@@ -68,7 +68,7 @@ struct _pid {
68 int32_t i_gain; 68 int32_t i_gain;
69 int32_t d_gain; 69 int32_t d_gain;
70 int deadband; 70 int deadband;
71 int last_err; 71 int32_t last_err;
72}; 72};
73 73
74struct cpudata { 74struct cpudata {
@@ -153,16 +153,15 @@ static inline void pid_d_gain_set(struct _pid *pid, int percent)
153 pid->d_gain = div_fp(int_tofp(percent), int_tofp(100)); 153 pid->d_gain = div_fp(int_tofp(percent), int_tofp(100));
154} 154}
155 155
156static signed int pid_calc(struct _pid *pid, int busy) 156static signed int pid_calc(struct _pid *pid, int32_t busy)
157{ 157{
158 signed int err, result; 158 signed int result;
159 int32_t pterm, dterm, fp_error; 159 int32_t pterm, dterm, fp_error;
160 int32_t integral_limit; 160 int32_t integral_limit;
161 161
162 err = pid->setpoint - busy; 162 fp_error = int_tofp(pid->setpoint) - busy;
163 fp_error = int_tofp(err);
164 163
165 if (abs(err) <= pid->deadband) 164 if (abs(fp_error) <= int_tofp(pid->deadband))
166 return 0; 165 return 0;
167 166
168 pterm = mul_fp(pid->p_gain, fp_error); 167 pterm = mul_fp(pid->p_gain, fp_error);
@@ -176,8 +175,8 @@ static signed int pid_calc(struct _pid *pid, int busy)
176 if (pid->integral < -integral_limit) 175 if (pid->integral < -integral_limit)
177 pid->integral = -integral_limit; 176 pid->integral = -integral_limit;
178 177
179 dterm = mul_fp(pid->d_gain, (err - pid->last_err)); 178 dterm = mul_fp(pid->d_gain, fp_error - pid->last_err);
180 pid->last_err = err; 179 pid->last_err = fp_error;
181 180
182 result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm; 181 result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm;
183 182
@@ -367,12 +366,13 @@ static int intel_pstate_turbo_pstate(void)
367static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) 366static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
368{ 367{
369 int max_perf = cpu->pstate.turbo_pstate; 368 int max_perf = cpu->pstate.turbo_pstate;
369 int max_perf_adj;
370 int min_perf; 370 int min_perf;
371 if (limits.no_turbo) 371 if (limits.no_turbo)
372 max_perf = cpu->pstate.max_pstate; 372 max_perf = cpu->pstate.max_pstate;
373 373
374 max_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf)); 374 max_perf_adj = fp_toint(mul_fp(int_tofp(max_perf), limits.max_perf));
375 *max = clamp_t(int, max_perf, 375 *max = clamp_t(int, max_perf_adj,
376 cpu->pstate.min_pstate, cpu->pstate.turbo_pstate); 376 cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
377 377
378 min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf)); 378 min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
@@ -436,8 +436,9 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
436 struct sample *sample) 436 struct sample *sample)
437{ 437{
438 u64 core_pct; 438 u64 core_pct;
439 core_pct = div64_u64(sample->aperf * 100, sample->mperf); 439 core_pct = div64_u64(int_tofp(sample->aperf * 100),
440 sample->freq = cpu->pstate.max_pstate * core_pct * 1000; 440 sample->mperf);
441 sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000);
441 442
442 sample->core_pct_busy = core_pct; 443 sample->core_pct_busy = core_pct;
443} 444}
@@ -469,22 +470,19 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
469 mod_timer_pinned(&cpu->timer, jiffies + delay); 470 mod_timer_pinned(&cpu->timer, jiffies + delay);
470} 471}
471 472
472static inline int intel_pstate_get_scaled_busy(struct cpudata *cpu) 473static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
473{ 474{
474 int32_t busy_scaled;
475 int32_t core_busy, max_pstate, current_pstate; 475 int32_t core_busy, max_pstate, current_pstate;
476 476
477 core_busy = int_tofp(cpu->samples[cpu->sample_ptr].core_pct_busy); 477 core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy;
478 max_pstate = int_tofp(cpu->pstate.max_pstate); 478 max_pstate = int_tofp(cpu->pstate.max_pstate);
479 current_pstate = int_tofp(cpu->pstate.current_pstate); 479 current_pstate = int_tofp(cpu->pstate.current_pstate);
480 busy_scaled = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); 480 return mul_fp(core_busy, div_fp(max_pstate, current_pstate));
481
482 return fp_toint(busy_scaled);
483} 481}
484 482
485static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) 483static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
486{ 484{
487 int busy_scaled; 485 int32_t busy_scaled;
488 struct _pid *pid; 486 struct _pid *pid;
489 signed int ctl = 0; 487 signed int ctl = 0;
490 int steps; 488 int steps;
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index c9c759d5a15c..0121dab83f43 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -846,7 +846,7 @@ static int software_resume(void)
846 goto Finish; 846 goto Finish;
847} 847}
848 848
849late_initcall(software_resume); 849late_initcall_sync(software_resume);
850 850
851 851
852static const char * const hibernation_modes[] = { 852static const char * const hibernation_modes[] = {