]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
hwmon: (ads7871) Propagate SPI errors in voltage_show
authorTabrez Ahmed <tabreztalks@gmail.com>
Sun, 8 Mar 2026 12:47:14 +0000 (18:17 +0530)
committerGuenter Roeck <linux@roeck-us.net>
Tue, 31 Mar 2026 02:45:06 +0000 (19:45 -0700)
The voltage_show() function previously ignored negative error codes
returned by the underlying SPI read/write functions. Because negative
numbers have their most significant bits set in two's complement, a
failed SPI read returning -EIO (-5) would incorrectly evaluate to true
when masked with MUX_CNV_BM (0x80).

This would cause the driver to enter the polling loop even when the SPI bus
failed, eventually returning a misleading -ETIMEDOUT error to userspace
instead of the actual hardware error. Furthermore, the return values of
the initial SPI write and the final 16-bit SPI read were completely
ignored.

Add proper error checking after every SPI operation to ensure hardware
failures are immediately propagated back to userspace.

Suggested-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Tabrez Ahmed <tabreztalks@gmail.com>
Link: https://lore.kernel.org/r/20260308124714.84715-1-tabreztalks@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/ads7871.c

index 753bf77ce19b4c8ae5c706d05681332c72f6cec1..9bfdf9e6bcd77d599cc6a262cf43301b6a3688ca 100644 (file)
@@ -104,10 +104,14 @@ static ssize_t voltage_show(struct device *dev, struct device_attribute *da,
         */
        /*MUX_M3_BM forces single ended*/
        /*This is also where the gain of the PGA would be set*/
-       ads7871_write_reg8(spi, REG_GAIN_MUX,
-               (MUX_CNV_BM | MUX_M3_BM | channel));
+       ret = ads7871_write_reg8(spi, REG_GAIN_MUX,
+                                (MUX_CNV_BM | MUX_M3_BM | channel));
+       if (ret < 0)
+               return ret;
 
        ret = ads7871_read_reg8(spi, REG_GAIN_MUX);
+       if (ret < 0)
+               return ret;
        mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV);
        /*
         * on 400MHz arm9 platform the conversion
@@ -116,12 +120,16 @@ static ssize_t voltage_show(struct device *dev, struct device_attribute *da,
        while ((i < 2) && mux_cnv) {
                i++;
                ret = ads7871_read_reg8(spi, REG_GAIN_MUX);
+               if (ret < 0)
+                       return ret;
                mux_cnv = ((ret & MUX_CNV_BM) >> MUX_CNV_BV);
                msleep_interruptible(1);
        }
 
        if (mux_cnv == 0) {
                val = ads7871_read_reg16(spi, REG_LS_BYTE);
+               if (val < 0)
+                       return val;
                /*result in volts*10000 = (val/8192)*2.5*10000*/
                val = ((val >> 2) * 25000) / 8192;
                return sysfs_emit(buf, "%d\n", val);