Skip to content

Commit 987c420

Browse files
committed
Merge branches 'pm-cpuidle', 'pm-qos', 'pm-devfreq' and 'pm-opp'
Merge a cpuidle update, a PM QoS update, devfreq updates, and an OPP (operating performance points) update for 6.17-rc1: - Fix opencoded for_each_cpu() in idle_state_valid() in the DT cpuidle driver (Yury Norov) - Remove info about non-existing QoS interfaces from the PM QoS documentation (Ulf Hansson) - Use c_* types via kernel prelude in Rust for OPP (Abhinav Ananthu) - Add HiSilicon uncore frequency scaling driver to devfreq (Jie Zhan) - Allow devfreq drivers to add custom sysfs ABIs (Jie Zhan) - Simplify the sun8i-a33-mbus devfreq driver by using more devm functions (Uwe Kleine-König) - Fix an index typo in trans_stat() in devfreq (Chanwoo Choi) - Check devfreq governor before using governor->name (Lifeng Zheng) - Remove a redundant devfreq_get_freq_range() call from devfreq_add_device() (Lifeng Zheng) - Limit max_freq with scaling_min_freq in devfreq (Lifeng Zheng) - Replace sscanf() with kstrtoul() in set_freq_store() (Lifeng Zheng) * pm-cpuidle: cpuidle: dt: fix opencoded for_each_cpu() in idle_state_valid() * pm-qos: Documentation: power: Remove info about non-existing QoS interfaces * pm-devfreq: PM / devfreq: Add HiSilicon uncore frequency scaling driver PM / devfreq: Allow devfreq driver to add custom sysfs ABIs PM / devfreq: sun8i-a33-mbus: Simplify by using more devm functions PM / devfreq: Fix a index typo in trans_stat PM / devfreq: Check governor before using governor->name PM / devfreq: Remove redundant devfreq_get_freq_range() calling in devfreq_add_device() PM / devfreq: Limit max_freq with scaling_min_freq PM / devfreq: governor: Replace sscanf() with kstrtoul() in set_freq_store() * pm-opp: rust: opp: use c_* types via kernel prelude
5 parents caf4427 + ee27368 + 01d40d3 + c224584 + 1c61cf9 commit 987c420

11 files changed

Lines changed: 713 additions & 66 deletions

File tree

Documentation/ABI/testing/sysfs-class-devfreq

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,12 @@ Description:
132132

133133
A list of governors that support the node:
134134
- simple_ondemand
135+
136+
What: /sys/class/devfreq/.../related_cpus
137+
Date: June 2025
138+
Contact: Linux power management list <linux-pm@vger.kernel.org>
139+
Description: The list of CPUs whose performance is closely related to the
140+
frequency of this devfreq domain.
141+
142+
This file is only present if a specific devfreq device is
143+
closely associated with a subset of CPUs.

Documentation/power/pm_qos_interface.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,6 @@ int cpu_latency_qos_request_active(handle):
5252
Returns if the request is still active, i.e. it has not been removed from the
5353
CPU latency QoS list.
5454

55-
int cpu_latency_qos_add_notifier(notifier):
56-
Adds a notification callback function to the CPU latency QoS. The callback is
57-
called when the aggregated value for the CPU latency QoS is changed.
58-
59-
int cpu_latency_qos_remove_notifier(notifier):
60-
Removes the notification callback function from the CPU latency QoS.
61-
6255

6356
From user space:
6457

drivers/cpuidle/dt_idle_states.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
9898
{
9999
int cpu;
100100
struct device_node *cpu_node, *curr_state_node;
101-
bool valid = true;
102101

103102
/*
104103
* Compare idle state phandles for index idx on all CPUs in the
@@ -107,20 +106,17 @@ static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
107106
* retrieved from. If a mismatch is found bail out straight
108107
* away since we certainly hit a firmware misconfiguration.
109108
*/
110-
for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
111-
cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
109+
cpu = cpumask_first(cpumask) + 1;
110+
for_each_cpu_from(cpu, cpumask) {
112111
cpu_node = of_cpu_device_node_get(cpu);
113112
curr_state_node = of_get_cpu_state_node(cpu_node, idx);
114-
if (state_node != curr_state_node)
115-
valid = false;
116-
117113
of_node_put(curr_state_node);
118114
of_node_put(cpu_node);
119-
if (!valid)
120-
break;
115+
if (state_node != curr_state_node)
116+
return false;
121117
}
122118

123-
return valid;
119+
return true;
124120
}
125121

