Skip to content

Commit 9910531

Browse files
committed
Merge tag 'pm-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "The majority of these are cpufreq changes, which has been a recurring pattern for a few recent cycles. Those changes include new hardware support (AN7583 SoC support in the airoha cpufreq driver, ipq5424 support in the qcom-nvmem cpufreq driver, MT8196 support in the mediatek cpufreq driver, AM62D2 support in the ti cpufreq driver), DT bindings and Rust code updates, cleanups of the core and governors, and multiple driver fixes and cleanups. Beyond that, there are hibernation fixes (some remaining 6.16 cycle fallout and an issue related to hybrid suspend in the amdgpu driver), cleanups of the PM core code, runtime PM documentation update, cpuidle and power capping cleanups, and tooling updates. Specifics: - Rearrange variable declarations involving __free() in the cpufreq core and intel_pstate driver to follow common coding style (Rafael Wysocki) - Fix object lifecycle issue in update_qos_request(), rearrange freq QoS updates using __free(), and adjust frequency percentage computations in the intel_pstate driver (Rafael Wysocki) - Update intel_pstate to allow it to enable HWP without EPP if the new DEC (Dynamic Efficiency Control) HW feature is enabled (Rafael Wysocki) - Use on_each_cpu_mask() in drv_write() in the ACPI cpufreq driver to simplify the code (Rafael Wysocki) - Use likely() optimization in intel_pstate_sample() (Yaxiong Tian) - Remove dead EPB-related code from intel_pstate (Srinivas Pandruvada) - Use scope-based cleanup for cpufreq policy references in multiple cpufreq drivers (Zihuan Zhang) - Avoid calling get_governor() for the first policy in the cpufreq core to simplify the initial policy path (Zihuan Zhang) - Clean up the cpufreq core in multiple places (Zihuan Zhang) - Use int type to store negative error codes in the cpufreq core and update the speedstep-lib to use int for error codes (Qianfeng Rong) - Update the efficient idle check for Intel extended Families in the ondemand cpufreq governor (Sohil Mehta) - Replace sscanf() with kstrtouint() in the conservative cpufreq governor (Kaushlendra Kumar) - Rename CpumaskVar::as[_mut]_ref to from_raw[_mut] in the cpumask Rust code and mark CpumaskVar as transparent (Alice Ryhl, Baptiste Lepers) - Update ARef and AlwaysRefCounted imports from sync::aref in the OPP Rust code (Shankari Anand) - Add support for AN7583 SoC to the airoha cpufreq driver (Christian Marangi) - Enable cpufreq for ipq5424 in the qcom-nvmem cpufreq driver (Md Sadre Alam) - Add support for MT8196 to the mediatek-hw cpufreq driver, refactor that driver and add mediatek,mt8196-cpufreq-hw DT binding (Nicolas Frattaroli) - Avoid redundant conditions in the mediatek cpufreq driver (Liao Yuanhong) - Add support for AM62D2 to the ti cpufreq driver and blocklist ti,am62d2 SoC in dt-platdev (Paresh Bhagat) - Support more speed grades on AM62Px SoC in the ti cpufreq driver, allow all silicon revisions to support OPPs in it, and fix supported hardware for 1GHz OPP (Judith Mendez) - Add QCS615 compatible to DT bindings for cpufreq-qcom-hw (Taniya Das) - Minor assorted updates of the scmi, longhaul, CPPC, and armada-37xx cpufreq drivers (Akhilesh Patil, BowenYu, Dennis Beier, and Florian Fainelli) - Remove outdated cpufreq-dt.txt (Frank Li) - Fix python gnuplot package names in the amd_pstate_tracer utility (Kuan-Wei Chiu) - Saravana Kannan will maintain the virtual-cpufreq driver (Saravana Kannan) - Prevent CPU capacity updates after registering a perf domain from failing on a first CPU that is not present (Christian Loehle) - Add support for the cases in which frequency alone is not sufficient to uniquely identify an OPP (Krishna Chaitanya Chundru) - Use to_result() for OPP error handling in Rust (Onur Özkan) - Add support for LPDDR5 on Rockhip RK3588 SoC to rockchip-dfi devfreq driver (Nicolas Frattaroli) - Fix an issue where DDR cycle counts on RK3588/RK3528 with LPDDR4(X) are reported as half by adding a cycle multiplier to the DFI driver in rockchip-dfi devfreq-event driver (Nicolas Frattaroli) - Fix missing error pointer dereference check of regulator instance in the mtk-cci devfreq driver probe and remove a redundant condition from an if () statement in that driver (Dan Carpenter, Liao Yuanhong) - Fail cpuidle device registration if there is one already to avoid sysfs-related issues (Rafael Wysocki) - Use sysfs_emit()/sysfs_emit_at() instead of sprintf()/scnprintf() in cpuidle (Vivek Yadav) - Fix device and OF node leaks at probe in the qcom-spm cpuidle driver and drop unnecessary initialisations from it (Johan Hovold) - Remove unnecessary address-of operators from the intel_idle cpuidle driver (Kaushlendra Kumar) - Rearrange main loop in menu_select() to make the code in that funtion easier to follow (Rafael Wysocki) - Convert values in microseconds to ktime using us_to_ktime() where applicable in the intel_idle power capping driver (Xichao Zhao) - Annotate loops walking device links in the power management core code as _srcu and add macros for walking device links to reduce the likelihood of coding mistakes related to them (Rafael Wysocki) - Document time units for *_time functions in the runtime PM API (Brian Norris) - Clear power.must_resume in noirq suspend error path to avoid resuming a dependant device under a suspended parent or supplier (Rafael Wysocki) - Fix GFP mask handling during hybrid suspend and make the amdgpu driver handle hybrid suspend correctly (Mario Limonciello, Rafael Wysocki) - Fix GFP mask handling after aborted hibernation in platform mode and combine exit paths in power_down() to avoid code duplication (Rafael Wysocki) - Use vmalloc_array() and vcalloc() in the hibernation core to avoid open-coded size computations (Qianfeng Rong) - Fix typo in hibernation core code comment (Li Jun) - Call pm_wakeup_clear() in the same place where other functions that do bookkeeping prior to suspend_prepare() are called (Samuel Wu) - Fix and clean up the x86_energy_perf_policy utility and update its documentation (Len Brown, Kaushlendra Kumar) - Fix incorrect sorting of PMT telemetry in turbostat (Kaushlendra Kumar) - Fix incorrect size in cpuidle_state_disable() and the error return value of cpupower_write_sysfs() in cpupower (Kaushlendra Kumar)" * tag 'pm-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (86 commits) PM: hibernate: Combine return paths in power_down() PM: hibernate: Restrict GFP mask in power_down() PM: hibernate: Fix pm_hibernation_mode_is_suspend() build breakage PM: runtime: Documentation: ABI: Document time units for *_time tools/power x86_energy_perf_policy.8: Emphasize preference for SW interfaces tools/power x86_energy_perf_policy: Add make snapshot target tools/power x86_energy_perf_policy: Prefer driver HWP limits tools/power x86_energy_perf_policy: EPB access is only via sysfs tools/power x86_energy_perf_policy: Prepare for MSR/sysfs refactoring tools/power x86_energy_perf_policy: Enhance HWP enable tools/power x86_energy_perf_policy: Enhance HWP enabled check tools/power x86_energy_perf_policy: Fix incorrect fopen mode usage tools/power turbostat: Fix incorrect sorting of PMT telemetry drm/amd: Fix hybrid sleep PM: hibernate: Add pm_hibernation_mode_is_suspend() PM: hibernate: Fix hybrid-sleep tools/cpupower: Fix incorrect size in cpuidle_state_disable() tools/power/x86/amd_pstate_tracer: Fix python gnuplot package names cpufreq: Replace pointer subtraction with iteration macro cpuidle: Fail cpuidle device registration if there is one already ...
2 parents 080ffb4 + 40d2cf9 commit 9910531

