[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Name of kernel driver that manages fan (PowerBook5,8)



Hi Michel, Hi All

On Fri, May 15, 2009 at 12:35:18PM +0200, Michel Dänzer wrote:
> On Fri, 2009-05-15 at 12:12 +0200, Wolfgang Pfeiffer wrote:
> > 
> > Sometimes my fan seems to hang, at a very high speed, IINM, that is,
> >  
> > /sys/devices/temperatures/sensor1_fan_speed
> > 
> > in these cases gives me a value of something like
> > 
> > 0 (3859 rpm)
> > 
> > I'd (wild .. :) guess the second value simply means the number of
> > rounds/min the fan is spinning ... No idea what the first number
> > means.
> > 
> > The only chance - so far - to stop the fan in these instances, is a
> > reboot. I'd like to avoid the latter, by simply trying to 
> > switch off/on the driver that is responsible for the fan ...
> > 
> > So anyone knows the name of this driver? Is there one? Or is it solely
> > a firmware issue? Hints?
> 
> It's a bug in the therm_adt746x driver, it sometimes sets the hardware
> bit which inverts the meaning of the fan speed register. The patch below
> fixes it for me, I'm going to submit it for inclusion.

Just a little feed-back, that I - sort of - was promising quite some
time ago: Your patch, Michel - or better, a slightly edited version
that you wrote, and which I found, IIRC, on the Internet - works great
here: I haven't had this situation ever again with a fan running high
and endlessly since I installed a self rolled, non-Debian 2.6.30
kernel from, IINM, kernel.org, that I patched with the file you
thankfully published.

I installed this patched kernel, IINM, around 3 months ago on the
Powerbook5,8, and I use it on a nearly daily basis, time and again
with a CPU & fans running very high. Plus, I reboot very rarely: In all
this time I don't remember even one single instance where the fans
went belly up on me.

I attach this patch I used for the 2.6.30.

And for everyone else out there: please note that this patched
therm_adt746x.c is already part of the latest git kernel sources. So,
no need to apply it to such fresh kernels ...

Michel,
I owe you not just one pizza, and beer: So if you're around Stuttgart,
Germany, then I hope you'll holler at me, so I can pay my debts ... :)

Thank you for your precious work ... 

Regards
Wolfgang

PS: I cut some header in this email to make sure it will be detached
from the very old original thread, and to make sure it's not going to be
unnoted in there ...


> 
> 
> diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
> index 82607ad..d2575d5 100644
> --- a/drivers/macintosh/therm_adt746x.c
> +++ b/drivers/macintosh/therm_adt746x.c
> @@ -37,6 +37,7 @@
>  #define CONFIG_REG   0x40
>  #define MANUAL_MASK  0xe0
>  #define AUTO_MASK    0x20
> +#define INVERT_MASK  0x10
>  
>  static u8 TEMP_REG[3]    = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */
>  static u8 LIMIT_REG[3]   = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */
> @@ -229,7 +227,9 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
>  	
>  	if (speed >= 0) {
>  		manual = read_reg(th, MANUAL_MODE[fan]);
> -		write_reg(th, MANUAL_MODE[fan], manual|MANUAL_MASK);
> +		write_reg(th, MANUAL_MODE[fan],
> +			(manual|MANUAL_MASK) & (~INVERT_MASK));
>  		write_reg(th, FAN_SPD_SET[fan], speed);
>  	} else {
>  		/* back to automatic */
> 
> 

-- 
http://heelsbroke.wordpress.com
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 82607ad..321eaad 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -37,6 +37,7 @@
 #define CONFIG_REG   0x40
 #define MANUAL_MASK  0xe0
 #define AUTO_MASK    0x20
+#define INVERT_MASK  0x10
 
 static u8 TEMP_REG[3]    = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */
 static u8 LIMIT_REG[3]   = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */
@@ -229,7 +230,8 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
 	
 	if (speed >= 0) {
 		manual = read_reg(th, MANUAL_MODE[fan]);
-		write_reg(th, MANUAL_MODE[fan], manual|MANUAL_MASK);
+		write_reg(th, MANUAL_MODE[fan],
+			(manual|MANUAL_MASK) & (~INVERT_MASK));
 		write_reg(th, FAN_SPD_SET[fan], speed);
 	} else {
 		/* back to automatic */


Reply to: