hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/macintosh/windfarm_cpufreq_clamp.c
....@@ -1,10 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/types.h>
23 #include <linux/errno.h>
34 #include <linux/kernel.h>
45 #include <linux/delay.h>
6
+#include <linux/pm_qos.h>
57 #include <linux/slab.h>
68 #include <linux/init.h>
79 #include <linux/wait.h>
10
+#include <linux/cpu.h>
811 #include <linux/cpufreq.h>
912
1013 #include <asm/prom.h>
....@@ -15,36 +18,24 @@
1518
1619 static int clamped;
1720 static struct wf_control *clamp_control;
18
-
19
-static int clamp_notifier_call(struct notifier_block *self,
20
- unsigned long event, void *data)
21
-{
22
- struct cpufreq_policy *p = data;
23
- unsigned long max_freq;
24
-
25
- if (event != CPUFREQ_ADJUST)
26
- return 0;
27
-
28
- max_freq = clamped ? (p->cpuinfo.min_freq) : (p->cpuinfo.max_freq);
29
- cpufreq_verify_within_limits(p, 0, max_freq);
30
-
31
- return 0;
32
-}
33
-
34
-static struct notifier_block clamp_notifier = {
35
- .notifier_call = clamp_notifier_call,
36
-};
21
+static struct freq_qos_request qos_req;
22
+static unsigned int min_freq, max_freq;
3723
3824 static int clamp_set(struct wf_control *ct, s32 value)
3925 {
40
- if (value)
26
+ unsigned int freq;
27
+
28
+ if (value) {
29
+ freq = min_freq;
4130 printk(KERN_INFO "windfarm: Clamping CPU frequency to "
4231 "minimum !\n");
43
- else
32
+ } else {
33
+ freq = max_freq;
4434 printk(KERN_INFO "windfarm: CPU frequency unclamped !\n");
35
+ }
4536 clamped = value;
46
- cpufreq_update_policy(0);
47
- return 0;
37
+
38
+ return freq_qos_update_request(&qos_req, freq);
4839 }
4940
5041 static int clamp_get(struct wf_control *ct, s32 *value)
....@@ -73,27 +64,66 @@
7364
7465 static int __init wf_cpufreq_clamp_init(void)
7566 {
67
+ struct cpufreq_policy *policy;
7668 struct wf_control *clamp;
69
+ struct device *dev;
70
+ int ret;
71
+
72
+ policy = cpufreq_cpu_get(0);
73
+ if (!policy) {
74
+ pr_warn("%s: cpufreq policy not found cpu0\n", __func__);
75
+ return -EPROBE_DEFER;
76
+ }
77
+
78
+ min_freq = policy->cpuinfo.min_freq;
79
+ max_freq = policy->cpuinfo.max_freq;
80
+
81
+ ret = freq_qos_add_request(&policy->constraints, &qos_req, FREQ_QOS_MAX,
82
+ max_freq);
83
+
84
+ cpufreq_cpu_put(policy);
85
+
86
+ if (ret < 0) {
87
+ pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
88
+ ret);
89
+ return ret;
90
+ }
91
+
92
+ dev = get_cpu_device(0);
93
+ if (unlikely(!dev)) {
94
+ pr_warn("%s: No cpu device for cpu0\n", __func__);
95
+ ret = -ENODEV;
96
+ goto fail;
97
+ }
7798
7899 clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
79
- if (clamp == NULL)
80
- return -ENOMEM;
81
- cpufreq_register_notifier(&clamp_notifier, CPUFREQ_POLICY_NOTIFIER);
100
+ if (clamp == NULL) {
101
+ ret = -ENOMEM;
102
+ goto fail;
103
+ }
104
+
82105 clamp->ops = &clamp_ops;
83106 clamp->name = "cpufreq-clamp";
84
- if (wf_register_control(clamp))
85
- goto fail;
107
+ ret = wf_register_control(clamp);
108
+ if (ret)
109
+ goto free;
110
+
86111 clamp_control = clamp;
87112 return 0;
88
- fail:
113
+
114
+ free:
89115 kfree(clamp);
90
- return -ENODEV;
116
+ fail:
117
+ freq_qos_remove_request(&qos_req);
118
+ return ret;
91119 }
92120
93121 static void __exit wf_cpufreq_clamp_exit(void)
94122 {
95
- if (clamp_control)
123
+ if (clamp_control) {
96124 wf_unregister_control(clamp_control);
125
+ freq_qos_remove_request(&qos_req);
126
+ }
97127 }
98128
99129