mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
hwmon: (tmp102) Fix jiffies wraparound in conversion-ready check
tmp102 records a one-shot deadline in ->ready_time at probe (and resume)
and, on every temperature read, refuses the read with -EAGAIN while
time_before(jiffies, ready_time) is true, in order to skip the first
~35 ms conversion.
->ready_time is an unsigned long compared with time_before(), whose
signed difference is only meaningful while the two values are within
LONG_MAX jiffies of each other. Because ->ready_time is set once and
never refreshed, jiffies keeps advancing away from it, and after 2^31
jiffies the difference flips sign. On a 32-bit HZ=100 kernel that
happens ~248.5 days after boot: time_before() then permanently reports
"not ready" and the driver returns -EAGAIN on every read, without ever
touching the sensor, until the next reboot.
Store the deadline as a 64-bit jiffies value and compare it with
get_jiffies_64()/time_before64(), which does not wrap in any practical
uptime.
Fixes: 3d8f7a89a1 ("hwmon: (tmp102) Improve handling of initial read delay")
Cc: stable@vger.kernel.org
Signed-off-by: Tom Verdonck <tom.verdonck@inspiral.be>
Link: https://patch.msgid.link/2952f070f82913aea96eec25d28008d3b9058656.1790358356.git.tom.verdonck@inspiral.be
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
e463cd582c
commit
56c1d32323
|
|
@ -58,7 +58,7 @@ struct tmp102 {
|
|||
const char *label;
|
||||
struct regmap *regmap;
|
||||
u16 config_orig;
|
||||
unsigned long ready_time;
|
||||
u64 ready_time;
|
||||
u16 sample_time;
|
||||
};
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ static int tmp102_read_temp(struct device *dev, u32 attr, long *val)
|
|||
switch (attr) {
|
||||
case hwmon_temp_input:
|
||||
/* Is it too early to return a conversion ? */
|
||||
if (time_before(jiffies, tmp102->ready_time)) {
|
||||
if (time_before64(get_jiffies_64(), tmp102->ready_time)) {
|
||||
dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
|
@ -354,7 +354,7 @@ static int tmp102_probe(struct i2c_client *client)
|
|||
* Mark that we are not ready with data until the first
|
||||
* conversion is complete
|
||||
*/
|
||||
tmp102->ready_time = jiffies + msecs_to_jiffies(CONVERSION_TIME_MS);
|
||||
tmp102->ready_time = get_jiffies_64() + msecs_to_jiffies(CONVERSION_TIME_MS);
|
||||
|
||||
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
|
||||
tmp102,
|
||||
|
|
@ -387,7 +387,7 @@ static int tmp102_resume(struct device *dev)
|
|||
err = regmap_update_bits(tmp102->regmap, TMP102_CONF_REG,
|
||||
TMP102_CONF_SD, 0);
|
||||
|
||||
tmp102->ready_time = jiffies + msecs_to_jiffies(CONVERSION_TIME_MS);
|
||||
tmp102->ready_time = get_jiffies_64() + msecs_to_jiffies(CONVERSION_TIME_MS);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user