Commit 1eab0e42 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm+acpi-4.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
 "These fix a potential regression introduced during the 4.3 cycle
  (generic power domains framework), a nasty bug that has been present
  forever (power capping RAPL driver), a build issue (Tegra cpufreq
  driver) and a minor ugliness introduced recently (intel_pstate).

  Specifics:

   - Fix a potential regression in the generic power domains framework
     introduced during the 4.3 development cycle that may lead to
     spurious failures of system suspend in certain situations (Ulf
     Hansson).

   - Fix a problem in the power capping RAPL (Running Average Power
     Limits) driver that causes it to initialize successfully on some
     systems where it is not supposed to do that which is due to an
     incorrect check in an initialization routine (Prarit Bhargava).

   - Fix a build problem in the cpufreq Tegra driver that depends on the
     regulator framework, but that dependency is not reflected in
     Kconfig (Arnd Bergmann).

   - Fix a recent mistake in the intel_pstate driver where a numeric
     constant is used directly instead of a symbol defined specifically
     for the case in question (Prarit Bhargava)"

* tag 'pm+acpi-4.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  powercap / RAPL: fix BIOS lock check
  cpufreq: intel_pstate: Minor cleanup for FRAC_BITS
  cpufreq: tegra: add regulator dependency for T124
  PM / Domains: Allow runtime PM callbacks to be re-used during system PM
parents 4fee35a3 f1b9fc59
...@@ -390,6 +390,7 @@ static int pm_genpd_runtime_suspend(struct device *dev) ...@@ -390,6 +390,7 @@ static int pm_genpd_runtime_suspend(struct device *dev)
struct generic_pm_domain *genpd; struct generic_pm_domain *genpd;
bool (*stop_ok)(struct device *__dev); bool (*stop_ok)(struct device *__dev);
struct gpd_timing_data *td = &dev_gpd_data(dev)->td; struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
bool runtime_pm = pm_runtime_enabled(dev);
ktime_t time_start; ktime_t time_start;
s64 elapsed_ns; s64 elapsed_ns;
int ret; int ret;
...@@ -400,11 +401,18 @@ static int pm_genpd_runtime_suspend(struct device *dev) ...@@ -400,11 +401,18 @@ static int pm_genpd_runtime_suspend(struct device *dev)
if (IS_ERR(genpd)) if (IS_ERR(genpd))
return -EINVAL; return -EINVAL;
/*
* A runtime PM centric subsystem/driver may re-use the runtime PM
* callbacks for other purposes than runtime PM. In those scenarios
* runtime PM is disabled. Under these circumstances, we shall skip
* validating/measuring the PM QoS latency.
*/
stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL; stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
if (stop_ok && !stop_ok(dev)) if (runtime_pm && stop_ok && !stop_ok(dev))
return -EBUSY; return -EBUSY;
/* Measure suspend latency. */ /* Measure suspend latency. */
if (runtime_pm)
time_start = ktime_get(); time_start = ktime_get();
ret = genpd_save_dev(genpd, dev); ret = genpd_save_dev(genpd, dev);
...@@ -418,6 +426,7 @@ static int pm_genpd_runtime_suspend(struct device *dev) ...@@ -418,6 +426,7 @@ static int pm_genpd_runtime_suspend(struct device *dev)
} }
/* Update suspend latency value if the measured time exceeds it. */ /* Update suspend latency value if the measured time exceeds it. */
if (runtime_pm) {
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns > td->suspend_latency_ns) { if (elapsed_ns > td->suspend_latency_ns) {
td->suspend_latency_ns = elapsed_ns; td->suspend_latency_ns = elapsed_ns;
...@@ -426,6 +435,7 @@ static int pm_genpd_runtime_suspend(struct device *dev) ...@@ -426,6 +435,7 @@ static int pm_genpd_runtime_suspend(struct device *dev)
genpd->max_off_time_changed = true; genpd->max_off_time_changed = true;
td->constraint_changed = true; td->constraint_changed = true;
} }
}
/* /*
* If power.irq_safe is set, this routine will be run with interrupts * If power.irq_safe is set, this routine will be run with interrupts
...@@ -453,6 +463,7 @@ static int pm_genpd_runtime_resume(struct device *dev) ...@@ -453,6 +463,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
{ {
struct generic_pm_domain *genpd; struct generic_pm_domain *genpd;
struct gpd_timing_data *td = &dev_gpd_data(dev)->td; struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
bool runtime_pm = pm_runtime_enabled(dev);
ktime_t time_start; ktime_t time_start;
s64 elapsed_ns; s64 elapsed_ns;
int ret; int ret;
...@@ -479,14 +490,14 @@ static int pm_genpd_runtime_resume(struct device *dev) ...@@ -479,14 +490,14 @@ static int pm_genpd_runtime_resume(struct device *dev)
out: out:
/* Measure resume latency. */ /* Measure resume latency. */
if (timed) if (timed && runtime_pm)
time_start = ktime_get(); time_start = ktime_get();
genpd_start_dev(genpd, dev); genpd_start_dev(genpd, dev);
genpd_restore_dev(genpd, dev); genpd_restore_dev(genpd, dev);
/* Update resume latency value if the measured time exceeds it. */ /* Update resume latency value if the measured time exceeds it. */
if (timed) { if (timed && runtime_pm) {
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
if (elapsed_ns > td->resume_latency_ns) { if (elapsed_ns > td->resume_latency_ns) {
td->resume_latency_ns = elapsed_ns; td->resume_latency_ns = elapsed_ns;
......
...@@ -226,7 +226,7 @@ config ARM_TEGRA20_CPUFREQ ...@@ -226,7 +226,7 @@ config ARM_TEGRA20_CPUFREQ
config ARM_TEGRA124_CPUFREQ config ARM_TEGRA124_CPUFREQ
tristate "Tegra124 CPUFreq support" tristate "Tegra124 CPUFreq support"
depends on ARCH_TEGRA && CPUFREQ_DT depends on ARCH_TEGRA && CPUFREQ_DT && REGULATOR
default y default y
help help
This adds the CPUFreq driver support for Tegra124 SOCs. This adds the CPUFreq driver support for Tegra124 SOCs.
......
...@@ -1123,7 +1123,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) ...@@ -1123,7 +1123,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
limits->max_sysfs_pct); limits->max_sysfs_pct);
limits->max_perf_pct = max(limits->min_policy_pct, limits->max_perf_pct = max(limits->min_policy_pct,
limits->max_perf_pct); limits->max_perf_pct);
limits->max_perf = round_up(limits->max_perf, 8); limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
/* Make sure min_perf_pct <= max_perf_pct */ /* Make sure min_perf_pct <= max_perf_pct */
limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct); limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct);
......
...@@ -1341,7 +1341,10 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu) ...@@ -1341,7 +1341,10 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) { for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
/* check if the domain is locked by BIOS */ /* check if the domain is locked by BIOS */
if (rapl_read_data_raw(rd, FW_LOCK, false, &locked)) { ret = rapl_read_data_raw(rd, FW_LOCK, false, &locked);
if (ret)
return ret;
if (locked) {
pr_info("RAPL package %d domain %s locked by BIOS\n", pr_info("RAPL package %d domain %s locked by BIOS\n",
rp->id, rd->name); rp->id, rd->name);
rd->state |= DOMAIN_STATE_BIOS_LOCKED; rd->state |= DOMAIN_STATE_BIOS_LOCKED;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment