git: c9882d7600f9 - stable/13 - htu21: don't needlessly bother hardware when measurements are not needed

From: Andriy Gapon <avg_at_FreeBSD.org>
Date: Sat, 13 Nov 2021 09:05:00 UTC
The branch stable/13 has been updated by avg:

URL: https://cgit.FreeBSD.org/src/commit/?id=c9882d7600f95d5aa9dfb369548900148a47a950

commit c9882d7600f95d5aa9dfb369548900148a47a950
Author:     Andriy Gapon <avg@FreeBSD.org>
AuthorDate: 2021-11-06 16:47:32 +0000
Commit:     Andriy Gapon <avg@FreeBSD.org>
CommitDate: 2021-11-13 08:59:33 +0000

    htu21: don't needlessly bother hardware when measurements are not needed
    
    sysctl(8) first queries a sysctl to get a size of its value even if the
    sysctl is of a fixed size, e.g. it has an integer type.
    Only after that sysctl(8) queries an actual value of the sysctl.
    
    Previosuly the driver would needlessly read a sensor in the first step.
    
    (cherry picked from commit 43b031a371eb90c15c390c26202f5f58d09300ef)
---
 sys/dev/iicbus/htu21.c | 88 +++++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 40 deletions(-)

diff --git a/sys/dev/iicbus/htu21.c b/sys/dev/iicbus/htu21.c
index 5c59ebe8f54a..24f868eb5165 100644
--- a/sys/dev/iicbus/htu21.c
+++ b/sys/dev/iicbus/htu21.c
@@ -192,21 +192,24 @@ htu21_temp_sysctl(SYSCTL_HANDLER_ARGS)
 	dev = arg1;
 	sc = device_get_softc(dev);
 
-	if (sc->sc_hold)
-		error = htu21_get_measurement(dev, HTU21_GET_TEMP,
-		    raw_data, nitems(raw_data));
-	else
-		error = htu21_get_measurement_nohold(dev, HTU21_GET_TEMP_NH,
-		    raw_data, nitems(raw_data));
-
-	if (error != 0) {
-		return (EIO);
-	} else if (!check_crc_16(raw_data, raw_data[2])) {
-		temp = -1;
-		sc->sc_errcount++;
-	} else {
-		temp = (((uint16_t)raw_data[0]) << 8) | (raw_data[1] & 0xfc);
-		temp = ((temp * 17572) >> 16 ) + 27315 - 4685;
+	if (req->oldptr != NULL) {
+		if (sc->sc_hold)
+			error = htu21_get_measurement(dev, HTU21_GET_TEMP,
+			    raw_data, nitems(raw_data));
+		else
+			error = htu21_get_measurement_nohold(dev,
+			    HTU21_GET_TEMP_NH, raw_data, nitems(raw_data));
+
+		if (error != 0) {
+			return (EIO);
+		} else if (!check_crc_16(raw_data, raw_data[2])) {
+			temp = -1;
+			sc->sc_errcount++;
+		} else {
+			temp = (((uint16_t)raw_data[0]) << 8) |
+			    (raw_data[1] & 0xfc);
+			temp = ((temp * 17572) >> 16 ) + 27315 - 4685;
+		}
 	}
 
 	error = sysctl_handle_int(oidp, &temp, 0, req);
@@ -224,21 +227,24 @@ htu21_rh_sysctl(SYSCTL_HANDLER_ARGS)
 	dev = arg1;
 	sc = device_get_softc(dev);
 
-	if (sc->sc_hold)
-		error = htu21_get_measurement(dev, HTU21_GET_HUM,
-		    raw_data, nitems(raw_data));
-	else
-		error = htu21_get_measurement_nohold(dev, HTU21_GET_HUM_NH,
-		    raw_data, nitems(raw_data));
-
-	if (error != 0) {
-		return (EIO);
-	} else if (!check_crc_16(raw_data, raw_data[2])) {
-		rh = -1;
-		sc->sc_errcount++;
-	} else {
-		rh = (((uint16_t)raw_data[0]) << 8) | (raw_data[1] & 0xfc);
-		rh = ((rh * 12500) >> 16 ) - 600;
+	if (req->oldptr != NULL) {
+		if (sc->sc_hold)
+			error = htu21_get_measurement(dev, HTU21_GET_HUM,
+			    raw_data, nitems(raw_data));
+		else
+			error = htu21_get_measurement_nohold(dev,
+			    HTU21_GET_HUM_NH, raw_data, nitems(raw_data));
+
+		if (error != 0) {
+			return (EIO);
+		} else if (!check_crc_16(raw_data, raw_data[2])) {
+			rh = -1;
+			sc->sc_errcount++;
+		} else {
+			rh = (((uint16_t)raw_data[0]) << 8) |
+			    (raw_data[1] & 0xfc);
+			rh = ((rh * 12500) >> 16 ) - 600;
+		}
 	}
 
 	error = sysctl_handle_int(oidp, &rh, 0, req);
@@ -302,11 +308,12 @@ htu21_heater_sysctl(SYSCTL_HANDLER_ARGS)
 	dev = arg1;
 	sc = device_get_softc(dev);
 
-	error = htu21_get_cfg(dev, &cfg);
-	if (error != 0)
-		return (EIO);
-
-	heater = (cfg & 0x04) != 0;
+	if (req->oldptr != NULL) {
+		error = htu21_get_cfg(dev, &cfg);
+		if (error != 0)
+			return (EIO);
+		heater = (cfg & 0x04) != 0;
+	}
 	error = sysctl_handle_int(oidp, &heater, 0, req);
 	if (error != 0 || req->newptr == NULL)
 		return (error);
@@ -328,11 +335,12 @@ htu21_power_sysctl(SYSCTL_HANDLER_ARGS)
 	dev = arg1;
 	sc = device_get_softc(dev);
 
-	error = htu21_get_cfg(dev, &cfg);
-	if (error != 0)
-		return (EIO);
-
-	power = (cfg & 0x40) == 0;
+	if (req->oldptr != NULL) {
+		error = htu21_get_cfg(dev, &cfg);
+		if (error != 0)
+			return (EIO);
+		power = (cfg & 0x40) == 0;
+	}
 	error = sysctl_handle_int(oidp, &power, 0, req);
 	return (error);
 }