Skip to content

Commit 5ddbecb

Browse files
committed
Merge branch 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Pull ARM cpufreq updates for v5.14-rc1 from Viresh Kumar: "- Add frequency invariance support for CPPC driver again and related fixes/changes." - Minor changes/cleanups for Meditak driver (Fabien Parent and Seiya Wang), Qcom platform (Sibi Sankar), and SCMI driver (Christophe JAILLET). - New bindings for generic performance domains (Sudeep Holla). - Rename black/white-lists (Viresh Kumar)." * 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: cpufreq: CPPC: Add support for frequency invariance arch_topology: Avoid use-after-free for scale_freq_data cpufreq: CPPC: Pass structure instance by reference cpufreq: CPPC: Fix potential memleak in cppc_cpufreq_cpu_init dt-bindings: cpufreq: update cpu type and clock name for MT8173 SoC clk: mediatek: remove deprecated CLK_INFRA_CA57SEL for MT8173 SoC cpufreq: dt: Rename black/white-lists cpufreq: scmi: Fix an error message cpufreq: mediatek: add support for mt8365 dt-bindings: dvfs: Add support for generic performance domains cpufreq: blacklist SC7280 in cpufreq-dt-platdev
2 parents b3beca7 + c503c19 commit 5ddbecb

File tree

12 files changed

+390
-42
lines changed

12 files changed

+390
-42
lines changed

Documentation/devicetree/bindings/arm/cpus.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,13 @@ properties:
257257

258258
where voltage is in V, frequency is in MHz.
259259

260+
performance-domains:
261+
maxItems: 1
262+
description:
263+
List of phandles and performance domain specifiers, as defined by
264+
bindings of the performance domain provider. See also
265+
dvfs/performance-domain.yaml.
266+
260267
power-domains:
261268
description:
262269
List of phandles and PM domain specifiers, as defined by bindings of the

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,23 +202,23 @@ Example 2 (MT8173 SoC):
202202

203203
cpu2: cpu@100 {
204204
device_type = "cpu";
205-
compatible = "arm,cortex-a57";
205+
compatible = "arm,cortex-a72";
206206
reg = <0x100>;
207207
enable-method = "psci";
208208
cpu-idle-states = <&CPU_SLEEP_0>;
209-
clocks = <&infracfg CLK_INFRA_CA57SEL>,
209+
clocks = <&infracfg CLK_INFRA_CA72SEL>,
210210
<&apmixedsys CLK_APMIXED_MAINPLL>;
211211
clock-names = "cpu", "intermediate";
212212
operating-points-v2 = <&cpu_opp_table_b>;
213213
};
214214

215215
cpu3: cpu@101 {
216216
device_type = "cpu";
217-
compatible = "arm,cortex-a57";
217+
compatible = "arm,cortex-a72";
218218
reg = <0x101>;
219219
enable-method = "psci";
220220
cpu-idle-states = <&CPU_SLEEP_0>;
221-
clocks = <&infracfg CLK_INFRA_CA57SEL>,
221+
clocks = <&infracfg CLK_INFRA_CA72SEL>,
222222
<&apmixedsys CLK_APMIXED_MAINPLL>;
223223
clock-names = "cpu", "intermediate";
224224
operating-points-v2 = <&cpu_opp_table_b>;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/dvfs/performance-domain.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Generic performance domains
8+
9+
maintainers:
10+
- Sudeep Holla <[email protected]>
11+
12+
description: |+
13+
This binding is intended for performance management of groups of devices or
14+
CPUs that run in the same performance domain. Performance domains must not
15+
be confused with power domains. A performance domain is defined by a set
16+
of devices that always have to run at the same performance level. For a given
17+
performance domain, there is a single point of control that affects all the
18+
devices in the domain, making it impossible to set the performance level of
19+
an individual device in the domain independently from other devices in
20+
that domain. For example, a set of CPUs that share a voltage domain, and
21+
have a common frequency control, is said to be in the same performance
22+
domain.
23+
24+
This device tree binding can be used to bind performance domain consumer
25+
devices with their performance domains provided by performance domain
26+
providers. A performance domain provider can be represented by any node in
27+
the device tree and can provide one or more performance domains. A consumer
28+
node can refer to the provider by a phandle and a set of phandle arguments
29+
(so called performance domain specifiers) of length specified by the
30+
\#performance-domain-cells property in the performance domain provider node.
31+
32+
select: true
33+
34+
properties:
35+
"#performance-domain-cells":
36+
description:
37+
Number of cells in a performance domain specifier. Typically 0 for nodes
38+
representing a single performance domain and 1 for nodes providing
39+
multiple performance domains (e.g. performance controllers), but can be
40+
any value as specified by device tree binding documentation of particular
41+
provider.
42+
enum: [ 0, 1 ]
43+
44+
performance-domains:
45+
$ref: '/schemas/types.yaml#/definitions/phandle-array'
46+
maxItems: 1
47+
description:
48+
A phandle and performance domain specifier as defined by bindings of the
49+
performance controller/provider specified by phandle.
50+
51+
additionalProperties: true
52+
53+
examples:
54+
- |
55+
performance: performance-controller@12340000 {
56+
compatible = "qcom,cpufreq-hw";
57+
reg = <0x12340000 0x1000>;
58+
#performance-domain-cells = <1>;
59+
};
60+
61+
// The node above defines a performance controller that is a performance
62+
// domain provider and expects one cell as its phandle argument.
63+
64+
cpus {
65+
#address-cells = <2>;
66+
#size-cells = <0>;
67+
68+
cpu@0 {
69+
device_type = "cpu";
70+
compatible = "arm,cortex-a57";
71+
reg = <0x0 0x0>;
72+
performance-domains = <&performance 1>;
73+
};
74+
};

drivers/base/arch_topology.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@
1818
#include <linux/cpumask.h>
1919
#include <linux/init.h>
2020
#include <linux/percpu.h>
21+
#include <linux/rcupdate.h>
2122
#include <linux/sched.h>
2223
#include <linux/smp.h>
2324

24-
static DEFINE_PER_CPU(struct scale_freq_data *, sft_data);
25+
static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data);
2526
static struct cpumask scale_freq_counters_mask;
2627
static bool scale_freq_invariant;
2728

