aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2009-12-03 11:19:59 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-12-09 01:09:31 -0500
commit1496e89ae2a0962748e55165a590fa3209c6f158 (patch)
tree7cc992051eae48946cf11fa9595447e5bb0cf7b6
parent37580f3f229fa72f2ef73ea7df0a1d28a9dab36d (diff)
powerpc/therm_adt746x: Record pwm invert bit at module load time]
In commit 0512a9a8e277a9de2820211eef964473b714ae65, we unilaterally zero the "pwm invert" bit in the fan behavior configuration register. On my PowerBook G4, this results in the fans going to full speed at low temperature and shutting off at high temperature because the pwm invert bit is supposed to be set. Therefore, record the pwm invert bit at driver load time, and write the bit into the fan behavior control register. This restores correct behavior on my PBG4 and should work around the bit being set to the wrong value after suspend/resume (which is what the original patch was trying to fix). It also fixes a minor omission where the pwm invert bit correction is NOT performed when switching into automatic mode. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> CC: <stable@kernel.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--drivers/macintosh/therm_adt746x.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 95b676a19be7..5ff47ba7f2d0 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -79,6 +79,7 @@ struct thermostat {
79 u8 limits[3]; 79 u8 limits[3];
80 int last_speed[2]; 80 int last_speed[2];
81 int last_var[2]; 81 int last_var[2];
82 int pwm_inv[2];
82}; 83};
83 84
84static enum {ADT7460, ADT7467} therm_type; 85static enum {ADT7460, ADT7467} therm_type;
@@ -229,19 +230,23 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
229 230
230 if (speed >= 0) { 231 if (speed >= 0) {
231 manual = read_reg(th, MANUAL_MODE[fan]); 232 manual = read_reg(th, MANUAL_MODE[fan]);
233 manual &= ~INVERT_MASK;
232 write_reg(th, MANUAL_MODE[fan], 234 write_reg(th, MANUAL_MODE[fan],
233 (manual|MANUAL_MASK) & (~INVERT_MASK)); 235 manual | MANUAL_MASK | th->pwm_inv[fan]);
234 write_reg(th, FAN_SPD_SET[fan], speed); 236 write_reg(th, FAN_SPD_SET[fan], speed);
235 } else { 237 } else {
236 /* back to automatic */ 238 /* back to automatic */
237 if(therm_type == ADT7460) { 239 if(therm_type == ADT7460) {
238 manual = read_reg(th, 240 manual = read_reg(th,
239 MANUAL_MODE[fan]) & (~MANUAL_MASK); 241 MANUAL_MODE[fan]) & (~MANUAL_MASK);
240 242 manual &= ~INVERT_MASK;
243 manual |= th->pwm_inv[fan];
241 write_reg(th, 244 write_reg(th,
242 MANUAL_MODE[fan], manual|REM_CONTROL[fan]); 245 MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
243 } else { 246 } else {
244 manual = read_reg(th, MANUAL_MODE[fan]); 247 manual = read_reg(th, MANUAL_MODE[fan]);
248 manual &= ~INVERT_MASK;
249 manual |= th->pwm_inv[fan];
245 write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); 250 write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK));
246 } 251 }
247 } 252 }
@@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_client *client,
418 423
419 thermostat = th; 424 thermostat = th;
420 425
426 /* record invert bit status because fw can corrupt it after suspend */
427 th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
428 th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
429
421 /* be sure to really write fan speed the first time */ 430 /* be sure to really write fan speed the first time */
422 th->last_speed[0] = -2; 431 th->last_speed[0] = -2;
423 th->last_speed[1] = -2; 432 th->last_speed[1] = -2;