64 files changed

Lines changed: 1050 additions & 641 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Documentation/ABI/testing/sysfs-devices-power

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,15 @@ What: /sys/devices/.../power/runtime_active_time
274274
Date: Jul 2010
275275
Contact: Arjan van de Ven <arjan@linux.intel.com>
276276
Description:
277-
Reports the total time that the device has been active.
278-
Used for runtime PM statistics.
277+
Reports the total time that the device has been active, in
278+
milliseconds. Used for runtime PM statistics.
279279

280280
What: /sys/devices/.../power/runtime_suspended_time
281281
Date: Jul 2010
282282
Contact: Arjan van de Ven <arjan@linux.intel.com>
283283
Description:
284-
Reports total time that the device has been suspended.
285-
Used for runtime PM statistics.
284+
Reports total time that the device has been suspended, in
285+
milliseconds. Used for runtime PM statistics.
286286

287287
What: /sys/devices/.../power/runtime_usage
288288
Date: Apr 2010

Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt

Lines changed: 0 additions & 61 deletions
This file was deleted.

Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ properties:
2222
items:
2323
- enum:
2424
- qcom,qcm2290-cpufreq-hw
25+
- qcom,qcs615-cpufreq-hw
2526
- qcom,sc7180-cpufreq-hw
2627
- qcom,sc8180x-cpufreq-hw
2728
- qcom,sdm670-cpufreq-hw
@@ -132,6 +133,7 @@ allOf:
132133
compatible:
133134
contains:
134135
enum:
136+
- qcom,qcs615-cpufreq-hw
135137
- qcom,qdu1000-cpufreq-epss
136138
- qcom,sa8255p-cpufreq-epss
137139
- qcom,sa8775p-cpufreq-epss
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/cpufreq/mediatek,mt8196-cpufreq-hw.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: MediaTek Hybrid CPUFreq for MT8196/MT6991 series SoCs
8+
9+
maintainers:
10+
- Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
11+
12+
description:
13+
MT8196 uses CPUFreq management hardware that supports dynamic voltage
14+
frequency scaling (dvfs), and can support several performance domains.
15+
16+
properties:
17+
compatible:
18+
const: mediatek,mt8196-cpufreq-hw
19+
20+
reg:
21+
items:
22+
- description: FDVFS control register region
23+
- description: OPP tables and control for performance domain 0
24+
- description: OPP tables and control for performance domain 1
25+
- description: OPP tables and control for performance domain 2
26+
27+
"#performance-domain-cells":
28+
const: 1
29+
30+
required:
31+
- compatible
32+
- reg
33+
- "#performance-domain-cells"
34+
35+
additionalProperties: false
36+
37+
examples:
38+
- |
39+
cpus {
40+
#address-cells = <1>;
41+
#size-cells = <0>;
42+
43+
cpu0: cpu@0 {
44+
device_type = "cpu";
45+
compatible = "arm,cortex-a720";
46+
enable-method = "psci";
47+
performance-domains = <&performance 0>;
48+
reg = <0x000>;
49+
};
50+
51+
/* ... */
52+
53+
cpu6: cpu@600 {
54+
device_type = "cpu";
55+
compatible = "arm,cortex-x4";
56+
enable-method = "psci";
57+
performance-domains = <&performance 1>;
58+
reg = <0x600>;
59+
};
60+
61+
cpu7: cpu@700 {
62+
device_type = "cpu";
63+
compatible = "arm,cortex-x925";
64+
enable-method = "psci";
65+
performance-domains = <&performance 2>;
66+
reg = <0x700>;
67+
};
68+
};
69+
70+
/* ... */
71+
72+
soc {
73+
#address-cells = <2>;
74+
#size-cells = <2>;
75+
76+
performance: performance-controller@c2c2034 {
77+
compatible = "mediatek,mt8196-cpufreq-hw";
78+
reg = <0 0xc220400 0 0x20>, <0 0xc2c0f20 0 0x120>,
79+
<0 0xc2c1040 0 0x120>, <0 0xc2c1160 0 0x120>;
80+
#performance-domain-cells = <1>;
81+
};
82+
};

MAINTAINERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6360,6 +6360,12 @@ F: kernel/sched/cpufreq*.c
63606360
F: rust/kernel/cpufreq.rs
63616361
F: tools/testing/selftests/cpufreq/
63626362

6363+
CPU FREQUENCY DRIVERS - VIRTUAL MACHINE CPUFREQ
6364+
M: Saravana Kannan <saravanak@google.com>
6365+
L: linux-pm@vger.kernel.org
6366+
S: Maintained
6367+
F: drivers/cpufreq/virtual-cpufreq.c
6368+
63636369
CPU HOTPLUG
63646370
M: Thomas Gleixner <tglx@linutronix.de>
63656371
M: Peter Zijlstra <peterz@infradead.org>

arch/arm64/boot/dts/ti/k3-am62p5.dtsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135

136136
opp-1000000000 {
137137
opp-hz = /bits/ 64 <1000000000>;
138-
opp-supported-hw = <0x01 0x0006>;
138+
opp-supported-hw = <0x01 0x0007>;
139139
clock-latency-ns = <6000000>;
140140
};
141141

drivers/base/base.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ void device_links_unbind_consumers(struct device *dev);
251251
void fw_devlink_drivers_done(void);
252252
void fw_devlink_probing_done(void);
253253

254+
#define dev_for_each_link_to_supplier(__link, __dev) \
255+
list_for_each_entry_srcu(__link, &(__dev)->links.suppliers, c_node, \
256+
device_links_read_lock_held())
257+
258+
#define dev_for_each_link_to_consumer(__link, __dev) \
259+
list_for_each_entry_srcu(__link, &(__dev)->links.consumers, s_node, \
260+
device_links_read_lock_held())
261+
254262
/* device pm support */
255263
void device_pm_move_to_tail(struct device *dev);
256264

drivers/base/power/main.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@
4040

4141
typedef int (*pm_callback_t)(struct device *);
4242

43-
#define list_for_each_entry_rcu_locked(pos, head, member) \
44-
list_for_each_entry_rcu(pos, head, member, \
45-
device_links_read_lock_held())
46-
4743
/*
4844
* The entries in the dpm_list list are in a depth first order, simply
4945
* because children are guaranteed to be discovered after parents, and
@@ -281,7 +277,7 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async)
281277
* callbacks freeing the link objects for the links in the list we're
282278
* walking.
283279
*/
284-
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
280+
dev_for_each_link_to_supplier(link, dev)
285281
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
286282
dpm_wait(link->supplier, async);
287283

@@ -338,7 +334,7 @@ static void dpm_wait_for_consumers(struct device *dev, bool async)
338334
* continue instead of trying to continue in parallel with its
339335
* unregistration).
340336
*/
341-
list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node)
337+
dev_for_each_link_to_consumer(link, dev)
342338
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
343339
dpm_wait(link->consumer, async);
344340

@@ -675,7 +671,7 @@ static void dpm_async_resume_subordinate(struct device *dev, async_func_t func)
675671
idx = device_links_read_lock();
676672

677673
/* Start processing the device's "async" consumers. */
678-
list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node)
674+
dev_for_each_link_to_consumer(link, dev)
679675
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
680676
dpm_async_with_cleanup(link->consumer, func);
681677

@@ -724,8 +720,20 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
724720
if (dev->power.syscore || dev->power.direct_complete)
725721
goto Out;
726722

