public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] therm_adt746x: Record pwm invert bit at module load time
@ 2009-11-30 23:47 Darrick J. Wong
  2009-12-01  7:59 ` Michel Dänzer
  2009-12-04  2:20 ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 4+ messages in thread
From: Darrick J. Wong @ 2009-11-30 23:47 UTC (permalink / raw)
  To: Michel Dänzer, Benjamin Herrenschmidt; +Cc: lm-sensors, linux-kernel

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>
---

 drivers/macintosh/therm_adt746x.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)


diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 556f0fe..386a797 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -79,6 +79,7 @@ struct thermostat {
 	u8			limits[3];
 	int			last_speed[2];
 	int			last_var[2];
+	int			pwm_inv[2];
 };
 
 static enum {ADT7460, ADT7467} therm_type;
@@ -229,19 +230,23 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
 	
 	if (speed >= 0) {
 		manual = read_reg(th, MANUAL_MODE[fan]);
+		manual &= ~INVERT_MASK;
 		write_reg(th, MANUAL_MODE[fan],
-			(manual|MANUAL_MASK) & (~INVERT_MASK));
+			manual | MANUAL_MASK | th->pwm_inv[fan]);
 		write_reg(th, FAN_SPD_SET[fan], speed);
 	} else {
 		/* back to automatic */
 		if(therm_type == ADT7460) {
 			manual = read_reg(th,
 				MANUAL_MODE[fan]) & (~MANUAL_MASK);
-
+			manual &= ~INVERT_MASK;
+			manual |= th->pwm_inv[fan];
 			write_reg(th,
 				MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
 		} else {
 			manual = read_reg(th, MANUAL_MODE[fan]);
+			manual &= ~INVERT_MASK;
+			manual |= th->pwm_inv[fan];
 			write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK));
 		}
 	}
@@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_client *client,
 
 	thermostat = th;
 
+	/* record invert bit status because fw can corrupt it after suspend */
+	th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
+	th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
+
 	/* be sure to really write fan speed the first time */
 	th->last_speed[0] = -2;
 	th->last_speed[1] = -2;

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] therm_adt746x: Record pwm invert bit at module load time
  2009-11-30 23:47 [PATCH] therm_adt746x: Record pwm invert bit at module load time Darrick J. Wong
@ 2009-12-01  7:59 ` Michel Dänzer
  2009-12-04  2:20 ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 4+ messages in thread
From: Michel Dänzer @ 2009-12-01  7:59 UTC (permalink / raw)
  To: djwong; +Cc: Benjamin Herrenschmidt, lm-sensors, linux-kernel

On Mon, 2009-11-30 at 15:47 -0800, Darrick J. Wong wrote: 
> 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>

Reviewed-by: Michel Dänzer <michel@daenzer.net>

Looks great, thanks Darrick. Also FWIW, at least loading the patched
driver works as expected on my PowerBook5,8 which has the invert bit
disabled.


> ---
> 
>  drivers/macintosh/therm_adt746x.c |   13 +++++++++++--
>  1 files changed, 11 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
> index 556f0fe..386a797 100644
> --- a/drivers/macintosh/therm_adt746x.c
> +++ b/drivers/macintosh/therm_adt746x.c
> @@ -79,6 +79,7 @@ struct thermostat {
>  	u8			limits[3];
>  	int			last_speed[2];
>  	int			last_var[2];
> +	int			pwm_inv[2];
>  };
>  
>  static enum {ADT7460, ADT7467} therm_type;
> @@ -229,19 +230,23 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
>  	
>  	if (speed >= 0) {
>  		manual = read_reg(th, MANUAL_MODE[fan]);
> +		manual &= ~INVERT_MASK;
>  		write_reg(th, MANUAL_MODE[fan],
> -			(manual|MANUAL_MASK) & (~INVERT_MASK));
> +			manual | MANUAL_MASK | th->pwm_inv[fan]);
>  		write_reg(th, FAN_SPD_SET[fan], speed);
>  	} else {
>  		/* back to automatic */
>  		if(therm_type == ADT7460) {
>  			manual = read_reg(th,
>  				MANUAL_MODE[fan]) & (~MANUAL_MASK);
> -
> +			manual &= ~INVERT_MASK;
> +			manual |= th->pwm_inv[fan];
>  			write_reg(th,
>  				MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
>  		} else {
>  			manual = read_reg(th, MANUAL_MODE[fan]);
> +			manual &= ~INVERT_MASK;
> +			manual |= th->pwm_inv[fan];
>  			write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK));
>  		}
>  	}
> @@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_client *client,
>  
>  	thermostat = th;
>  
> +	/* record invert bit status because fw can corrupt it after suspend */
> +	th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
> +	th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
> +
>  	/* be sure to really write fan speed the first time */
>  	th->last_speed[0] = -2;
>  	th->last_speed[1] = -2;