@@ -66,16 +67,20 @@ void topology_set_scale_freq_source(struct scale_freq_data *data,
6667
if (cpumask_empty(&scale_freq_counters_mask))
6768
scale_freq_invariant = topology_scale_freq_invariant();
6869

70+
rcu_read_lock();
71+
6972
for_each_cpu(cpu, cpus) {
70-
sfd = per_cpu(sft_data, cpu);
73+
sfd = rcu_dereference(*per_cpu_ptr(&sft_data, cpu));
7174

7275
/* Use ARCH provided counters whenever possible */
7376
if (!sfd || sfd->source != SCALE_FREQ_SOURCE_ARCH) {
74-
per_cpu(sft_data, cpu) = data;
77+
rcu_assign_pointer(per_cpu(sft_data, cpu), data);
7578
cpumask_set_cpu(cpu, &scale_freq_counters_mask);
7679
}
7780
}
7881

82+
rcu_read_unlock();
83+
7984
update_scale_freq_invariant(true);
8085
}
8186
EXPORT_SYMBOL_GPL(topology_set_scale_freq_source);
@@ -86,22 +91,32 @@ void topology_clear_scale_freq_source(enum scale_freq_source source,
8691
struct scale_freq_data *sfd;
8792
int cpu;
8893

94+
rcu_read_lock();
95+
8996
for_each_cpu(cpu, cpus) {
90-
sfd = per_cpu(sft_data, cpu);
97+
sfd = rcu_dereference(*per_cpu_ptr(&sft_data, cpu));
9198

9299
if (sfd && sfd->source == source) {
93-
per_cpu(sft_data, cpu) = NULL;
100+
rcu_assign_pointer(per_cpu(sft_data, cpu), NULL);
94101
cpumask_clear_cpu(cpu, &scale_freq_counters_mask);
95102
}
96103
}
97104

105+
rcu_read_unlock();
106+
107+
/*
108+
* Make sure all references to previous sft_data are dropped to avoid
109+
* use-after-free races.
110+
*/
111+
synchronize_rcu();
112+
98113
update_scale_freq_invariant(false);
99114
}
100115
EXPORT_SYMBOL_GPL(topology_clear_scale_freq_source);
101116

102117
void topology_scale_freq_tick(void)
103118
{
104-
struct scale_freq_data *sfd = *this_cpu_ptr(&sft_data);
119+
struct scale_freq_data *sfd = rcu_dereference_sched(*this_cpu_ptr(&sft_data));
105120

106121
if (sfd)
107122
sfd->set_freq_scale();

drivers/cpufreq/Kconfig.arm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ config ACPI_CPPC_CPUFREQ
1919

2020
If in doubt, say N.
2121

22+
config ACPI_CPPC_CPUFREQ_FIE
23+
bool "Frequency Invariance support for CPPC cpufreq driver"
24+
depends on ACPI_CPPC_CPUFREQ && GENERIC_ARCH_TOPOLOGY
25+
default y
26+
help
27+
This extends frequency invariance support in the CPPC cpufreq driver,
28+
by using CPPC delivered and reference performance counters.
29+
30+
If in doubt, say N.
31+
2232
config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM
2333
tristate "Allwinner nvmem based SUN50I CPUFreq driver"
2434
depends on ARCH_SUNXI

0 commit comments

Comments
 (0)