On 14 May 2011 c. 01:09:03 Christopher Zimmermann wrote: > On 05/13/11 20:56, Alexander Polakov wrote: > > * Marco Peereboom<sl...@peereboom.us> [110512 17:59]: > >> On Thu, May 12, 2011 at 03:32:56PM +0200, Christopher Zimmermann wrote: > >>> On 05/12/11 14:37, Vadim Zhukov wrote: > >>>> Hello all. > >>>> > >>>> Here is a patch that allows for me to work on other things. :) > >>>> Basically, it makes OS choose fan mode instead of firmware. Main > >>>> feature here is enabling of "disengadged" mode when temperature > >>>> goes critical, picking 80C as a "red line". Now I can fully load > >>>> CPU on my X201i - say, "make -j 4" - and it still works instead > >>>> of being powering off by acpitz(4). > >> > >> User space will not be allowed to play. I don't have a stinkpad so > >> I can't test this but I do encourage people to play with this diff > >> and report to the list. > > > > My thinkpad is AMD-powered, so 60 degrees is *normal* for it. With > > this diff the fan is always running at max speed, generating lots of > > noise. > > I think the THINKPAD_FANMODE_MAX part could be left out. The normal > automatic should be able to set maximum speed at a model specific > appropriate temperature. The important part is the disengaged mode, > because the automatic regulation of the firmware is not able to set > this mode.
Received your letter just before rebooting new kernel. :) New version acts as you say: place fan in disengadged mode on critical overheat, and return to automatical firmware management when temperature goes back to (more or less) normal. I also made temperature and fan mode sensors fill sensor status. If anyone objects, I'll make this a separate diff, of course. -- Best wishes, Vadim Zhukov A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail? Index: acpithinkpad.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.26 diff -u -p -r1.26 acpithinkpad.c --- acpithinkpad.c 27 Apr 2011 20:55:42 -0000 1.26 +++ acpithinkpad.c 13 May 2011 21:36:43 -0000 @@ -71,11 +71,21 @@ #define THINKPAD_POWER_CHANGED 0x6030 #define THINKPAD_SWITCH_WIRELESS 0x7000 -#define THINKPAD_NSENSORS 9 -#define THINKPAD_NTEMPSENSORS 8 +#define THINKPAD_NSENSORS 10 +#define THINKPAD_NTEMPSENSORS 8 + +#define THINKPAD_SENSOR_FANRPM (THINKPAD_NTEMPSENSORS + 0) +#define THINKPAD_SENSOR_FANMODE (THINKPAD_NTEMPSENSORS + 1) #define THINKPAD_ECOFFSET_FANLO 0x84 #define THINKPAD_ECOFFSET_FANHI 0x85 +#define THINKPAD_ECOFFSET_FANMODE 0x2f + +#define THINKPAD_FANMODE_AUTO 0x80 +#define THINKPAD_FANMODE_DISENGADGED 0x40 + +/* critical temperature mark, in Celsius */ +#define THINKPAD_TEMP_OUCH 80 struct acpithinkpad_softc { struct device sc_dev; @@ -103,7 +113,7 @@ int thinkpad_volume_mute(struct acpithin int thinkpad_brightness_up(struct acpithinkpad_softc *); int thinkpad_brightness_down(struct acpithinkpad_softc *); -void thinkpad_sensor_attach(struct acpithinkpad_softc *sc); +void thinkpad_sensor_attach(struct acpithinkpad_softc *); void thinkpad_sensor_refresh(void *); struct cfattach acpithinkpad_ca = { @@ -156,8 +166,12 @@ thinkpad_sensor_attach(struct acpithinkp } /* Add fan probe */ - sc->sc_sens[i].type = SENSOR_FANRPM; - sensor_attach(&sc->sc_sensdev, &sc->sc_sens[i]); + sc->sc_sens[THINKPAD_SENSOR_FANRPM].type = SENSOR_FANRPM; + sensor_attach(&sc->sc_sensdev, &sc->sc_sens[THINKPAD_SENSOR_FANRPM]); + + /* Add fan mode indicator */ + sc->sc_sens[THINKPAD_SENSOR_FANMODE].type = SENSOR_INTEGER; + sensor_attach(&sc->sc_sensdev, &sc->sc_sens[THINKPAD_SENSOR_FANMODE]); sensordev_install(&sc->sc_sensdev); } @@ -166,9 +180,11 @@ void thinkpad_sensor_refresh(void *arg) { struct acpithinkpad_softc *sc = arg; - u_int8_t lo, hi, i; - int64_t tmp; + u_int8_t lo, hi, i, mode; + int64_t tmp, maxtmp = -127; /* minimal correct value, see below */ + enum sensor_status ss; char sname[5]; + const char *desc; /* Refresh sensor readings */ for (i=0; i<THINKPAD_NTEMPSENSORS; i++) { @@ -176,14 +192,41 @@ thinkpad_sensor_refresh(void *arg) aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode, sname, 0, 0, &tmp); sc->sc_sens[i].value = (tmp * 1000000) + 273150000; - if (tmp > 127 || tmp < -127) + if (tmp > 127 || tmp < -127) { sc->sc_sens[i].flags = SENSOR_FINVALID; + sc->sc_sens[i].status = SENSOR_S_UNKNOWN; + } + if ((sc->sc_sens[i].flags & SENSOR_FINVALID) == SENSOR_FINVALID) + continue; + if (tmp > maxtmp) + maxtmp = tmp; + if (tmp > THINKPAD_TEMP_OUCH) + sc->sc_sens[i].status = SENSOR_S_CRIT; + else + sc->sc_sens[i].status = SENSOR_S_OK; } /* Read fan RPM */ acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANLO, 1, &lo); acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANHI, 1, &hi); - sc->sc_sens[i].value = ((hi << 8L) + lo); + sc->sc_sens[THINKPAD_SENSOR_FANRPM].value = ((hi << 8L) + lo); + + /* Update fan mode based on max temperature seen */ + if (maxtmp > THINKPAD_TEMP_OUCH) { + mode = THINKPAD_FANMODE_DISENGADGED; + desc = "disengadged"; + ss = SENSOR_S_CRIT; + } else { + mode = THINKPAD_FANMODE_AUTO; + desc = "auto"; + ss = SENSOR_S_OK; + } + acpiec_write(sc->sc_ec, THINKPAD_ECOFFSET_FANMODE, 1, &mode); + sc->sc_sens[THINKPAD_SENSOR_FANMODE].value = mode; + sc->sc_sens[THINKPAD_SENSOR_FANMODE].status = ss; + snprintf(sc->sc_sens[THINKPAD_SENSOR_FANMODE].desc, + sizeof(sc->sc_sens[THINKPAD_SENSOR_FANMODE]), + "fan mode: %s", desc); } void