-- 
Earthling Michel Dänzer           |                http://www.vmware.com
Libre software enthusiast         |          Debian, X and DRI developer

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] therm_adt746x: Record pwm invert bit at module load time
  2009-11-30 23:47 [PATCH] therm_adt746x: Record pwm invert bit at module load time Darrick J. Wong
  2009-12-01  7:59 ` Michel Dänzer
@ 2009-12-04  2:20 ` Benjamin Herrenschmidt
  2009-12-04  8:44   ` [lm-sensors] " Jean Delvare
  1 sibling, 1 reply; 4+ messages in thread
From: Benjamin Herrenschmidt @ 2009-12-04  2:20 UTC (permalink / raw)
  To: djwong; +Cc: Michel Dänzer, lm-sensors, linux-kernel

On Mon, 2009-11-30 at 15:47 -0800, Darrick J. Wong wrote:
> 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.

Thanks, I'll apply.

Cheers,
Ben.

> Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
> ---
> 
>  drivers/macintosh/therm_adt746x.c |   13 +++++++++++--
>  1 files changed, 11 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
> index 556f0fe..386a797 100644
> --- a/drivers/macintosh/therm_adt746x.c
> +++ b/drivers/macintosh/therm_adt746x.c
> @@ -79,6 +79,7 @@ struct thermostat {
>  	u8			limits[3];
>  	int			last_speed[2];
>  	int			last_var[2];
> +	int			pwm_inv[2];
>  };
>  
>  static enum {ADT7460, ADT7467} therm_type;
> @@ -229,19 +230,23 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
>  	
>  	if (speed >= 0) {
>  		manual = read_reg(th, MANUAL_MODE[fan]);
> +		manual &= ~INVERT_MASK;
>  		write_reg(th, MANUAL_MODE[fan],
> -			(manual|MANUAL_MASK) & (~INVERT_MASK));
> +			manual | MANUAL_MASK | th->pwm_inv[fan]);
>  		write_reg(th, FAN_SPD_SET[fan], speed);
>  	} else {
>  		/* back to automatic */
>  		if(therm_type == ADT7460) {
>  			manual = read_reg(th,
>  				MANUAL_MODE[fan]) & (~MANUAL_MASK);
> -
> +			manual &= ~INVERT_MASK;
> +			manual |= th->pwm_inv[fan];
>  			write_reg(th,
>  				MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
>  		} else {
>  			manual = read_reg(th, MANUAL_MODE[fan]);
> +			manual &= ~INVERT_MASK;
> +			manual |= th->pwm_inv[fan];
>  			write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK));
>  		}
>  	}
> @@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_client *client,
>  
>  	thermostat = th;
>  
> +	/* record invert bit status because fw can corrupt it after suspend */
> +	th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
> +	th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
> +
>  	/* be sure to really write fan speed the first time */
>  	th->last_speed[0] = -2;
>  	th->last_speed[1] = -2;



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [lm-sensors] [PATCH] therm_adt746x: Record pwm invert bit at  module load time
  2009-12-04  2:20 ` Benjamin Herrenschmidt
@ 2009-12-04  8:44   ` Jean Delvare
  0 siblings, 0 replies; 4+ messages in thread
From: Jean Delvare @ 2009-12-04  8:44 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: djwong, Michel Dänzer, linux-kernel, lm-sensors

On Fri, 04 Dec 2009 13:20:11 +1100, Benjamin Herrenschmidt wrote:
> On Mon, 2009-11-30 at 15:47 -0800, Darrick J. Wong wrote:
> > 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.
> 
> Thanks, I'll apply.

This is a pretty serious bug, please make sure to send the fix to the
stable team for kernels 2.6.31 and 2.6.32.

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-12-04  8:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-30 23:47 [PATCH] therm_adt746x: Record pwm invert bit at module load time Darrick J. Wong
2009-12-01  7:59 ` Michel Dänzer
2009-12-04  2:20 ` Benjamin Herrenschmidt
2009-12-04  8:44   ` [lm-sensors] " Jean Delvare

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox