Skip to content

Commit

Permalink
Merge tag 'pm-6.14-rc1-2' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/rafael/linux-pm

Pull more power management updates from Rafael Wysocki:
 "These are mostly fixes on top of the previously merged power
  management material with the addition of some teo cpuidle governor
  updates, some of which may also be regarded as fixes:

   - Add missing error handling for syscore_suspend() to the hibernation
     core code (Wentao Liang)

   - Revert a commit that added unused macros (Andy Shevchenko)

   - Synchronize the runtime PM status of devices that were runtime-
     suspended before a system-wide suspend and need to be resumed
     during the subsequent system-wide resume transition (Rafael
     Wysocki)

   - Clean up the teo cpuidle governor and make the handling of short
     idle intervals in it consistent regardless of the properties of
     idle states supplied by the cpuidle driver (Rafael Wysocki)

   - Fix some boost-related issues in cpufreq (Lifeng Zheng)

   - Fix build issues in the s3c64xx and airoha cpufreq drivers (Viresh
     Kumar)

   - Remove unconditional binding of schedutil governor kthreads to the
     affected CPUs if the cpufreq driver indicates that updates can
     happen from any CPU (Christian Loehle)"

* tag 'pm-6.14-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  PM: sleep: core: Synchronize runtime PM status of parents and children
  cpufreq: airoha: Depends on OF
  PM: Revert "Add EXPORT macros for exporting PM functions"
  PM: hibernate: Add error handling for syscore_suspend()
  cpufreq/schedutil: Only bind threads if needed
  cpufreq: ACPI: Remove set_boost in acpi_cpufreq_cpu_init()
  cpufreq: CPPC: Fix wrong max_freq in policy initialization
  cpufreq: Introduce a more generic way to set default per-policy boost flag
  cpufreq: Fix re-boost issue after hotplugging a CPU
  cpufreq: s3c64xx: Fix compilation warning
  cpuidle: teo: Skip sleep length computation for low latency constraints
  cpuidle: teo: Replace time_span_ns with a flag
  cpuidle: teo: Simplify handling of total events count
  cpuidle: teo: Skip getting the sleep length if wakeups are very frequent
  cpuidle: teo: Simplify counting events used for tick management
  cpuidle: teo: Clarify two code comments
  cpuidle: teo: Drop local variable prev_intercept_idx
  cpuidle: teo: Combine candidate state index checks against 0
  cpuidle: teo: Reorder candidate state index checks
  cpuidle: teo: Rearrange idle state lookup code
  • Loading branch information
torvalds committed Jan 30, 2025
2 parents c2933b2 + a01e0f4 commit f55b067
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 132 deletions.
29 changes: 20 additions & 9 deletions drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,13 +656,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
* so change its status accordingly.
*
* Otherwise, the device is going to be resumed, so set its PM-runtime
* status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
* to avoid confusing drivers that don't use it.
* status to "active" unless its power.set_active flag is clear, in
* which case it is not necessary to update its PM-runtime status.
*/
if (skip_resume)
if (skip_resume) {
pm_runtime_set_suspended(dev);
else if (dev_pm_skip_suspend(dev))
} else if (dev->power.set_active) {
pm_runtime_set_active(dev);
dev->power.set_active = false;
}

if (dev->pm_domain) {
info = "noirq power domain ";
Expand Down Expand Up @@ -1189,18 +1191,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
return PMSG_ON;
}

static void dpm_superior_set_must_resume(struct device *dev)
static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
{
struct device_link *link;
int idx;

if (dev->parent)
if (dev->parent) {
dev->parent->power.must_resume = true;
if (set_active)
dev->parent->power.set_active = true;
}

idx = device_links_read_lock();

list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
link->supplier->power.must_resume = true;
if (set_active)
link->supplier->power.set_active = true;
}

device_links_read_unlock(idx);
}
Expand Down Expand Up @@ -1278,8 +1286,11 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state, bool asy
dev->power.may_skip_resume))
dev->power.must_resume = true;

if (dev->power.must_resume)
dpm_superior_set_must_resume(dev);
if (dev->power.must_resume) {
dev->power.set_active = dev->power.set_active ||
dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
dpm_superior_set_must_resume(dev, dev->power.set_active);
}

Complete:
complete_all(&dev->power.completion);
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/Kconfig.arm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM

