aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh/windfarm_smu_controls.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-02-08 00:42:51 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-08 01:05:14 -0500
commitac171c46667c1cb2ee9e22312291df6ed78e1b6e (patch)
tree86ca722abc1ddceb0887b3ed6a195d77bb200dc2 /drivers/macintosh/windfarm_smu_controls.c
parent746f956beb534ddf73da4346de81f2941c8573f8 (diff)
[PATCH] powerpc: Thermal control for dual core G5s
This patch adds a windfarm module, windfarm_pm112, for the dual core G5s (both 2 and 4 core models), keeping the machine from getting into vacuum-cleaner mode ;) For proper credits, the patch was initially written by Paul Mackerras, and slightly reworked by me to add overtemp handling among others. The patch also removes the sysfs attributes from windfarm_pm81 and windfarm_pm91 and instead adds code to the windfarm core to automagically expose attributes for sensor & controls. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/macintosh/windfarm_smu_controls.c')
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c69
1 files changed, 54 insertions, 15 deletions
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index 4d811600bdab..a9e88edc0c72 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -24,7 +24,7 @@
24 24
25#include "windfarm.h" 25#include "windfarm.h"
26 26
27#define VERSION "0.3" 27#define VERSION "0.4"
28 28
29#undef DEBUG 29#undef DEBUG
30 30
@@ -34,6 +34,8 @@
34#define DBG(args...) do { } while(0) 34#define DBG(args...) do { } while(0)
35#endif 35#endif
36 36
37static int smu_supports_new_fans_ops = 1;
38
37/* 39/*
38 * SMU fans control object 40 * SMU fans control object
39 */ 41 */
@@ -59,23 +61,49 @@ static int smu_set_fan(int pwm, u8 id, u16 value)
59 61
60 /* Fill SMU command structure */ 62 /* Fill SMU command structure */
61 cmd.cmd = SMU_CMD_FAN_COMMAND; 63 cmd.cmd = SMU_CMD_FAN_COMMAND;
62 cmd.data_len = 14; 64
65 /* The SMU has an "old" and a "new" way of setting the fan speed
66 * Unfortunately, I found no reliable way to know which one works
67 * on a given machine model. After some investigations it appears
68 * that MacOS X just tries the new one, and if it fails fallbacks
69 * to the old ones ... Ugh.
70 */
71 retry:
72 if (smu_supports_new_fans_ops) {
73 buffer[0] = 0x30;
74 buffer[1] = id;
75 *((u16 *)(&buffer[2])) = value;
76 cmd.data_len = 4;
77 } else {
78 if (id > 7)
79 return -EINVAL;
80 /* Fill argument buffer */
81 memset(buffer, 0, 16);
82 buffer[0] = pwm ? 0x10 : 0x00;
83 buffer[1] = 0x01 << id;
84 *((u16 *)&buffer[2 + id * 2]) = value;
85 cmd.data_len = 14;
86 }
87
63 cmd.reply_len = 16; 88 cmd.reply_len = 16;
64 cmd.data_buf = cmd.reply_buf = buffer; 89 cmd.data_buf = cmd.reply_buf = buffer;
65 cmd.status = 0; 90 cmd.status = 0;
66 cmd.done = smu_done_complete; 91 cmd.done = smu_done_complete;
67 cmd.misc = &comp; 92 cmd.misc = &comp;
68 93
69 /* Fill argument buffer */
70 memset(buffer, 0, 16);
71 buffer[0] = pwm ? 0x10 : 0x00;
72 buffer[1] = 0x01 << id;
73 *((u16 *)&buffer[2 + id * 2]) = value;
74
75 rc = smu_queue_cmd(&cmd); 94 rc = smu_queue_cmd(&cmd);
76 if (rc) 95 if (rc)
77 return rc; 96 return rc;
78 wait_for_completion(&comp); 97 wait_for_completion(&comp);
98
99 /* Handle fallback (see coment above) */
100 if (cmd.status != 0 && smu_supports_new_fans_ops) {
101 printk(KERN_WARNING "windfarm: SMU failed new fan command "
102 "falling back to old method\n");
103 smu_supports_new_fans_ops = 0;
104 goto retry;
105 }
106
79 return cmd.status; 107 return cmd.status;
80} 108}
81 109
@@ -158,19 +186,29 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
158 186
159 /* Names used on desktop models */ 187 /* Names used on desktop models */
160 if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || 188 if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") ||
161 !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan")) 189 !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") ||
190 !strcmp(l, "CPU A EXHAUST"))
162 fct->ctrl.name = "cpu-rear-fan-0"; 191 fct->ctrl.name = "cpu-rear-fan-0";
163 else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1")) 192 else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") ||
193 !strcmp(l, "CPU B EXHAUST"))
164 fct->ctrl.name = "cpu-rear-fan-1"; 194 fct->ctrl.name = "cpu-rear-fan-1";
165 else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || 195 else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") ||
166 !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan")) 196 !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") ||
197 !strcmp(l, "CPU A INTAKE"))
167 fct->ctrl.name = "cpu-front-fan-0"; 198 fct->ctrl.name = "cpu-front-fan-0";
168 else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1")) 199 else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") ||
200 !strcmp(l, "CPU B INTAKE"))
169 fct->ctrl.name = "cpu-front-fan-1"; 201 fct->ctrl.name = "cpu-front-fan-1";
170 else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan")) 202 else if (!strcmp(l, "CPU A PUMP"))
203 fct->ctrl.name = "cpu-pump-0";
204 else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") ||
205 !strcmp(l, "EXPANSION SLOTS INTAKE"))
171 fct->ctrl.name = "slots-fan"; 206 fct->ctrl.name = "slots-fan";
172 else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay")) 207 else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") ||
208 !strcmp(l, "DRIVE BAY A INTAKE"))
173 fct->ctrl.name = "drive-bay-fan"; 209 fct->ctrl.name = "drive-bay-fan";
210 else if (!strcmp(l, "BACKSIDE"))
211 fct->ctrl.name = "backside-fan";
174 212
175 /* Names used on iMac models */ 213 /* Names used on iMac models */
176 if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) 214 if (!strcmp(l, "System Fan") || !strcmp(l, "System fan"))
@@ -223,7 +261,8 @@ static int __init smu_controls_init(void)
223 261
224 /* Look for RPM fans */ 262 /* Look for RPM fans */
225 for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) 263 for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
226 if (!strcmp(fans->name, "rpm-fans")) 264 if (!strcmp(fans->name, "rpm-fans") ||
265 device_is_compatible(fans, "smu-rpm-fans"))
227 break; 266 break;
228 for (fan = NULL; 267 for (fan = NULL;
229 fans && (fan = of_get_next_child(fans, fan)) != NULL;) { 268 fans && (fan = of_get_next_child(fans, fan)) != NULL;) {