summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuiz Angelo Daros de Luca <luizluca@gmail.com>2026-07-27 21:22:18 -0300
committerGuenter Roeck <linux@roeck-us.net>2026-07-27 17:54:08 -0700
commit05270bd38d9bf88a2f4c212246a8fa29f4032078 (patch)
tree87058a905b6f8f62cd2a74d552f74269072483a9
parent625a2c02a1c04571232a746fe188b4d9a8d63edd (diff)
downloadlinux-next-05270bd38d9bf88a2f4c212246a8fa29f4032078.tar.gz
linux-next-05270bd38d9bf88a2f4c212246a8fa29f4032078.zip
hwmon: (adt7470) Fix cache updated before hardware write on I2C error
adt7470_temp_write() and adt7470_pwm_write() update the driver's cached values (temp_min, temp_max, pwm_input, pwm_enable) before issuing the corresponding regmap_write(), and never check whether the write succeeded before committing that update. If the I2C transaction fails, the function correctly propagates the error to the caller, but the cache silently keeps the new value, which was never actually applied to the hardware. Subsequent reads then report a value that does not match the device state. Reorder both write paths to update the cache only after a successful regmap_write(), so the cache always reflects what was actually written to the hardware. Fixes: ef67959c4253 ("hwmon: (adt7470) Convert to use regmap") Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> Link: https://lore.kernel.org/r/20260727-adt7470_fixes-v2-2-598e38a46ba6@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/adt7470.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 481d51617f4b..62ec68ea0a40 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -589,14 +589,16 @@ static int adt7470_temp_write(struct device *dev, u32 attr, int channel, long va
switch (attr) {
case hwmon_temp_min:
mutex_lock(&data->lock);
- data->temp_min[channel] = val;
err = regmap_write(data->regmap, ADT7470_TEMP_MIN_REG(channel), val);
+ if (!err)
+ data->temp_min[channel] = val;
mutex_unlock(&data->lock);
break;
case hwmon_temp_max:
mutex_lock(&data->lock);
- data->temp_max[channel] = val;
err = regmap_write(data->regmap, ADT7470_TEMP_MAX_REG(channel), val);
+ if (!err)
+ data->temp_max[channel] = val;
mutex_unlock(&data->lock);
break;
default:
@@ -831,9 +833,10 @@ static int adt7470_pwm_write(struct device *dev, u32 attr, int channel, long val
case hwmon_pwm_input:
val = clamp_val(val, 0, 255);
mutex_lock(&data->lock);
- data->pwm[channel] = val;
err = regmap_write(data->regmap, ADT7470_REG_PWM(channel),
- data->pwm[channel]);
+ val);
+ if (!err)
+ data->pwm[channel] = val;
mutex_unlock(&data->lock);
break;
case hwmon_pwm_enable:
@@ -847,10 +850,11 @@ static int adt7470_pwm_write(struct device *dev, u32 attr, int channel, long val
val--;
mutex_lock(&data->lock);
- data->pwm_automatic[channel] = val;
err = regmap_update_bits(data->regmap, ADT7470_REG_PWM_CFG(channel),
pwm_auto_reg_mask,
val ? pwm_auto_reg_mask : 0);
+ if (!err)
+ data->pwm_automatic[channel] = val;
mutex_unlock(&data->lock);
break;
case hwmon_pwm_freq: