acpithinkpad sets up a hard-coded number of temperature sensors and doesn't check the result of aml_evalinteger when polling, so for all invalid sensors it ends up reporting the value of the previous successful sensor check resulting in this (for a machine with only a TMP0 sensor):
hw.sensors.acpithinkpad0.temp0=47.00 degC hw.sensors.acpithinkpad0.temp1=47.00 degC hw.sensors.acpithinkpad0.temp2=47.00 degC hw.sensors.acpithinkpad0.temp3=47.00 degC hw.sensors.acpithinkpad0.temp4=47.00 degC hw.sensors.acpithinkpad0.temp5=47.00 degC hw.sensors.acpithinkpad0.temp6=47.00 degC hw.sensors.acpithinkpad0.temp7=47.00 degC hw.sensors.acpithinkpad0.fan0=3605 RPM hw.sensors.acpithinkpad0.indicator0=Off (port replicator), UNKNOWN This diff checks whether the TMP[0-8] node actually exists during attach and if not, it doesn't create the sensor. It also checks the return value during polling and sets the sensor to invalid if it failed for some reason. hw.sensors.acpithinkpad0.temp0=55.00 degC hw.sensors.acpithinkpad0.fan0=5045 RPM hw.sensors.acpithinkpad0.indicator0=Off (port replicator), UNKNOWN Index: sys/dev/acpi/acpithinkpad.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.70 diff -u -p -u -p -r1.70 acpithinkpad.c --- sys/dev/acpi/acpithinkpad.c 6 Apr 2022 18:59:27 -0000 1.70 +++ sys/dev/acpi/acpithinkpad.c 5 Apr 2023 03:43:59 -0000 @@ -112,11 +112,10 @@ #define THINKPAD_TABLET_SCREEN_CHANGED 0x60c0 #define THINKPAD_SWITCH_WIRELESS 0x7000 -#define THINKPAD_NSENSORS 10 -#define THINKPAD_NTEMPSENSORS 8 - -#define THINKPAD_SENSOR_FANRPM THINKPAD_NTEMPSENSORS -#define THINKPAD_SENSOR_PORTREPL THINKPAD_NTEMPSENSORS + 1 +#define THINKPAD_SENSOR_FANRPM 0 +#define THINKPAD_SENSOR_PORTREPL 1 +#define THINKPAD_SENSOR_TMP0 2 +#define THINKPAD_NSENSORS 10 #define THINKPAD_ECOFFSET_VOLUME 0x30 #define THINKPAD_ECOFFSET_VOLUME_MUTE_MASK 0x40 @@ -140,6 +139,7 @@ struct acpithinkpad_softc { struct ksensor sc_sens[THINKPAD_NSENSORS]; struct ksensordev sc_sensdev; + int sc_ntempsens; uint64_t sc_hkey_version; @@ -178,6 +178,7 @@ int thinkpad_get_brightness(struct acpit int thinkpad_set_brightness(void *, int); int thinkpad_get_param(struct wsdisplay_param *); int thinkpad_set_param(struct wsdisplay_param *); +int thinkpad_get_temp(struct acpithinkpad_softc *, int, int64_t *); void thinkpad_sensor_attach(struct acpithinkpad_softc *sc); void thinkpad_sensor_refresh(void *); @@ -228,6 +229,7 @@ thinkpad_match(struct device *parent, vo void thinkpad_sensor_attach(struct acpithinkpad_softc *sc) { + int64_t tmp; int i; if (sc->sc_acpi->sc_ec == NULL) @@ -237,10 +239,16 @@ thinkpad_sensor_attach(struct acpithinkp /* Add temperature probes */ strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), sizeof(sc->sc_sensdev.xname)); - for (i=0; i<THINKPAD_NTEMPSENSORS; i++) { - sc->sc_sens[i].type = SENSOR_TEMP; - sensor_attach(&sc->sc_sensdev, &sc->sc_sens[i]); - } + sc->sc_ntempsens = 0; + for (i = 0; i < THINKPAD_NSENSORS - THINKPAD_SENSOR_TMP0; i++) { + if (thinkpad_get_temp(sc, i, &tmp) != 0) + break; + + sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].type = SENSOR_TEMP; + sensor_attach(&sc->sc_sensdev, + &sc->sc_sens[THINKPAD_SENSOR_TMP0 + i]); + sc->sc_ntempsens++; + } /* Add fan probe */ sc->sc_sens[THINKPAD_SENSOR_FANRPM].type = SENSOR_FANRPM; @@ -262,17 +270,19 @@ thinkpad_sensor_refresh(void *arg) struct acpithinkpad_softc *sc = arg; uint8_t lo, hi, i; int64_t tmp; - char sname[5]; /* Refresh sensor readings */ - for (i=0; i<THINKPAD_NTEMPSENSORS; i++) { - snprintf(sname, sizeof(sname), "TMP%d", i); - 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) - sc->sc_sens[i].flags = SENSOR_FINVALID; - } + for (i = 0; i < sc->sc_ntempsens; i++) { + if (thinkpad_get_temp(sc, i, &tmp) != 0) { + sc->sc_sens[i].flags = SENSOR_FINVALID; + continue; + } + + sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].value = + (tmp * 1000000) + 273150000; + sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].flags = + (tmp > 127 || tmp < -127) ? SENSOR_FINVALID : 0; + } /* Read fan RPM */ acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANLO, 1, &lo); @@ -321,10 +331,8 @@ thinkpad_attach(struct device *parent, s wskbd_set_backlight = thinkpad_set_kbd_backlight; } - /* On version 2 and newer, let *drm or acpivout control brightness */ - if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION1 && - (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", - 0, NULL, &sc->sc_brightness) == 0)) { + if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", + 0, NULL, &sc->sc_brightness) == 0) { ws_get_param = thinkpad_get_param; ws_set_param = thinkpad_set_param; } @@ -785,6 +793,20 @@ thinkpad_set_param(struct wsdisplay_para default: return -1; } +} + +int +thinkpad_get_temp(struct acpithinkpad_softc *sc, int idx, int64_t *temp) +{ + char sname[5]; + + snprintf(sname, sizeof(sname), "TMP%d", idx); + + if (aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode, sname, 0, 0, + temp) != 0) + return (1); + + return (0); } #if NAUDIO > 0 && NWSKBD > 0