Re: Thinkpad active cooling
On Fri, Jul 17, 2015 at 08:54:26PM +0200, Mark Kettenis wrote: > Tobias Ulmer schreef op 2015-07-15 02:33: > >As we all know, some Thinkpads have problems with their EC fan control. > >EC is not spinning up the fans to maximum speed, let alone blast mode. > >They also do not offer ACPI methods to spin the fan up. > > > >Previous diffs doing manual fan control were always rejected because > >hooking into the sensors framework with fixed temp limits is crude and > >there are concerns with slowing the fan down and frying the hardware. > > > >This is an attempt to solve the problem slightly differently. > >- Hook into acpitz and only speed the fan up when it is requesting active > > cooling > >- Never set the fan to a mode that would endanger the hardware should we > > crash > > > >PS: It would be nice if there was a function to add cooling methods to > >acpitz eg: acpitz_add(void (*fn)(struct acpitz_softc *, void *), void > >*arg) > >I tried but getting struct acpitz_softc into a header is a bit messy. > > Does the AML define any active cooling trip points (_AC0, _AC1, etc)? No, not in my machines. Aside from not checking for interference with ACPI, this diff can't handle multiple thermal zones in a sensible manner. There's also the problem of not throttling the CPU fast enough for the little thermal mass in some machines. And I suspect acpitz_refresh() is not running frequent enough to regulate properly. I need to play with this some more, not feeling good about it just yet.. > > >Index: acpithinkpad.c > >=== > >RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpithinkpad.c,v > >retrieving revision 1.44 > >diff -u -p -r1.44 acpithinkpad.c > >--- acpithinkpad.c 24 Apr 2015 14:44:17 - 1.44 > >+++ acpithinkpad.c 14 Jul 2015 23:52:14 - > >@@ -104,6 +104,11 @@ > > #define THINKPAD_ECOFFSET_FANLO 0x84 > > #define THINKPAD_ECOFFSET_FANHI 0x85 > > > >+#define THINKPAD_ECOFFSET_FANLEVEL 0x2f > >+#define THINKPAD_ECFANLEVEL_MAX 7 > >+#define THINKPAD_ECFANLEVEL_BLAST (1<<6) > >+#define THINKPAD_ECFANLEVEL_AUTO(1<<7) > >+ > > #define THINKPAD_ADAPTIVE_MODE_HOME 1 > > #define THINKPAD_ADAPTIVE_MODE_FUNCTION 3 > > > >@@ -119,6 +124,7 @@ struct acpithinkpad_softc { > > }; > > > > extern void acpiec_read(struct acpiec_softc *, u_int8_t, int, u_int8_t > >*); > >+extern void (*acpitz_activecool)(int, int); > > > > int thinkpad_match(struct device *, void *, void *); > > voidthinkpad_attach(struct device *, struct device *, void *); > >@@ -134,6 +140,7 @@ int thinkpad_brightness_up(struct acpith > > int thinkpad_brightness_down(struct acpithinkpad_softc *); > > int thinkpad_adaptive_change(struct acpithinkpad_softc *); > > int thinkpad_activate(struct device *, int); > >+voidthinkpad_activecool(int, int); > > > > voidthinkpad_sensor_attach(struct acpithinkpad_softc *sc); > > voidthinkpad_sensor_refresh(void *); > >@@ -228,6 +235,7 @@ thinkpad_attach(struct device *parent, s > > { > > struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self; > > struct acpi_attach_args *aa = aux; > >+u_int8_t level; > > > > sc->sc_acpi = (struct acpi_softc *)parent; > > sc->sc_devnode = aa->aaa_node; > >@@ -241,6 +249,11 @@ thinkpad_attach(struct device *parent, s > > /* Run thinkpad_hotkey on button presses */ > > aml_register_notify(sc->sc_devnode, aa->aaa_dev, > > thinkpad_hotkey, sc, ACPIDEV_POLL); > >+ > >+/* Make sure fan is in auto mode, otherwise we're not sure of support */ > >+acpiec_read(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, &level); > >+if (level == THINKPAD_ECFANLEVEL_AUTO) > >+acpitz_activecool = thinkpad_activecool; > > } > > > > int > >@@ -546,4 +559,30 @@ thinkpad_activate(struct device *self, i > > break; > > } > > return (0); > >+} > >+ > >+void > >+thinkpad_activecool(int tmp, int psv) > >+{ > >+static uint8_t level = THINKPAD_ECFANLEVEL_AUTO; > >+uint8_t nlevel; > >+ > >+if (tmp < 0 || psv < 0) > >+return; > >+ > >+if (tmp > psv) > >+nlevel = THINKPAD_ECFANLEVEL_BLAST; > >+else if (tmp > psv-50) > >+/* EC firmware fan control is too slow in some models. When > >+ * we're getting within 5C of active cooling mode, turn the > >+ * fan to MAX. Helps with oscillation between blast and auto */ > >+nlevel = THINKPAD_ECFANLEVEL_MAX; > >+else > >+nlevel = THINKPAD_ECFANLEVEL_AUTO; > >+ > >+if (nlevel != level) { > >+acpiec_write(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, > >+&nlevel); > >+level = nlevel; > >+} > > } > >Index: acpitz.c > >=== > >RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpitz.c,v > >retrieving revision 1.49 > >diff -u
Re: Thinkpad active cooling
17 июля 2015 г. 22:24 пользователь "Mark Kettenis" написал: > > Tobias Ulmer schreef op 2015-07-15 05:42: > >> On Wed, Jul 15, 2015 at 05:12:41AM +0300, Paul Irofti wrote: >>> >>> I am not familiar with all the fan hack specifics so please keep that in mind >>> if my questions and comments seem trivial. >>> >>> > This is an attempt to solve the problem slightly differently. >>> > - Hook into acpitz and only speed the fan up when it is requesting active >>> > cooling >>> > - Never set the fan to a mode that would endanger the hardware should we >>> > crash >>> >>> Your diff applies to all Thinkpad models. Is that okay? >> >> >> It applies to all Thinkpads that have a sensible value in >> THINKPAD_ECOFFSET_FANLEVEL, as you noticed. There is no flag or >> documentation indicating the existence of this register as far as I >> know. It's somewhat of a tradition, every TP I've owned had it. >> >> My hope is if they drop support or move the offset, the value will >> change and we won't do any damage. > > > The Linux thinkpad-acpi driver suggests that accessing (and especially writing to) the > THINKPAD_ECOFFSET_FANLEVEL register should not be done if the GFAN and/or SFAN ACPI method > exists. > > The Linux driver also says that full blast mode might damage the fan. I've run my thinkpads in disengaged mode at least 30% of their life. Never had a problem with fans. Neither I heard a word about broken fans from people running my "disengaged" patches. And overheating damages CPU, which is much more expensive to replace. -- Vadim Zhukov
Re: Thinkpad active cooling
Tobias Ulmer schreef op 2015-07-15 02:33: As we all know, some Thinkpads have problems with their EC fan control. EC is not spinning up the fans to maximum speed, let alone blast mode. They also do not offer ACPI methods to spin the fan up. Previous diffs doing manual fan control were always rejected because hooking into the sensors framework with fixed temp limits is crude and there are concerns with slowing the fan down and frying the hardware. This is an attempt to solve the problem slightly differently. - Hook into acpitz and only speed the fan up when it is requesting active cooling - Never set the fan to a mode that would endanger the hardware should we crash PS: It would be nice if there was a function to add cooling methods to acpitz eg: acpitz_add(void (*fn)(struct acpitz_softc *, void *), void *arg) I tried but getting struct acpitz_softc into a header is a bit messy. Does the AML define any active cooling trip points (_AC0, _AC1, etc)? Index: acpithinkpad.c === RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.44 diff -u -p -r1.44 acpithinkpad.c --- acpithinkpad.c 24 Apr 2015 14:44:17 - 1.44 +++ acpithinkpad.c 14 Jul 2015 23:52:14 - @@ -104,6 +104,11 @@ #define THINKPAD_ECOFFSET_FANLO0x84 #define THINKPAD_ECOFFSET_FANHI0x85 +#define THINKPAD_ECOFFSET_FANLEVEL 0x2f +#define THINKPAD_ECFANLEVEL_MAX7 +#define THINKPAD_ECFANLEVEL_BLAST (1<<6) +#define THINKPAD_ECFANLEVEL_AUTO (1<<7) + #defineTHINKPAD_ADAPTIVE_MODE_HOME 1 #defineTHINKPAD_ADAPTIVE_MODE_FUNCTION 3 @@ -119,6 +124,7 @@ struct acpithinkpad_softc { }; extern void acpiec_read(struct acpiec_softc *, u_int8_t, int, u_int8_t *); +extern void (*acpitz_activecool)(int, int); intthinkpad_match(struct device *, void *, void *); void thinkpad_attach(struct device *, struct device *, void *); @@ -134,6 +140,7 @@ int thinkpad_brightness_up(struct acpith intthinkpad_brightness_down(struct acpithinkpad_softc *); intthinkpad_adaptive_change(struct acpithinkpad_softc *); intthinkpad_activate(struct device *, int); +voidthinkpad_activecool(int, int); voidthinkpad_sensor_attach(struct acpithinkpad_softc *sc); voidthinkpad_sensor_refresh(void *); @@ -228,6 +235,7 @@ thinkpad_attach(struct device *parent, s { struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self; struct acpi_attach_args *aa = aux; + u_int8_t level; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; @@ -241,6 +249,11 @@ thinkpad_attach(struct device *parent, s /* Run thinkpad_hotkey on button presses */ aml_register_notify(sc->sc_devnode, aa->aaa_dev, thinkpad_hotkey, sc, ACPIDEV_POLL); + + /* Make sure fan is in auto mode, otherwise we're not sure of support */ + acpiec_read(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, &level); + if (level == THINKPAD_ECFANLEVEL_AUTO) + acpitz_activecool = thinkpad_activecool; } int @@ -546,4 +559,30 @@ thinkpad_activate(struct device *self, i break; } return (0); +} + +void +thinkpad_activecool(int tmp, int psv) +{ + static uint8_t level = THINKPAD_ECFANLEVEL_AUTO; + uint8_t nlevel; + + if (tmp < 0 || psv < 0) + return; + + if (tmp > psv) + nlevel = THINKPAD_ECFANLEVEL_BLAST; + else if (tmp > psv-50) + /* EC firmware fan control is too slow in some models. When +* we're getting within 5C of active cooling mode, turn the +* fan to MAX. Helps with oscillation between blast and auto */ + nlevel = THINKPAD_ECFANLEVEL_MAX; + else + nlevel = THINKPAD_ECFANLEVEL_AUTO; + + if (nlevel != level) { + acpiec_write(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, + &nlevel); + level = nlevel; + } } Index: acpitz.c === RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpitz.c,v retrieving revision 1.49 diff -u -p -r1.49 acpitz.c --- acpitz.c6 May 2015 01:41:55 - 1.49 +++ acpitz.c14 Jul 2015 23:52:14 - @@ -86,6 +86,7 @@ int acpitz_setfan(struct acpitz_softc *, void acpitz_init(struct acpitz_softc *, int); void (*acpitz_cpu_setperf)(int); +void(*acpitz_activecool)(int, int) = NULL; intacpitz_perflevel = -1; extern void(*cpu_setperf)(int); extern int perflevel; @@ -427,6 +428,11 @@ acpitz_refresh(void *arg) acpitz_setfan(sc, i, "_OFF"); } } + + /* active cooling hook */ + if (acpitz_activecool) + acpitz_activecool(sc->sc_tmp, sc-
Re: Thinkpad active cooling
Tobias Ulmer schreef op 2015-07-15 05:42: On Wed, Jul 15, 2015 at 05:12:41AM +0300, Paul Irofti wrote: I am not familiar with all the fan hack specifics so please keep that in mind if my questions and comments seem trivial. > This is an attempt to solve the problem slightly differently. > - Hook into acpitz and only speed the fan up when it is requesting active > cooling > - Never set the fan to a mode that would endanger the hardware should we > crash Your diff applies to all Thinkpad models. Is that okay? It applies to all Thinkpads that have a sensible value in THINKPAD_ECOFFSET_FANLEVEL, as you noticed. There is no flag or documentation indicating the existence of this register as far as I know. It's somewhat of a tradition, every TP I've owned had it. My hope is if they drop support or move the offset, the value will change and we won't do any damage. The Linux thinkpad-acpi driver suggests that accessing (and especially writing to) the THINKPAD_ECOFFSET_FANLEVEL register should not be done if the GFAN and/or SFAN ACPI method exists. The Linux driver also says that full blast mode might damage the fan.
Re: Thinkpad active cooling
On Wed, Jul 15, 2015 at 11:28:49PM -0500, Adam Thompson wrote: > Although I agree the fan speed handling under OpenBSD still has room > for improvement... I haven't run OpenBSD on it for any significant > amount of time since the ~recent changes to improve Thinkpad power > usage. The C-state changes were a huge improvement. Thanks again, Philip.
Re: Thinkpad active cooling
On 2015-07-14 09:13 PM, Michael McConville wrote: On Wed, Jul 15, 2015 at 03:04:07AM +0200, Tobias Ulmer wrote: Theo is asking for affected models, so lets compile a list. All my Thinkpads can be provoked into shutdown due to overtemp because the fan doesn't spin up: T60 T61 X201 I've had it happen on my X201, but only once in the ~6 months I've had it. I was building a Coq library with all four cores in a hot lab. It's survived many other build beatings without issue, and I've never noticed a problem with the fans. I'm not questioning that it could be improved, though. FWIW, the X201t can trivially hit thermal throttling under Windows 7 (using the OEM image, even) if you exercise the GPU (easiest way: play a Flash game), although not into complete thermal shutdown. It's a hardware design flaw, not a firmware problem. I've never had my x201t actually hit the thermal limit under OpenBSD - at least not that I've noticed. I don't use it for CPU-intensive work, and I'm not even sure how I would go about exercising the GPU under OpenBSD without Adobe Flash :-). Although I agree the fan speed handling under OpenBSD still has room for improvement... I haven't run OpenBSD on it for any significant amount of time since the ~recent changes to improve Thinkpad power usage. -- -Adam Thompson athom...@athompso.net
Re: Thinkpad active cooling
On Wed, Jul 15, 2015 at 12:03:45AM -0400, Ted Unangst wrote: > Tobias Ulmer wrote: > > As we all know, some Thinkpads have problems with their EC fan control. > > EC is not spinning up the fans to maximum speed, let alone blast mode. > > They also do not offer ACPI methods to spin the fan up. > > > > Previous diffs doing manual fan control were always rejected because > > hooking into the sensors framework with fixed temp limits is crude and > > there are concerns with slowing the fan down and frying the hardware. > > > > This is an attempt to solve the problem slightly differently. > > - Hook into acpitz and only speed the fan up when it is requesting active > > cooling > > - Never set the fan to a mode that would endanger the hardware should we > > crash > > Can you clarify what if any effect should be observed with this diff? Will it > make my fans louder or quieter? > > (I was very happy to discover that with the C states diff, my one thinkpad now > idles at 3000 rpm vs 3500 rpm, and that is actually a lot quieter.) > There should be zero change in behaviour for normal use. Only if thermal zone temp reaches its "passive" cooling limit (93C on my X201) and demands active cooling will it spin the fan up. At the same time acpitz also reduces cpuspeed. Once temps are back to normal it switches to automatic mode and the fans should quiet down.
Re: Thinkpad active cooling
Tobias Ulmer wrote: > As we all know, some Thinkpads have problems with their EC fan control. > EC is not spinning up the fans to maximum speed, let alone blast mode. > They also do not offer ACPI methods to spin the fan up. > > Previous diffs doing manual fan control were always rejected because > hooking into the sensors framework with fixed temp limits is crude and > there are concerns with slowing the fan down and frying the hardware. > > This is an attempt to solve the problem slightly differently. > - Hook into acpitz and only speed the fan up when it is requesting active > cooling > - Never set the fan to a mode that would endanger the hardware should we > crash Can you clarify what if any effect should be observed with this diff? Will it make my fans louder or quieter? (I was very happy to discover that with the C states diff, my one thinkpad now idles at 3000 rpm vs 3500 rpm, and that is actually a lot quieter.)
Re: Thinkpad active cooling
On Wed, Jul 15, 2015 at 05:12:41AM +0300, Paul Irofti wrote: > I am not familiar with all the fan hack specifics so please keep that in mind > if my questions and comments seem trivial. > > > This is an attempt to solve the problem slightly differently. > > - Hook into acpitz and only speed the fan up when it is requesting active > > cooling > > - Never set the fan to a mode that would endanger the hardware should we > > crash > > Your diff applies to all Thinkpad models. Is that okay? It applies to all Thinkpads that have a sensible value in THINKPAD_ECOFFSET_FANLEVEL, as you noticed. There is no flag or documentation indicating the existence of this register as far as I know. It's somewhat of a tradition, every TP I've owned had it. My hope is if they drop support or move the offset, the value will change and we won't do any damage. I'm thinking this can be improved further by querying ACPI for _AC, so it doesn't ever interfere with acpitz_setfan(). I'll look into this. > > > > > PS: It would be nice if there was a function to add cooling methods to > > acpitz eg: acpitz_add(void (*fn)(struct acpitz_softc *, void *), void *arg) > > I tried but getting struct acpitz_softc into a header is a bit messy. > > If needed you can move the softc in the acpivar.h header file. > Nothing messy about it. What other model drivers would need this though? So far none, but I imagine we will see more software controlled power management in the future. I guess I just don't like global variables and extern declarations :) > > thinkpad_hotkey, sc, ACPIDEV_POLL); > > + > > + /* Make sure fan is in auto mode, otherwise we're not sure of support */ > > + acpiec_read(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, &level); > > + if (level == THINKPAD_ECFANLEVEL_AUTO) > > + acpitz_activecool = thinkpad_activecool; > > Why is there no support if the fan is not in auto mode? Trying not to break future models. > > > + else if (tmp > psv-50) > > + /* EC firmware fan control is too slow in some models. When > > +* we're getting within 5C of active cooling mode, turn the > > +* fan to MAX. Helps with oscillation between blast and auto */ > > This comment does not follow KNF :-) Heh, I'll fix that to make you happy ;) > > > + nlevel = THINKPAD_ECFANLEVEL_MAX; > > + else > > + nlevel = THINKPAD_ECFANLEVEL_AUTO; > > + > > + if (nlevel != level) { > > + acpiec_write(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, > > + &nlevel); > > + level = nlevel; > > + } > > } > > Index: acpitz.c > > === > > RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpitz.c,v > > retrieving revision 1.49 > > diff -u -p -r1.49 acpitz.c > > --- acpitz.c6 May 2015 01:41:55 - 1.49 > > +++ acpitz.c14 Jul 2015 23:52:14 - > > @@ -86,6 +86,7 @@ int acpitz_setfan(struct acpitz_softc *, > > void acpitz_init(struct acpitz_softc *, int); > > > > void (*acpitz_cpu_setperf)(int); > > +void(*acpitz_activecool)(int, int) = NULL; > > intacpitz_perflevel = -1; > > extern void(*cpu_setperf)(int); > > extern int perflevel; > > @@ -427,6 +428,11 @@ acpitz_refresh(void *arg) > > acpitz_setfan(sc, i, "_OFF"); > > } > > } > > + > > + /* active cooling hook */ > > + if (acpitz_activecool) > > + acpitz_activecool(sc->sc_tmp, sc->sc_psv); > > + > > I'm not sure, but is it ever possible for acpitz to attach BEFORE > acpithinkpad and render this check false? > Would you need to somehow tie the two together? The check evaluating to false is not a problem, it will become true in time, it's a slow running loop. I didn't see any locking around acpitz_cpu_setperf(), so I'm guessing it's fine
Re: Thinkpad active cooling
On Wed, Jul 15, 2015 at 03:04:07AM +0200, Tobias Ulmer wrote: > Theo is asking for affected models, so lets compile a list. > All my Thinkpads can be provoked into shutdown due to overtemp because > the fan doesn't spin up: > > T60 > T61 > X201 I've had it happen on my X201, but only once in the ~6 months I've had it. I was building a Coq library with all four cores in a hot lab. It's survived many other build beatings without issue, and I've never noticed a problem with the fans. I'm not questioning that it could be improved, though.
Re: Thinkpad active cooling
I am not familiar with all the fan hack specifics so please keep that in mind if my questions and comments seem trivial. > This is an attempt to solve the problem slightly differently. > - Hook into acpitz and only speed the fan up when it is requesting active > cooling > - Never set the fan to a mode that would endanger the hardware should we > crash Your diff applies to all Thinkpad models. Is that okay? > > PS: It would be nice if there was a function to add cooling methods to > acpitz eg: acpitz_add(void (*fn)(struct acpitz_softc *, void *), void *arg) > I tried but getting struct acpitz_softc into a header is a bit messy. If needed you can move the softc in the acpivar.h header file. Nothing messy about it. What other model drivers would need this though? thinkpad_hotkey, sc, ACPIDEV_POLL); > + > + /* Make sure fan is in auto mode, otherwise we're not sure of support */ > + acpiec_read(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, &level); > + if (level == THINKPAD_ECFANLEVEL_AUTO) > + acpitz_activecool = thinkpad_activecool; Why is there no support if the fan is not in auto mode? > + else if (tmp > psv-50) > + /* EC firmware fan control is too slow in some models. When > + * we're getting within 5C of active cooling mode, turn the > + * fan to MAX. Helps with oscillation between blast and auto */ This comment does not follow KNF :-) > + nlevel = THINKPAD_ECFANLEVEL_MAX; > + else > + nlevel = THINKPAD_ECFANLEVEL_AUTO; > + > + if (nlevel != level) { > + acpiec_write(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, > + &nlevel); > + level = nlevel; > + } > } > Index: acpitz.c > === > RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpitz.c,v > retrieving revision 1.49 > diff -u -p -r1.49 acpitz.c > --- acpitz.c 6 May 2015 01:41:55 - 1.49 > +++ acpitz.c 14 Jul 2015 23:52:14 - > @@ -86,6 +86,7 @@ int acpitz_setfan(struct acpitz_softc *, > void acpitz_init(struct acpitz_softc *, int); > > void (*acpitz_cpu_setperf)(int); > +void(*acpitz_activecool)(int, int) = NULL; > int acpitz_perflevel = -1; > extern void (*cpu_setperf)(int); > extern int perflevel; > @@ -427,6 +428,11 @@ acpitz_refresh(void *arg) > acpitz_setfan(sc, i, "_OFF"); > } > } > + > + /* active cooling hook */ > + if (acpitz_activecool) > + acpitz_activecool(sc->sc_tmp, sc->sc_psv); > + I'm not sure, but is it ever possible for acpitz to attach BEFORE acpithinkpad and render this check false? Would you need to somehow tie the two together?
Re: Thinkpad active cooling
Theo is asking for affected models, so lets compile a list. All my Thinkpads can be provoked into shutdown due to overtemp because the fan doesn't spin up: T60 T61 X201
Thinkpad active cooling
As we all know, some Thinkpads have problems with their EC fan control. EC is not spinning up the fans to maximum speed, let alone blast mode. They also do not offer ACPI methods to spin the fan up. Previous diffs doing manual fan control were always rejected because hooking into the sensors framework with fixed temp limits is crude and there are concerns with slowing the fan down and frying the hardware. This is an attempt to solve the problem slightly differently. - Hook into acpitz and only speed the fan up when it is requesting active cooling - Never set the fan to a mode that would endanger the hardware should we crash PS: It would be nice if there was a function to add cooling methods to acpitz eg: acpitz_add(void (*fn)(struct acpitz_softc *, void *), void *arg) I tried but getting struct acpitz_softc into a header is a bit messy. Index: acpithinkpad.c === RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.44 diff -u -p -r1.44 acpithinkpad.c --- acpithinkpad.c 24 Apr 2015 14:44:17 - 1.44 +++ acpithinkpad.c 14 Jul 2015 23:52:14 - @@ -104,6 +104,11 @@ #define THINKPAD_ECOFFSET_FANLO0x84 #define THINKPAD_ECOFFSET_FANHI0x85 +#define THINKPAD_ECOFFSET_FANLEVEL 0x2f +#define THINKPAD_ECFANLEVEL_MAX7 +#define THINKPAD_ECFANLEVEL_BLAST (1<<6) +#define THINKPAD_ECFANLEVEL_AUTO (1<<7) + #defineTHINKPAD_ADAPTIVE_MODE_HOME 1 #defineTHINKPAD_ADAPTIVE_MODE_FUNCTION 3 @@ -119,6 +124,7 @@ struct acpithinkpad_softc { }; extern void acpiec_read(struct acpiec_softc *, u_int8_t, int, u_int8_t *); +extern void (*acpitz_activecool)(int, int); intthinkpad_match(struct device *, void *, void *); void thinkpad_attach(struct device *, struct device *, void *); @@ -134,6 +140,7 @@ int thinkpad_brightness_up(struct acpith intthinkpad_brightness_down(struct acpithinkpad_softc *); intthinkpad_adaptive_change(struct acpithinkpad_softc *); intthinkpad_activate(struct device *, int); +voidthinkpad_activecool(int, int); voidthinkpad_sensor_attach(struct acpithinkpad_softc *sc); voidthinkpad_sensor_refresh(void *); @@ -228,6 +235,7 @@ thinkpad_attach(struct device *parent, s { struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self; struct acpi_attach_args *aa = aux; + u_int8_t level; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; @@ -241,6 +249,11 @@ thinkpad_attach(struct device *parent, s /* Run thinkpad_hotkey on button presses */ aml_register_notify(sc->sc_devnode, aa->aaa_dev, thinkpad_hotkey, sc, ACPIDEV_POLL); + + /* Make sure fan is in auto mode, otherwise we're not sure of support */ + acpiec_read(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, &level); + if (level == THINKPAD_ECFANLEVEL_AUTO) + acpitz_activecool = thinkpad_activecool; } int @@ -546,4 +559,30 @@ thinkpad_activate(struct device *self, i break; } return (0); +} + +void +thinkpad_activecool(int tmp, int psv) +{ + static uint8_t level = THINKPAD_ECFANLEVEL_AUTO; + uint8_t nlevel; + + if (tmp < 0 || psv < 0) + return; + + if (tmp > psv) + nlevel = THINKPAD_ECFANLEVEL_BLAST; + else if (tmp > psv-50) + /* EC firmware fan control is too slow in some models. When +* we're getting within 5C of active cooling mode, turn the +* fan to MAX. Helps with oscillation between blast and auto */ + nlevel = THINKPAD_ECFANLEVEL_MAX; + else + nlevel = THINKPAD_ECFANLEVEL_AUTO; + + if (nlevel != level) { + acpiec_write(acpi_softc->sc_ec, THINKPAD_ECOFFSET_FANLEVEL, 1, + &nlevel); + level = nlevel; + } } Index: acpitz.c === RCS file: /home/vcs/cvs/openbsd/src/sys/dev/acpi/acpitz.c,v retrieving revision 1.49 diff -u -p -r1.49 acpitz.c --- acpitz.c6 May 2015 01:41:55 - 1.49 +++ acpitz.c14 Jul 2015 23:52:14 - @@ -86,6 +86,7 @@ int acpitz_setfan(struct acpitz_softc *, void acpitz_init(struct acpitz_softc *, int); void (*acpitz_cpu_setperf)(int); +void(*acpitz_activecool)(int, int) = NULL; intacpitz_perflevel = -1; extern void(*cpu_setperf)(int); extern int perflevel; @@ -427,6 +428,11 @@ acpitz_refresh(void *arg) acpitz_setfan(sc, i, "_OFF"); } } + + /* active cooling hook */ + if (acpitz_activecool) + acpitz_activecool(sc->sc_tmp, sc->sc_psv); + sc->sc_sens.value = sc->sc_tmp * 10 - 5; }