727-
if (!dev->power.is_noirq_suspended)
723+
if (!dev->power.is_noirq_suspended) {
724+
/*
725+
* This means that system suspend has been aborted in the noirq
726+
* phase before invoking the noirq suspend callback for the
727+
* device, so if device_suspend_late() has left it in suspend,
728+
* device_resume_early() should leave it in suspend either in
729+
* case the early resume of it depends on the noirq resume that
730+
* has not run.
731+
*/
732+
if (dev_pm_skip_suspend(dev))
733+
dev->power.must_resume = false;
734+
728735
goto Out;
736+
}
729737

730738
if (!dpm_wait_for_superior(dev, async))
731739
goto Out;
@@ -1330,7 +1338,7 @@ static void dpm_async_suspend_superior(struct device *dev, async_func_t func)
13301338
idx = device_links_read_lock();
13311339

13321340
/* Start processing the device's "async" suppliers. */
1333-
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
1341+
dev_for_each_link_to_supplier(link, dev)
13341342
if (READ_ONCE(link->status) != DL_STATE_DORMANT)
13351343
dpm_async_with_cleanup(link->supplier, func);
13361344

@@ -1384,7 +1392,7 @@ static void dpm_superior_set_must_resume(struct device *dev)
13841392

13851393
idx = device_links_read_lock();
13861394

1387-
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
1395+
dev_for_each_link_to_supplier(link, dev)
13881396
link->supplier->power.must_resume = true;
13891397

13901398
device_links_read_unlock(idx);
@@ -1813,7 +1821,7 @@ static void dpm_clear_superiors_direct_complete(struct device *dev)
18131821

18141822
idx = device_links_read_lock();
18151823

1816-
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
1824+
dev_for_each_link_to_supplier(link, dev) {
18171825
spin_lock_irq(&link->supplier->power.lock);
18181826
link->supplier->power.direct_complete = false;
18191827
spin_unlock_irq(&link->supplier->power.lock);
@@ -2065,7 +2073,7 @@ static bool device_prepare_smart_suspend(struct device *dev)
20652073

20662074
idx = device_links_read_lock();
20672075

2068-
list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
2076+
dev_for_each_link_to_supplier(link, dev) {
20692077
if (!device_link_test(link, DL_FLAG_PM_RUNTIME))
20702078
continue;
20712079

drivers/base/power/runtime.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,8 +1903,7 @@ void pm_runtime_get_suppliers(struct device *dev)
19031903

19041904
idx = device_links_read_lock();
19051905

1906-
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
1907-
device_links_read_lock_held())
1906+
dev_for_each_link_to_supplier(link, dev)
19081907
if (device_link_test(link, DL_FLAG_PM_RUNTIME)) {
19091908
link->supplier_preactivated = true;
19101909
pm_runtime_get_sync(link->supplier);

drivers/cpufreq/acpi-cpufreq.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,6 @@ static u32 drv_read(struct acpi_cpufreq_data *data, const struct cpumask *mask)
318318
return cmd.val;
319319
}
320320

321-
/* Called via smp_call_function_many(), on the target CPUs */
322321
static void do_drv_write(void *_cmd)
323322
{
324323
struct drv_cmd *cmd = _cmd;
@@ -335,14 +334,8 @@ static void drv_write(struct acpi_cpufreq_data *data,
335334
.val = val,
336335
.func.write = data->cpu_freq_write,
337336
};
338-
int this_cpu;
339337

340-
this_cpu = get_cpu();
341-
if (cpumask_test_cpu(this_cpu, mask))
342-
do_drv_write(&cmd);
343-
344-
smp_call_function_many(mask, do_drv_write, &cmd, 1);
345-
put_cpu();
338+
on_each_cpu_mask(mask, do_drv_write, &cmd, true);
346339
}
347340

348341
static u32 get_cur_val(const struct cpumask *mask, struct acpi_cpufreq_data *data)

0 commit comments

Comments
 (0)