diff options
Diffstat (limited to 'drivers/macintosh/windfarm_cpufreq_clamp.c')
-rw-r--r-- | drivers/macintosh/windfarm_cpufreq_clamp.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c new file mode 100644 index 000000000000..607dbaca69c9 --- /dev/null +++ b/drivers/macintosh/windfarm_cpufreq_clamp.c | |||
@@ -0,0 +1,105 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/errno.h> | ||
4 | #include <linux/kernel.h> | ||
5 | #include <linux/delay.h> | ||
6 | #include <linux/slab.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/wait.h> | ||
9 | #include <linux/cpufreq.h> | ||
10 | |||
11 | #include "windfarm.h" | ||
12 | |||
13 | #define VERSION "0.3" | ||
14 | |||
15 | static int clamped; | ||
16 | static struct wf_control *clamp_control; | ||
17 | |||
18 | static int clamp_notifier_call(struct notifier_block *self, | ||
19 | unsigned long event, void *data) | ||
20 | { | ||
21 | struct cpufreq_policy *p = data; | ||
22 | unsigned long max_freq; | ||
23 | |||
24 | if (event != CPUFREQ_ADJUST) | ||
25 | return 0; | ||
26 | |||
27 | max_freq = clamped ? (p->cpuinfo.min_freq) : (p->cpuinfo.max_freq); | ||
28 | cpufreq_verify_within_limits(p, 0, max_freq); | ||
29 | |||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static struct notifier_block clamp_notifier = { | ||
34 | .notifier_call = clamp_notifier_call, | ||
35 | }; | ||
36 | |||
37 | static int clamp_set(struct wf_control *ct, s32 value) | ||
38 | { | ||
39 | if (value) | ||
40 | printk(KERN_INFO "windfarm: Clamping CPU frequency to " | ||
41 | "minimum !\n"); | ||
42 | else | ||
43 | printk(KERN_INFO "windfarm: CPU frequency unclamped !\n"); | ||
44 | clamped = value; | ||
45 | cpufreq_update_policy(0); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int clamp_get(struct wf_control *ct, s32 *value) | ||
50 | { | ||
51 | *value = clamped; | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static s32 clamp_min(struct wf_control *ct) | ||
56 | { | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static s32 clamp_max(struct wf_control *ct) | ||
61 | { | ||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | static struct wf_control_ops clamp_ops = { | ||
66 | .set_value = clamp_set, | ||
67 | .get_value = clamp_get, | ||
68 | .get_min = clamp_min, | ||
69 | .get_max = clamp_max, | ||
70 | .owner = THIS_MODULE, | ||
71 | }; | ||
72 | |||
73 | static int __init wf_cpufreq_clamp_init(void) | ||
74 | { | ||
75 | struct wf_control *clamp; | ||
76 | |||
77 | clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); | ||
78 | if (clamp == NULL) | ||
79 | return -ENOMEM; | ||
80 | cpufreq_register_notifier(&clamp_notifier, CPUFREQ_POLICY_NOTIFIER); | ||
81 | clamp->ops = &clamp_ops; | ||
82 | clamp->name = "cpufreq-clamp"; | ||
83 | if (wf_register_control(clamp)) | ||
84 | goto fail; | ||
85 | clamp_control = clamp; | ||
86 | return 0; | ||
87 | fail: | ||
88 | kfree(clamp); | ||
89 | return -ENODEV; | ||
90 | } | ||
91 | |||
92 | static void __exit wf_cpufreq_clamp_exit(void) | ||
93 | { | ||
94 | if (clamp_control) | ||
95 | wf_unregister_control(clamp_control); | ||
96 | } | ||
97 | |||
98 | |||
99 | module_init(wf_cpufreq_clamp_init); | ||
100 | module_exit(wf_cpufreq_clamp_exit); | ||
101 | |||
102 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | ||
103 | MODULE_DESCRIPTION("CPU frequency clamp for PowerMacs thermal control"); | ||
104 | MODULE_LICENSE("GPL"); | ||
105 | |||