126122
/**

drivers/devfreq/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ config ARM_EXYNOS_BUS_DEVFREQ
9090
and adjusts the operating frequencies and voltages with OPP support.
9191
This does not yet operate with optimal voltages.
9292

93+
config ARM_HISI_UNCORE_DEVFREQ
94+
tristate "HiSilicon uncore DEVFREQ Driver"
95+
depends on ACPI && ACPI_PPTT && PCC
96+
select DEVFREQ_GOV_PERFORMANCE
97+
select DEVFREQ_GOV_USERSPACE
98+
help
99+
This adds a DEVFREQ driver that manages uncore frequency scaling for
100+
HiSilicon Kunpeng SoCs. This enables runtime management of uncore
101+
frequency scaling from kernel and userspace. The uncore domain
102+
contains system interconnects and L3 cache.
103+
93104
config ARM_IMX_BUS_DEVFREQ
94105
tristate "i.MX Generic Bus DEVFREQ Driver"
95106
depends on ARCH_MXC || COMPILE_TEST

drivers/devfreq/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o
99

1010
# DEVFREQ Drivers
1111
obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o
12+
obj-$(CONFIG_ARM_HISI_UNCORE_DEVFREQ) += hisi_uncore_freq.o
1213
obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o
1314
obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o
1415
obj-$(CONFIG_ARM_MEDIATEK_CCI_DEVFREQ) += mtk-cci-devfreq.o

drivers/devfreq/devfreq.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,8 @@ void devfreq_get_freq_range(struct devfreq *devfreq,
152152
(unsigned long)HZ_PER_KHZ * qos_max_freq);
153153

154154
/* Apply constraints from OPP interface */
155-
*min_freq = max(*min_freq, devfreq->scaling_min_freq);
156-
*max_freq = min(*max_freq, devfreq->scaling_max_freq);
157-
158-
if (*min_freq > *max_freq)
159-
*min_freq = *max_freq;
155+
*max_freq = clamp(*max_freq, devfreq->scaling_min_freq, devfreq->scaling_max_freq);
156+
*min_freq = clamp(*min_freq, devfreq->scaling_min_freq, *max_freq);
160157
}
161158
EXPORT_SYMBOL(devfreq_get_freq_range);
162159

@@ -807,7 +804,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
807804
{
808805
struct devfreq *devfreq;
809806
struct devfreq_governor *governor;
810-
unsigned long min_freq, max_freq;
811807
int err = 0;
812808

813809
if (!dev || !profile || !governor_name) {
@@ -835,6 +831,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
835831
mutex_lock(&devfreq->lock);
836832
devfreq->dev.parent = dev;
837833
devfreq->dev.class = devfreq_class;
834+
devfreq->dev.groups = profile->dev_groups;
838835
devfreq->dev.release = devfreq_dev_release;
839836
INIT_LIST_HEAD(&devfreq->node);
840837
devfreq->profile = profile;
@@ -875,8 +872,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
875872
goto err_dev;
876873
}
877874

878-
devfreq_get_freq_range(devfreq, &min_freq, &max_freq);
879-
880875
devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev);
881876
devfreq->opp_table = dev_pm_opp_get_opp_table(dev);
882877
if (IS_ERR(devfreq->opp_table))
@@ -1382,15 +1377,11 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
13821377
int ret;
13831378
struct device *dev = devfreq->dev.parent;
13841379

1380+
if (!devfreq->governor)
1381+
continue;
1382+
13851383
if (!strncmp(devfreq->governor->name, governor->name,
13861384
DEVFREQ_NAME_LEN)) {
1387-
/* we should have a devfreq governor! */
1388-
if (!devfreq->governor) {
1389-
dev_warn(dev, "%s: Governor %s NOT present\n",
1390-
__func__, governor->name);
1391-
continue;
1392-
/* Fall through */
1393-
}
13941385
ret = devfreq->governor->event_handler(devfreq,
13951386
DEVFREQ_GOV_STOP, NULL);
13961387
if (ret) {
@@ -1743,7 +1734,7 @@ static ssize_t trans_stat_show(struct device *dev,
17431734
for (i = 0; i < max_state; i++) {
17441735
if (len >= PAGE_SIZE - 1)
17451736
break;
1746-
if (df->freq_table[2] == df->previous_freq)
1737+
if (df->freq_table[i] == df->previous_freq)
17471738
len += sysfs_emit_at(buf, len, "*");
17481739
else
17491740
len += sysfs_emit_at(buf, len, " ");

drivers/devfreq/governor_userspace.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/slab.h>
1010
#include <linux/device.h>
1111
#include <linux/devfreq.h>
12+
#include <linux/kstrtox.h>
1213
#include <linux/pm.h>
1314
#include <linux/mutex.h>
1415
#include <linux/module.h>
@@ -39,10 +40,13 @@ static ssize_t set_freq_store(struct device *dev, struct device_attribute *attr,
3940
unsigned long wanted;
4041
int err = 0;
4142

43+
err = kstrtoul(buf, 0, &wanted);
44+
if (err)
45+
return err;
46+
4247
mutex_lock(&devfreq->lock);
4348
data = devfreq->governor_data;
4449

45-
sscanf(buf, "%lu", &wanted);
4650
data->user_frequency = wanted;
4751
data->valid = true;
4852
err = update_devfreq(devfreq);

0 commit comments

Comments
 (0)