config ARM_AIROHA_SOC_CPUFREQ
tristate "Airoha EN7581 SoC CPUFreq support"
depends on ARCH_AIROHA || COMPILE_TEST
depends on (ARCH_AIROHA && OF) || COMPILE_TEST
select PM_OPP
default ARCH_AIROHA
help
Expand Down
5 changes: 0 additions & 5 deletions drivers/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,11 +909,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
pr_warn(FW_WARN "P-state 0 is not max freq\n");

if (acpi_cpufreq_driver.set_boost) {
set_boost(policy, acpi_cpufreq_driver.boost_enabled);
policy->boost_enabled = acpi_cpufreq_driver.boost_enabled;
}

return result;

err_unreg:
Expand Down
5 changes: 3 additions & 2 deletions drivers/cpufreq/cppc_cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,15 +611,16 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
*/
policy->min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf);
policy->max = cppc_perf_to_khz(caps, caps->nominal_perf);
policy->max = cppc_perf_to_khz(caps, policy->boost_enabled ?
caps->highest_perf : caps->nominal_perf);

/*
* Set cpuinfo.min_freq to Lowest to make the full range of performance
* available if userspace wants to use any perf between lowest & lowest
* nonlinear perf
*/
policy->cpuinfo.min_freq = cppc_perf_to_khz(caps, caps->lowest_perf);
policy->cpuinfo.max_freq = cppc_perf_to_khz(caps, caps->nominal_perf);
policy->cpuinfo.max_freq = policy->max;

policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu);
policy->shared_type = cpu_data->shared_type;
Expand Down
20 changes: 16 additions & 4 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1410,10 +1410,6 @@ static int cpufreq_online(unsigned int cpu)
goto out_free_policy;
}

/* Let the per-policy boost flag mirror the cpufreq_driver boost during init */
if (cpufreq_boost_enabled() && policy_has_boost_freq(policy))
policy->boost_enabled = true;

/*
* The initialization has succeeded and the policy is online.
* If there is a problem with its frequency table, take it
Expand Down Expand Up @@ -1476,6 +1472,10 @@ static int cpufreq_online(unsigned int cpu)

blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_CREATE_POLICY, policy);
} else {
ret = freq_qos_update_request(policy->max_freq_req, policy->max);
if (ret < 0)
goto out_destroy_policy;
}

if (cpufreq_driver->get && has_target()) {
Expand Down Expand Up @@ -1570,6 +1570,18 @@ static int cpufreq_online(unsigned int cpu)
if (new_policy && cpufreq_thermal_control_enabled(cpufreq_driver))
policy->cdev = of_cpufreq_cooling_register(policy);

/* Let the per-policy boost flag mirror the cpufreq_driver boost during init */
if (policy->boost_enabled != cpufreq_boost_enabled()) {
policy->boost_enabled = cpufreq_boost_enabled();
ret = cpufreq_driver->set_boost(policy, policy->boost_enabled);
if (ret) {
/* If the set_boost fails, the online operation is not affected */
pr_info("%s: CPU%d: Cannot %s BOOST\n", __func__, policy->cpu,
policy->boost_enabled ? "enable" : "disable");
policy->boost_enabled = !policy->boost_enabled;
}
}

pr_debug("initialization complete\n");

return 0;
Expand Down
11 changes: 7 additions & 4 deletions drivers/cpufreq/s3c64xx-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ struct s3c64xx_dvfs {
unsigned int vddarm_max;
};

#ifdef CONFIG_REGULATOR
static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
[0] = { 1000000, 1150000 },
[1] = { 1050000, 1150000 },
[2] = { 1100000, 1150000 },
[3] = { 1200000, 1350000 },
[4] = { 1300000, 1350000 },
};
#endif

static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
{ 0, 0, 66000 },
Expand All @@ -51,15 +53,16 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
unsigned int index)
{
struct s3c64xx_dvfs *dvfs;
unsigned int old_freq, new_freq;
unsigned int new_freq = s3c64xx_freq_table[index].frequency;
int ret;

#ifdef CONFIG_REGULATOR
struct s3c64xx_dvfs *dvfs;
unsigned int old_freq;

old_freq = clk_get_rate(policy->clk) / 1000;
new_freq = s3c64xx_freq_table[index].frequency;
dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];

#ifdef CONFIG_REGULATOR
if (vddarm && new_freq > old_freq) {
ret = regulator_set_voltage(vddarm,
dvfs->vddarm_min,
Expand Down
Loading

0 comments on commit f55b067

Please sign in to comment.