diff options
| author | Tabrez Ahmed <tabreztalks@gmail.com> | 2026-03-08 15:47:14 +0300 |
|---|---|---|
| committer | Guenter Roeck <linux@roeck-us.net> | 2026-03-31 05:45:06 +0300 |
| commit | 487a9ab28fdd4df773b68c953e69a6f6ecc2fe68 (patch) | |
| tree | b3705c5b5a8a50d1a2f5d9fc007cb4c843956af7 | |
| parent | 0a42986b65776759490ac960910651c1e4634b17 (diff) | |
| download | linux-487a9ab28fdd4df773b68c953e69a6f6ecc2fe68.tar.xz | |
hwmon: (ads7871) Propagate SPI errors in voltage_show
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>
| -rw-r--r-- | drivers/hwmon/ads7871.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index 753bf77ce19b..9bfdf9e6bcd7 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c @@ -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); |
