hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/acpi/processor_thermal.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * processor_thermal.c - Passive cooling submodule of the ACPI processor driver
34 *
....@@ -6,20 +7,6 @@
67 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
78 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
89 * - Added processor hotplug support
9
- *
10
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation; either version 2 of the License, or (at
15
- * your option) any later version.
16
- *
17
- * This program is distributed in the hope that it will be useful, but
18
- * WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
- * General Public License for more details.
21
- *
22
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2310 */
2411
2512 #include <linux/kernel.h>
....@@ -33,8 +20,6 @@
3320 #define PREFIX "ACPI: "
3421
3522 #define ACPI_PROCESSOR_CLASS "processor"
36
-#define _COMPONENT ACPI_PROCESSOR_COMPONENT
37
-ACPI_MODULE_NAME("processor_thermal");
3823
3924 #ifdef CONFIG_CPU_FREQ
4025
....@@ -48,7 +33,6 @@
4833 #define CPUFREQ_THERMAL_MAX_STEP 3
4934
5035 static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg);
51
-static unsigned int acpi_thermal_cpufreq_is_init = 0;
5236
5337 #define reduction_pctg(cpu) \
5438 per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu))
....@@ -74,34 +58,10 @@
7458 static int cpu_has_cpufreq(unsigned int cpu)
7559 {
7660 struct cpufreq_policy policy;
77
- if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu))
61
+ if (!acpi_processor_cpufreq_init || cpufreq_get_policy(&policy, cpu))
7862 return 0;
7963 return 1;
8064 }
81
-
82
-static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
83
- unsigned long event, void *data)
84
-{
85
- struct cpufreq_policy *policy = data;
86
- unsigned long max_freq = 0;
87
-
88
- if (event != CPUFREQ_ADJUST)
89
- goto out;
90
-
91
- max_freq = (
92
- policy->cpuinfo.max_freq *
93
- (100 - reduction_pctg(policy->cpu) * 20)
94
- ) / 100;
95
-
96
- cpufreq_verify_within_limits(policy, 0, max_freq);
97
-
98
- out:
99
- return 0;
100
-}
101
-
102
-static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
103
- .notifier_call = acpi_thermal_cpufreq_notifier,
104
-};
10565
10666 static int cpufreq_get_max_state(unsigned int cpu)
10767 {
....@@ -121,7 +81,10 @@
12181
12282 static int cpufreq_set_cur_state(unsigned int cpu, int state)
12383 {
124
- int i;
84
+ struct cpufreq_policy *policy;
85
+ struct acpi_processor *pr;
86
+ unsigned long max_freq;
87
+ int i, ret;
12588
12689 if (!cpu_has_cpufreq(cpu))
12790 return 0;
....@@ -134,33 +97,63 @@
13497 * frequency.
13598 */
13699 for_each_online_cpu(i) {
137
- if (topology_physical_package_id(i) ==
100
+ if (topology_physical_package_id(i) !=
138101 topology_physical_package_id(cpu))
139
- cpufreq_update_policy(i);
102
+ continue;
103
+
104
+ pr = per_cpu(processors, i);
105
+
106
+ if (unlikely(!freq_qos_request_active(&pr->thermal_req)))
107
+ continue;
108
+
109
+ policy = cpufreq_cpu_get(i);
110
+ if (!policy)
111
+ return -EINVAL;
112
+
113
+ max_freq = (policy->cpuinfo.max_freq * (100 - reduction_pctg(i) * 20)) / 100;
114
+
115
+ cpufreq_cpu_put(policy);
116
+
117
+ ret = freq_qos_update_request(&pr->thermal_req, max_freq);
118
+ if (ret < 0) {
119
+ pr_warn("Failed to update thermal freq constraint: CPU%d (%d)\n",
120
+ pr->id, ret);
121
+ }
140122 }
141123 return 0;
142124 }
143125
144
-void acpi_thermal_cpufreq_init(void)
126
+void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy)
145127 {
146
- int i;
128
+ unsigned int cpu;
147129
148
- i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block,
149
- CPUFREQ_POLICY_NOTIFIER);
150
- if (!i)
151
- acpi_thermal_cpufreq_is_init = 1;
130
+ for_each_cpu(cpu, policy->related_cpus) {
131
+ struct acpi_processor *pr = per_cpu(processors, cpu);
132
+ int ret;
133
+
134
+ if (!pr)
135
+ continue;
136
+
137
+ ret = freq_qos_add_request(&policy->constraints,
138
+ &pr->thermal_req,
139
+ FREQ_QOS_MAX, INT_MAX);
140
+ if (ret < 0)
141
+ pr_err("Failed to add freq constraint for CPU%d (%d)\n",
142
+ cpu, ret);
143
+ }
152144 }
153145
154
-void acpi_thermal_cpufreq_exit(void)
146
+void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
155147 {
156
- if (acpi_thermal_cpufreq_is_init)
157
- cpufreq_unregister_notifier
158
- (&acpi_thermal_cpufreq_notifier_block,
159
- CPUFREQ_POLICY_NOTIFIER);
148
+ unsigned int cpu;
160149
161
- acpi_thermal_cpufreq_is_init = 0;
150
+ for_each_cpu(cpu, policy->related_cpus) {
151
+ struct acpi_processor *pr = per_cpu(processors, cpu);
152
+
153
+ if (pr)
154
+ freq_qos_remove_request(&pr->thermal_req);
155
+ }
162156 }
163
-
164157 #else /* ! CONFIG_CPU_FREQ */
165158 static int cpufreq_get_max_state(unsigned int cpu)
166159 {