* [PATCH 001/102] hwmon: (abituguru) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
@ 2026-11-02 22:50 ` Guenter Roeck
2026-11-02 22:50 ` [PATCH 002/102] hwmon: (abituguru3) " Guenter Roeck
` (100 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:50 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Hans de Goede
abituguru_update_device() uses 32-bit jiffies and time_after() to track
the 1-second sensor cache expiration. On 32-bit architectures, if the
sensor is not polled for more than MAX_JIFFY_OFFSET ticks (about 24.8
days at HZ=1000), time_after() wraps around and evaluates to false,
preventing sensor values from being updated for another 24.8 days.
Switch last_updated to u64 and use get_jiffies_64() and time_after64()
under update_lock to avoid 32-bit jiffies wraparound.
Fixes: f2b84bbcebfd ("[PATCH] abituguru: New hardware monitoring driver")
Cc: Hans de Goede <hansg@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/abituguru.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index 3bb959d16dbf..409c2baf1d8c 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -197,7 +197,7 @@ MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n"
struct abituguru_data {
struct device *hwmon_dev; /* hwmon registered device */
struct mutex update_lock; /* protect access to data and uGuru */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
unsigned short addr; /* uguru base address */
char uguru_ready; /* is the uguru in ready state? */
unsigned char update_timeouts; /*
@@ -1323,7 +1323,7 @@ static int abituguru_probe(struct platform_device *pdev)
ABIT_UGURU_MAX_RETRIES) != 5)
goto abituguru_probe_error;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
/* Detect sensor types and fill the sysfs attr for bank1 */
sysfs_attr_i = 0;
@@ -1449,7 +1449,7 @@ static struct abituguru_data *abituguru_update_device(struct device *dev)
char success = 1;
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ)) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ)) {
success = 0;
err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0,
data->alarms, 3, 0);
@@ -1492,7 +1492,7 @@ static struct abituguru_data *abituguru_update_device(struct device *dev)
}
/* On success set last_updated */
if (success)
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
}
mutex_unlock(&data->update_lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 002/102] hwmon: (abituguru3) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
2026-11-02 22:50 ` [PATCH 001/102] hwmon: (abituguru) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:50 ` Guenter Roeck
2026-11-02 22:50 ` [PATCH 003/102] hwmon: (acpi_power_meter) Use ktime for sensor sampling interval Guenter Roeck
` (99 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:50 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Alistair John Strachan
abituguru3_update_device() uses 32-bit jiffies and time_after() to track
the 1-second sensor cache expiration. On 32-bit architectures, if the
device is not polled for more than MAX_JIFFY_OFFSET ticks (about 24.8
days at HZ=1000), time_after() wraps around and evaluates to false,
causing stale cached sensor values to be returned.
Switch last_updated to u64 and use get_jiffies_64() and time_after64()
under update_lock to avoid 32-bit jiffies wraparound.
Fixes: 3faa1ffb4f4b ("hwmon: Add support for newer uGuru's")
Cc: Alistair John Strachan <alistair@devzero.co.uk>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/abituguru3.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index b70330dc2198..c38dc986f631 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -146,7 +146,7 @@ struct abituguru3_data {
struct mutex update_lock; /* protect access to data and uGuru */
unsigned short addr; /* uguru base address */
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/*
* For convenience the sysfs attr and their names are generated
@@ -1080,7 +1080,8 @@ static struct abituguru3_data *abituguru3_update_device(struct device *dev)
struct abituguru3_data *data = dev_get_drvdata(dev);
mutex_lock(&data->update_lock);
- if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
+ if (!data->valid ||
+ time_after64(get_jiffies_64(), data->last_updated + HZ)) {
/* Clear data->valid while updating */
data->valid = false;
/* Read alarms */
@@ -1115,7 +1116,7 @@ static struct abituguru3_data *abituguru3_update_device(struct device *dev)
data->settings[32 + i], 2) != 2)
goto LEAVE_UPDATE;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
LEAVE_UPDATE:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 003/102] hwmon: (acpi_power_meter) Use ktime for sensor sampling interval
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
2026-11-02 22:50 ` [PATCH 001/102] hwmon: (abituguru) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:50 ` [PATCH 002/102] hwmon: (abituguru3) " Guenter Roeck
@ 2026-11-02 22:50 ` Guenter Roeck
2026-11-02 22:50 ` [PATCH 004/102] hwmon: (ad7414) Use 64-bit jiffies for update deadline Guenter Roeck
` (98 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:50 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
update_meter() uses 32-bit jiffies, msecs_to_jiffies(), and time_before()
to cache power readings for caps.sampling_time milliseconds. On 32-bit
architectures, if the meter is not polled for about 24.8 days (at
HZ=1000), the 32-bit jiffies comparison wraps around and stops updating
power readings.
Because ACPI reports sampling_time natively in milliseconds, convert
sensors_last_updated to ktime_t and compare elapsed milliseconds using
ktime_ms_delta() and ktime_get(). This avoids 32-bit jiffies wraparound
as well as repeated millisecond-to-jiffies conversions.
Fixes: de584afa5e18 ("hwmon driver for ACPI 4.0 power meters")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/acpi_power_meter.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index 300acf1998ce..aae0a627f847 100644
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -9,7 +9,7 @@
#include <linux/module.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/limits.h>
#include <linux/mutex.h>
#include <linux/dmi.h>
@@ -95,7 +95,7 @@ struct acpi_power_meter_resource {
u64 avg_interval;
bool power_alarm;
int sensors_valid;
- unsigned long sensors_last_updated;
+ ktime_t sensors_last_updated;
#define POWER_METER_TRIP_AVERAGE_MIN_IDX 0
#define POWER_METER_TRIP_AVERAGE_MAX_IDX 1
s64 trip[2];
@@ -179,12 +179,11 @@ static int update_meter(struct acpi_power_meter_resource *resource)
{
unsigned long long data;
acpi_status status;
- unsigned long local_jiffies = jiffies;
- if (!acpi_power_meter_is_unknown(resource->caps.sampling_time) &&
- time_before(local_jiffies, resource->sensors_last_updated +
- msecs_to_jiffies(resource->caps.sampling_time)) &&
- resource->sensors_valid)
+ if (resource->sensors_valid &&
+ !acpi_power_meter_is_unknown(resource->caps.sampling_time) &&
+ ktime_ms_delta(ktime_get(), resource->sensors_last_updated) <
+ resource->caps.sampling_time)
return 0;
status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM",
@@ -197,7 +196,7 @@ static int update_meter(struct acpi_power_meter_resource *resource)
resource->power = data;
resource->sensors_valid = 1;
- resource->sensors_last_updated = jiffies;
+ resource->sensors_last_updated = ktime_get();
return 0;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 004/102] hwmon: (ad7414) Use 64-bit jiffies for update deadline
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (2 preceding siblings ...)
2026-11-02 22:50 ` [PATCH 003/102] hwmon: (acpi_power_meter) Use ktime for sensor sampling interval Guenter Roeck
@ 2026-11-02 22:50 ` Guenter Roeck
2026-11-02 22:50 ` [PATCH 005/102] hwmon: (ad7418) Use 64-bit jiffies for update timestamp Guenter Roeck
` (97 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:50 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
ad7414_update_device() uses an unsigned long next_update timestamp with
time_after(jiffies, ...). On 32-bit architectures, if the sensor is not
polled for more than MAX_JIFFY_OFFSET ticks (about 24.8 days at HZ=1000),
time_after() wraps around and evaluates to false, preventing sensor
values from being refreshed.
Convert next_update to u64 and use get_jiffies_64() and time_after64()
under data->lock to avoid 32-bit jiffies wraparound.
Fixes: 6c633c3025c7 ("hwmon: ad7414 driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ad7414.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c
index c2df631ae93a..fd3a49d5fe4a 100644
--- a/drivers/hwmon/ad7414.c
+++ b/drivers/hwmon/ad7414.c
@@ -38,7 +38,7 @@ struct ad7414_data {
struct i2c_client *client;
struct mutex lock; /* atomic read data updates */
bool valid; /* true if following fields are valid */
- unsigned long next_update; /* In jiffies */
+ u64 next_update; /* In jiffies */
s16 temp_input; /* Register values */
s8 temps[ARRAY_SIZE(AD7414_REG_LIMIT)];
};
@@ -73,7 +73,7 @@ static struct ad7414_data *ad7414_update_device(struct device *dev)
mutex_lock(&data->lock);
- if (time_after(jiffies, data->next_update) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->next_update) || !data->valid) {
int value, i;
dev_dbg(&client->dev, "starting ad7414 update\n");
@@ -94,7 +94,7 @@ static struct ad7414_data *ad7414_update_device(struct device *dev)
data->temps[i] = value;
}
- data->next_update = jiffies + HZ + HZ / 2;
+ data->next_update = get_jiffies_64() + HZ + HZ / 2;
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 005/102] hwmon: (ad7418) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (3 preceding siblings ...)
2026-11-02 22:50 ` [PATCH 004/102] hwmon: (ad7414) Use 64-bit jiffies for update deadline Guenter Roeck
@ 2026-11-02 22:50 ` Guenter Roeck
2026-11-02 22:50 ` [PATCH 006/102] hwmon: (adc128d818) " Guenter Roeck
` (96 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:50 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
ad7418_update_device() uses 32-bit jiffies and time_after() to determine
when cached sensor values have expired. On 32-bit architectures, if the
device is not polled for about 24.8 days at HZ=1000, the jiffies
comparison wraps around and sensor readings stop updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
under data->lock to prevent 32-bit jiffies wraparound.
Fixes: 2d8dd65fc142 ("hwmon: New AD7416, AD7417 and AD7418 driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ad7418.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c
index a0c9cf5e12cc..a31e08fb7fe4 100644
--- a/drivers/hwmon/ad7418.c
+++ b/drivers/hwmon/ad7418.c
@@ -47,7 +47,7 @@ struct ad7418_data {
struct mutex lock;
int adc_max; /* number of ADC channels */
bool valid;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
s16 temp[3]; /* Register values */
u16 in[4];
};
@@ -60,8 +60,8 @@ static int ad7418_update_device(struct device *dev)
mutex_lock(&data->lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
u8 cfg;
int i, ch;
@@ -110,7 +110,7 @@ static int ad7418_update_device(struct device *dev)
if (val < 0)
goto abort;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 006/102] hwmon: (adc128d818) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (4 preceding siblings ...)
2026-11-02 22:50 ` [PATCH 005/102] hwmon: (ad7418) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:50 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 007/102] hwmon: (adm1025) " Guenter Roeck
` (95 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:50 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
adc128_update_device() uses 32-bit jiffies and time_after() to determine
whether cached register values are older than 1 second. On 32-bit
architectures, if the sensor is not polled for about 24.8 days at
HZ=1000, the signed jiffies delta overflows and sensor readings stop
updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
under update_lock to prevent 32-bit jiffies wraparound.
Fixes: b4c9c1a7987e ("hwmon: Driver for TI ADC128D818")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adc128d818.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/adc128d818.c b/drivers/hwmon/adc128d818.c
index e45adc0b84d1..d6108e561515 100644
--- a/drivers/hwmon/adc128d818.c
+++ b/drivers/hwmon/adc128d818.c
@@ -62,7 +62,7 @@ struct adc128_data {
struct mutex update_lock;
u8 mode; /* Operation mode */
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u16 in[3][8]; /* Register value, normalized to 12 bit
* 0: input voltage
@@ -84,7 +84,8 @@ static struct adc128_data *adc128_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
for (i = 0; i < num_inputs[data->mode]; i++) {
rv = i2c_smbus_read_word_swapped(client,
ADC128_REG_IN(i));
@@ -130,7 +131,7 @@ static struct adc128_data *adc128_update_device(struct device *dev)
goto abort;
data->alarms |= rv;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
goto done;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 007/102] hwmon: (adm1025) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (5 preceding siblings ...)
2026-11-02 22:50 ` [PATCH 006/102] hwmon: (adc128d818) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 008/102] hwmon: (adm1026) Use 64-bit jiffies for update timestamps Guenter Roeck
` (94 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
adm1025_update_device() uses 32-bit jiffies and time_after() to guard its
2-second register cache. On 32-bit architectures, leaving the sensor
unpolled for more than about 24.8 days at HZ=1000 causes time_after() to
wrap around and return stale cached readings.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
under update_lock to avoid 32-bit jiffies wraparound.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adm1025.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
index ccac7ba601e9..1a947cc91d85 100644
--- a/drivers/hwmon/adm1025.c
+++ b/drivers/hwmon/adm1025.c
@@ -98,7 +98,7 @@ struct adm1025_data {
const struct attribute_group *groups[3];
struct mutex update_lock;
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
u8 in[6]; /* register value */
u8 in_max[6]; /* register value */
@@ -118,7 +118,8 @@ static struct adm1025_data *adm1025_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ * 2) ||
+ !data->valid) {
int i;
dev_dbg(&client->dev, "Updating data.\n");
@@ -147,7 +148,7 @@ static struct adm1025_data *adm1025_update_device(struct device *dev)
| ((i2c_smbus_read_byte_data(client,
ADM1025_REG_VID4) & 0x01) << 4);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 008/102] hwmon: (adm1026) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (6 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 007/102] hwmon: (adm1025) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 009/102] hwmon: (adm1029) Use 64-bit jiffies for update timestamp Guenter Roeck
` (93 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
adm1026_update_device() uses 32-bit jiffies and time_after() for both
last_reading and last_config cache intervals. On 32-bit architectures, if
the device is not polled for more than about 24.8 days at HZ=1000,
time_after() wraps around and cached sensor and configuration values stop
updating.
Convert last_reading and last_config to u64 and use get_jiffies_64() and
time_after64() under update_lock to avoid 32-bit jiffies wraparound.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adm1026.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index 3ad82c01f81d..7e10ace4b03a 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -268,8 +268,8 @@ struct adm1026_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_reading; /* In jiffies */
- unsigned long last_config; /* In jiffies */
+ u64 last_reading; /* In jiffies */
+ u64 last_config; /* In jiffies */
u8 in[17]; /* Register value */
u8 in_max[17]; /* Register value */
@@ -332,9 +332,9 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
long value, alarms, gpio;
mutex_lock(&data->update_lock);
- if (!data->valid
- || time_after(jiffies,
- data->last_reading + ADM1026_DATA_INTERVAL)) {
+ if (!data->valid ||
+ time_after64(get_jiffies_64(),
+ data->last_reading + ADM1026_DATA_INTERVAL)) {
/* Things that change quickly */
dev_dbg(&client->dev, "Reading sensor values\n");
for (i = 0; i <= 16; ++i) {
@@ -380,11 +380,12 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
ADM1026_REG_GPIO_STATUS_0_7);
data->gpio = gpio;
- data->last_reading = jiffies;
+ data->last_reading = get_jiffies_64();
} /* last_reading */
if (!data->valid ||
- time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) {
+ time_after64(get_jiffies_64(),
+ data->last_config + ADM1026_CONFIG_INTERVAL)) {
/* Things that don't change often */
dev_dbg(&client->dev, "Reading config values\n");
for (i = 0; i <= 16; ++i) {
@@ -464,7 +465,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
value >>= 2;
}
- data->last_config = jiffies;
+ data->last_config = get_jiffies_64();
} /* last_config */
data->valid = true;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 009/102] hwmon: (adm1029) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (7 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 008/102] hwmon: (adm1026) Use 64-bit jiffies for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 010/102] hwmon: (adm1031) Use ktime for sensor update interval Guenter Roeck
` (92 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Corentin Labbe
adm1029_update_device() uses 32-bit jiffies and time_after() to check
whether its 2-second register cache has expired. On 32-bit architectures,
leaving the device unpolled for about 24.8 days at HZ=1000 causes the
jiffies comparison to wrap around so sensor values stop updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
under update_lock to avoid 32-bit jiffies wraparound.
Fixes: cae2caae7825 ("hwmon: New driver for the Analog Devices ADM1029")
Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adm1029.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
index 6cb0a238e059..0af5d48dc01f 100644
--- a/drivers/hwmon/adm1029.c
+++ b/drivers/hwmon/adm1029.c
@@ -100,7 +100,7 @@ struct adm1029_data {
struct i2c_client *client;
struct mutex update_lock; /* protect register access */
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* registers values, signed for temperature, unsigned for other stuff */
s8 temp[ARRAY_SIZE(ADM1029_REG_TEMP)];
@@ -121,7 +121,8 @@ static struct adm1029_data *adm1029_update_device(struct device *dev)
* Use the "cache" Luke, don't recheck values
* if there are already checked not a long time later
*/
- if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ * 2) ||
+ !data->valid) {
int nr;
dev_dbg(&client->dev, "Updating adm1029 data\n");
@@ -142,7 +143,7 @@ static struct adm1029_data *adm1029_update_device(struct device *dev)
ADM1029_REG_FAN_DIV[nr]);
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 010/102] hwmon: (adm1031) Use ktime for sensor update interval
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (8 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 009/102] hwmon: (adm1029) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 011/102] hwmon: (adt7411) Use 64-bit jiffies for vref update deadline Guenter Roeck
` (91 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
adm1031_update_device() converts update_interval (125 ms to 16000 ms) to
jiffies and uses 32-bit time_after() to decide whether to refresh cached
registers. On 32-bit architectures, leaving the device unpolled for about
24.8 days at HZ=1000 causes time_after() to wrap around and stop updating
sensor values.
Since update_interval is stored in milliseconds down to 125 ms, convert
last_updated to ktime_t and use ktime_get(), ktime_add_ms(), and
ktime_after() under update_lock. This avoids both 32-bit jiffies
wraparound and coarse tick quantization at low HZ values.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adm1031.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 24d0d4146c87..cd98871426be 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -11,7 +11,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
@@ -66,7 +66,7 @@ struct adm1031_data {
struct mutex update_lock;
int chip_type;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ ktime_t last_updated;
unsigned int update_interval; /* In milliseconds */
/*
* The chan_select_table contains the possible configurations for
@@ -108,14 +108,14 @@ static struct adm1031_data *adm1031_update_device(struct device *dev)
{
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- unsigned long next_update;
int chan;
mutex_lock(&data->update_lock);
- next_update = data->last_updated
- + msecs_to_jiffies(data->update_interval);
- if (time_after(jiffies, next_update) || !data->valid) {
+ if (!data->valid ||
+ ktime_after(ktime_get(),
+ ktime_add_ms(data->last_updated,
+ data->update_interval))) {
dev_dbg(&client->dev, "Starting adm1031 update\n");
for (chan = 0;
@@ -186,7 +186,7 @@ static struct adm1031_data *adm1031_update_device(struct device *dev)
(adm1031_read_value(client,
ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
}
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 011/102] hwmon: (adt7411) Use 64-bit jiffies for vref update deadline
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (9 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 010/102] hwmon: (adm1031) Use ktime for sensor update interval Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 012/102] hwmon: (adt7462) Use 64-bit jiffies for update timestamps Guenter Roeck
` (90 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
adt7411_update_vref() uses 32-bit jiffies and time_after_eq() to check
whether the cached Vref measurement has expired. On 32-bit architectures,
if the sensor is not polled for about 24.8 days at HZ=1000, the jiffies
comparison wraps around and Vref stops updating.
Convert next_update to u64 and use get_jiffies_64() and time_after_eq64()
(already serialized by hwmon_lock) to avoid 32-bit jiffies wraparound.
Fixes: d84ca5b345c2 ("hwmon: Add driver for ADT7411 voltage and temperature sensor")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adt7411.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index 598f31647544..4c50f4167a10 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -98,7 +98,7 @@ static const u8 adt7411_in_alarm_bits[] = {
};
struct adt7411_data {
- unsigned long next_update;
+ u64 next_update;
long vref_cached;
struct i2c_client *client;
bool use_ext_temp;
@@ -172,7 +172,7 @@ static ssize_t adt7411_set_bit(struct device *dev,
scoped_guard(hwmon_lock, dev) {
ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag);
/* force update */
- data->next_update = jiffies;
+ data->next_update = get_jiffies_64();
}
return ret < 0 ? ret : count;
@@ -246,7 +246,7 @@ static int adt7411_update_vref(struct device *dev)
struct i2c_client *client = data->client;
int val;
- if (time_after_eq(jiffies, data->next_update)) {
+ if (time_after_eq64(get_jiffies_64(), data->next_update)) {
val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3);
if (val < 0)
return val;
@@ -260,7 +260,7 @@ static int adt7411_update_vref(struct device *dev)
data->vref_cached = 2250;
}
- data->next_update = jiffies + HZ;
+ data->next_update = get_jiffies_64() + HZ;
}
return 0;
@@ -660,7 +660,7 @@ static int adt7411_probe(struct i2c_client *client)
return ret;
/* force update on first occasion */
- data->next_update = jiffies;
+ data->next_update = get_jiffies_64();
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
data,
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 012/102] hwmon: (adt7462) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (10 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 011/102] hwmon: (adt7411) Use 64-bit jiffies for vref update deadline Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 013/102] hwmon: (adt7470) " Guenter Roeck
` (89 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
adt7462_update_device() uses 32-bit jiffies and time_before() to cache
sensor and limit registers. On 32-bit architectures, leaving the device
unpolled for more than about 24.8 days at HZ=1000 causes time_before() to
wrap around and return stale cached values.
Convert sensors_last_updated and limits_last_updated to u64 and use
get_jiffies_64() and time_before64() under data->lock to avoid 32-bit
jiffies wraparound.
Fixes: c0b4e3ab0c76 ("adt7462: new hwmon driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adt7462.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index 376331f7fa17..61deb156d304 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -193,8 +193,8 @@ struct adt7462_data {
struct mutex lock;
char sensors_valid;
char limits_valid;
- unsigned long sensors_last_updated; /* In jiffies */
- unsigned long limits_last_updated; /* In jiffies */
+ u64 sensors_last_updated; /* In jiffies */
+ u64 limits_last_updated; /* In jiffies */
u8 temp[ADT7462_TEMP_COUNT];
/* bits 6-7 are quarter pieces of temp */
@@ -673,13 +673,14 @@ static struct adt7462_data *adt7462_update_device(struct device *dev)
{
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- unsigned long local_jiffies = jiffies;
+ u64 local_jiffies;
int i;
mutex_lock(&data->lock);
- if (time_before(local_jiffies, data->sensors_last_updated +
- SENSOR_REFRESH_INTERVAL)
- && data->sensors_valid)
+ local_jiffies = get_jiffies_64();
+ if (time_before64(local_jiffies, data->sensors_last_updated +
+ SENSOR_REFRESH_INTERVAL) &&
+ data->sensors_valid)
goto no_sensor_update;
for (i = 0; i < ADT7462_TEMP_COUNT; i++) {
@@ -726,9 +727,9 @@ static struct adt7462_data *adt7462_update_device(struct device *dev)
data->sensors_valid = 1;
no_sensor_update:
- if (time_before(local_jiffies, data->limits_last_updated +
- LIMIT_REFRESH_INTERVAL)
- && data->limits_valid)
+ if (time_before64(local_jiffies, data->limits_last_updated +
+ LIMIT_REFRESH_INTERVAL) &&
+ data->limits_valid)
goto out;
for (i = 0; i < ADT7462_TEMP_COUNT; i++) {
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 013/102] hwmon: (adt7470) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (11 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 012/102] hwmon: (adt7462) Use 64-bit jiffies for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 014/102] hwmon: (adt7475) Use 64-bit jiffies for measurement timestamp Guenter Roeck
` (88 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
adt7470_update_device() uses 32-bit jiffies and time_before() to decide
whether cached sensor and limit values are still fresh. On 32-bit
architectures, if the device is not polled for about 24.8 days at
HZ=1000, time_before() wraps around and prevents further updates.
Convert sensors_last_updated and limits_last_updated to atomic64_t and
use get_jiffies_64() and time_before64() with smp_load_acquire() /
smp_store_release() on the validity flags. This avoids torn 64-bit
timestamp accesses on 32-bit systems while preserving the lockless
fast-path so sysfs reads do not block behind adt7470_update_thread()
while it sleeps in adt7470_read_temperatures().
Fixes: 6f9703d0be16 ("hwmon: add support for adt7470")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adt7470.c | 48 +++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 16 deletions(-)
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index f652532f2f32..1e216e6598d4 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -8,6 +8,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/atomic.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
@@ -165,8 +166,8 @@ struct adt7470_data {
struct mutex lock;
char sensors_valid;
char limits_valid;
- unsigned long sensors_last_updated; /* In jiffies */
- unsigned long limits_last_updated; /* In jiffies */
+ atomic64_t sensors_last_updated; /* In jiffies */
+ atomic64_t limits_last_updated; /* In jiffies */
bool use_pwm_framework;
int num_temp_sensors; /* -1 = probe */
@@ -463,44 +464,59 @@ static int adt7470_update_limits(struct adt7470_data *data)
static struct adt7470_data *adt7470_update_device(struct device *dev)
{
struct adt7470_data *data = dev_get_drvdata(dev);
- unsigned long local_jiffies = jiffies;
+ u64 local_jiffies = get_jiffies_64();
int need_sensors = 1;
int need_limits = 1;
- int err;
+ int err = 0;
/*
* Figure out if we need to update the shadow registers.
* Lockless means that we may occasionally report out of
* date data.
*/
- if (time_before(local_jiffies, data->sensors_last_updated +
- SENSOR_REFRESH_INTERVAL) &&
- data->sensors_valid)
+ /* Pairs with smp_store_release() on sensors_valid. */
+ if (smp_load_acquire(&data->sensors_valid) &&
+ time_before64(local_jiffies,
+ (u64)atomic64_read(&data->sensors_last_updated) +
+ SENSOR_REFRESH_INTERVAL))
need_sensors = 0;
- if (time_before(local_jiffies, data->limits_last_updated +
- LIMIT_REFRESH_INTERVAL) &&
- data->limits_valid)
+ /* Pairs with smp_store_release() on limits_valid. */
+ if (smp_load_acquire(&data->limits_valid) &&
+ time_before64(local_jiffies,
+ (u64)atomic64_read(&data->limits_last_updated) +
+ LIMIT_REFRESH_INTERVAL))
need_limits = 0;
if (!need_sensors && !need_limits)
return data;
mutex_lock(&data->lock);
- if (need_sensors) {
+ local_jiffies = get_jiffies_64();
+ if (need_sensors &&
+ (!data->sensors_valid ||
+ !time_before64(local_jiffies,
+ (u64)atomic64_read(&data->sensors_last_updated) +
+ SENSOR_REFRESH_INTERVAL))) {
err = adt7470_update_sensors(data);
if (err < 0)
goto out;
- data->sensors_last_updated = local_jiffies;
- data->sensors_valid = 1;
+ atomic64_set(&data->sensors_last_updated, local_jiffies);
+ /* Pairs with smp_load_acquire() in lockless fast-path. */
+ smp_store_release(&data->sensors_valid, 1);
}
- if (need_limits) {
+ if (need_limits &&
+ (!data->limits_valid ||
+ !time_before64(local_jiffies,
+ (u64)atomic64_read(&data->limits_last_updated) +
+ LIMIT_REFRESH_INTERVAL))) {
err = adt7470_update_limits(data);
if (err < 0)
goto out;
- data->limits_last_updated = local_jiffies;
- data->limits_valid = 1;
+ atomic64_set(&data->limits_last_updated, local_jiffies);
+ /* Pairs with smp_load_acquire() in lockless fast-path. */
+ smp_store_release(&data->limits_valid, 1);
}
out:
mutex_unlock(&data->lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 014/102] hwmon: (adt7475) Use 64-bit jiffies for measurement timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (12 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 013/102] hwmon: (adt7470) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 015/102] hwmon: (aquacomputer_d5next) Use ktime for status update timestamp Guenter Roeck
` (87 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
adt7475_update_device() uses 32-bit jiffies and time_after() to check
whether its 2-second measurement cache has expired. On 32-bit
architectures, leaving the chip unpolled for about 24.8 days at HZ=1000
causes time_after() to wrap around and stop updating measurements.
Convert measure_updated to u64 and use get_jiffies_64() and
time_after64() under data->lock to prevent 32-bit jiffies wraparound.
Fixes: 1c301fc5394f ("hwmon: Add a driver for the ADT7475 hardware monitoring chip")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/adt7475.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index cd0b69ecb640..d505328a7670 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -199,7 +199,7 @@ struct adt7475_data {
struct i2c_client *client;
struct mutex lock;
- unsigned long measure_updated;
+ u64 measure_updated;
bool valid;
u8 config2;
@@ -2193,7 +2193,7 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
mutex_lock(&data->lock);
/* Measurement values update every 2 seconds */
- if (time_after(jiffies, data->measure_updated + HZ * 2) ||
+ if (time_after64(get_jiffies_64(), data->measure_updated + HZ * 2) ||
!data->valid) {
ret = adt7475_update_measure(dev);
if (ret) {
@@ -2201,7 +2201,7 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
mutex_unlock(&data->lock);
return ERR_PTR(ret);
}
- data->measure_updated = jiffies;
+ data->measure_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 015/102] hwmon: (aquacomputer_d5next) Use ktime for status update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (13 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 014/102] hwmon: (adt7475) Use 64-bit jiffies for measurement timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 016/102] hwmon: (asb100) Use 64-bit jiffies for " Guenter Roeck
` (86 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Aleksa Savic, Jack Doan
aquacomputer_d5next uses 32-bit jiffies and time_after() to check whether
the latest status report is older than 2 seconds. On 32-bit
architectures, if status reports stop arriving or a legacy device is not
polled for about 24.8 days at HZ=1000, time_after() wraps around and
stale readings are treated as fresh.
The driver already uses ktime_t for control report timing. Convert
priv->updated to ktime_t with a 2000 ms interval using ktime_get(),
ktime_add_ms(), and ktime_after(), and guard 64-bit updated accesses
between aqc_raw_event() and aqc_read() with a spinlock to prevent torn
reads/writes on 32-bit architectures.
Fixes: 0e35f63f7f4e ("hwmon: add driver for Aquacomputer D5 Next")
Cc: Aleksa Savic <savicaleksa83@gmail.com>
Cc: Jack Doan <me@jackdoan.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/aquacomputer_d5next.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
index cd6cc304614f..9599281bb6e7 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -17,11 +17,11 @@
#include <linux/delay.h>
#include <linux/hid.h>
#include <linux/hwmon.h>
-#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/seq_file.h>
+#include <linux/spinlock.h>
#include <linux/unaligned.h>
#define USB_VENDOR_ID_AQUACOMPUTER 0x0c70
@@ -64,7 +64,7 @@ static const char *const aqc_device_names[] = {
#define DRIVER_NAME "aquacomputer_d5next"
#define STATUS_REPORT_ID 0x01
-#define STATUS_UPDATE_INTERVAL (2 * HZ) /* In seconds */
+#define STATUS_UPDATE_INTERVAL 2000 /* In milliseconds */
#define SERIAL_PART_OFFSET 2
#define CTRL_REPORT_ID 0x03
@@ -655,7 +655,8 @@ struct aqc_data {
const char *const *voltage_label;
const char *const *current_label;
- unsigned long updated;
+ spinlock_t status_lock; /* Protect 'updated' flag */
+ ktime_t updated;
};
/* Converts from centi-percent */
@@ -1054,7 +1055,9 @@ static int aqc_legacy_read(struct aqc_data *priv)
break;
}
- priv->updated = jiffies;
+ spin_lock_irq(&priv->status_lock);
+ priv->updated = ktime_get();
+ spin_unlock_irq(&priv->status_lock);
return 0;
}
@@ -1064,8 +1067,14 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
long power;
int ret;
struct aqc_data *priv = dev_get_drvdata(dev);
+ ktime_t updated;
- if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL)) {
+ spin_lock_irq(&priv->status_lock);
+ updated = priv->updated;
+ spin_unlock_irq(&priv->status_lock);
+
+ if (ktime_after(ktime_get(),
+ ktime_add_ms(updated, STATUS_UPDATE_INTERVAL))) {
if (priv->status_report_id != 0) {
/* Legacy devices require manual reads */
ret = aqc_legacy_read(priv);
@@ -1386,6 +1395,7 @@ static const struct hwmon_chip_info aqc_chip_info = {
static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
{
int i, j, sensor_value;
+ unsigned long flags;
struct aqc_data *priv;
if (report->id != STATUS_REPORT_ID || report->type != HID_INPUT_REPORT ||
@@ -1537,7 +1547,9 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
break;
}
- priv->updated = jiffies;
+ spin_lock_irqsave(&priv->status_lock, flags);
+ priv->updated = ktime_get();
+ spin_unlock_irqrestore(&priv->status_lock, flags);
return 0;
}
@@ -1605,7 +1617,8 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->hdev = hdev;
hid_set_drvdata(hdev, priv);
- priv->updated = jiffies - STATUS_UPDATE_INTERVAL - 1;
+ spin_lock_init(&priv->status_lock);
+ priv->updated = ktime_sub_ms(ktime_get(), STATUS_UPDATE_INTERVAL + 1);
ret = hid_parse(hdev);
if (ret)
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 016/102] hwmon: (asb100) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (14 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 015/102] hwmon: (aquacomputer_d5next) Use ktime for status update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 017/102] hwmon: (asc7621) Use 64-bit jiffies for update timestamps Guenter Roeck
` (85 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
asb100_update_device() uses 32-bit jiffies and time_after() to track its
1.5-second sensor cache. On 32-bit architectures, leaving the device
unpolled for about 24.8 days at HZ=1000 causes time_after() to wrap
around and stop refreshing sensor registers.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
under update_lock to prevent 32-bit jiffies wraparound.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/asb100.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index 5f5c94505166..ec4c7e6e68fc 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -181,7 +181,7 @@ struct asb100_data {
struct mutex lock;
struct mutex update_lock;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/* array of 2 pointers to subclients */
struct i2c_client *lm75[2];
@@ -940,8 +940,8 @@ static struct asb100_data *asb100_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
dev_dbg(&client->dev, "starting device update...\n");
@@ -990,7 +990,7 @@ static struct asb100_data *asb100_update_device(struct device *dev)
data->alarms = asb100_read_value(client, ASB100_REG_ALARM1) +
(asb100_read_value(client, ASB100_REG_ALARM2) << 8);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
dev_dbg(&client->dev, "... device update complete\n");
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 017/102] hwmon: (asc7621) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (15 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 016/102] hwmon: (asb100) Use 64-bit jiffies for " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 018/102] hwmon: (asus_atk0110) Use 64-bit jiffies for sensor cache timestamp Guenter Roeck
` (84 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, George Joseph
asc7621_update_device() uses 32-bit jiffies and time_after() for both
high-priority and low-priority register caches. On 32-bit architectures,
leaving the chip unpolled for about 24.8 days at HZ=1000 causes
time_after() to wrap around and return stale cached registers.
Convert last_high_reading and last_low_reading to u64 and use
get_jiffies_64() and time_after64() under update_lock to avoid 32-bit
jiffies wraparound.
Fixes: d58de0387282 ("hwmon: Driver for Andigilog aSC7621 family monitoring chips")
Cc: George Joseph <george.joseph@fairview5.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/asc7621.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
index e8145bb13ab3..ad32918f4c6c 100644
--- a/drivers/hwmon/asc7621.c
+++ b/drivers/hwmon/asc7621.c
@@ -78,8 +78,8 @@ struct asc7621_data {
struct device *class_dev;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_high_reading; /* In jiffies */
- unsigned long last_low_reading; /* In jiffies */
+ u64 last_high_reading; /* In jiffies */
+ u64 last_low_reading; /* In jiffies */
/*
* Registers we care about occupy the corresponding index
* in the array. Registers we don't care about are left
@@ -1007,7 +1007,8 @@ static struct asc7621_data *asc7621_update_device(struct device *dev)
/* Read all the high priority registers */
if (!data->valid ||
- time_after(jiffies, data->last_high_reading + INTERVAL_HIGH)) {
+ time_after64(get_jiffies_64(),
+ data->last_high_reading + INTERVAL_HIGH)) {
for (i = 0; i < ARRAY_SIZE(asc7621_register_priorities); i++) {
if (asc7621_register_priorities[i] == PRI_HIGH) {
@@ -1015,13 +1016,14 @@ static struct asc7621_data *asc7621_update_device(struct device *dev)
i2c_smbus_read_byte_data(client, i) & 0xff;
}
}
- data->last_high_reading = jiffies;
+ data->last_high_reading = get_jiffies_64();
} /* last_reading */
/* Read all the low priority registers. */
if (!data->valid ||
- time_after(jiffies, data->last_low_reading + INTERVAL_LOW)) {
+ time_after64(get_jiffies_64(),
+ data->last_low_reading + INTERVAL_LOW)) {
for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
if (asc7621_register_priorities[i] == PRI_LOW) {
@@ -1029,7 +1031,7 @@ static struct asc7621_data *asc7621_update_device(struct device *dev)
i2c_smbus_read_byte_data(client, i) & 0xff;
}
}
- data->last_low_reading = jiffies;
+ data->last_low_reading = get_jiffies_64();
} /* last_reading */
data->valid = true;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 018/102] hwmon: (asus_atk0110) Use 64-bit jiffies for sensor cache timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (16 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 017/102] hwmon: (asc7621) Use 64-bit jiffies for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 019/102] hwmon: (asus_rog_ryujin) Use ktime for status validity timestamp Guenter Roeck
` (83 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Luca Tettamanti
atk_read_value() uses 32-bit jiffies and time_after() to cache sensor
readings for CACHE_TIME (1 second). On 32-bit architectures, if a sensor
is not polled for about 24.8 days at HZ=1000, time_after() wraps around
and prevents new ACPI readings from being taken.
Convert last_updated to u64, use get_jiffies_64() and time_after64(), and
serialize sensor reads in atk_input_show() with hwmon_lock so 64-bit
timestamp and cached_value accesses cannot race or tear on 32-bit
systems.
Fixes: 2c03d07ad54d ("hwmon: Add Asus ATK0110 support")
Cc: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/asus_atk0110.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index 868c4e14d26a..3cc8e8d287e4 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -164,7 +164,7 @@ struct atk_sensor_data {
u64 limit1;
u64 limit2;
u64 cached_value;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
bool is_valid;
char const *acpi_name;
};
@@ -221,7 +221,8 @@ static ssize_t atk_input_show(struct device *dev,
u64 value;
int err;
- err = atk_read_value(s, &value);
+ scoped_guard(hwmon_lock, dev)
+ err = atk_read_value(s, &value);
if (err)
return err;
@@ -634,7 +635,7 @@ static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
int err;
if (!sensor->is_valid ||
- time_after(jiffies, sensor->last_updated + CACHE_TIME)) {
+ time_after64(get_jiffies_64(), sensor->last_updated + CACHE_TIME)) {
if (sensor->data->old_interface)
err = atk_read_value_old(sensor, value);
else
@@ -644,7 +645,7 @@ static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
return err;
sensor->is_valid = true;
- sensor->last_updated = jiffies;
+ sensor->last_updated = get_jiffies_64();
sensor->cached_value = *value;
} else {
*value = sensor->cached_value;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 019/102] hwmon: (asus_rog_ryujin) Use ktime for status validity timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (17 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 018/102] hwmon: (asus_atk0110) Use 64-bit jiffies for sensor cache timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 020/102] hwmon: (asus_wmi_sensors) Use 64-bit jiffies for source cache timestamps Guenter Roeck
` (82 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Aleksa Savic
rog_ryujin_get_status() converts STATUS_VALIDITY (1500 ms) to jiffies and
uses 32-bit time_after() to check whether cached cooler data is stale. On
32-bit architectures, leaving the sensor unpolled for about 24.8 days at
HZ=1000 causes time_after() to wrap around and return stale cached data.
Since STATUS_VALIDITY is defined in milliseconds, convert priv->updated
to ktime_t and use ktime_get(), ktime_add_ms(), and ktime_after() to
avoid 32-bit jiffies wraparound and repeated jiffies conversions.
Fixes: ed3e03790c5c ("hwmon: Add driver for ASUS ROG RYUJIN II 360 AIO cooler")
Cc: Aleksa Savic <savicaleksa83@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/asus_rog_ryujin.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
index 4cb18903e98a..34b1150520ca 100644
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -10,6 +10,7 @@
#include <linux/hid.h>
#include <linux/hwmon.h>
#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/unaligned.h>
@@ -136,7 +137,7 @@ struct rog_ryujin_data {
unsigned long source_changed; /* jiffies */
u8 *buffer;
- unsigned long updated; /* jiffies */
+ ktime_t updated;
};
static int rog_ryujin_percent_to_pwm(u16 val)
@@ -237,7 +238,8 @@ static int rog_ryujin_get_status(struct rog_ryujin_data *priv)
{
int ret;
- if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) {
+ if (!ktime_after(ktime_get(),
+ ktime_add_ms(priv->updated, STATUS_VALIDITY))) {
/* Data is up to date */
return 0;
}
@@ -274,7 +276,7 @@ static int rog_ryujin_get_status(struct rog_ryujin_data *priv)
return ret;
}
- priv->updated = jiffies;
+ priv->updated = ktime_get();
return 0;
}
@@ -700,7 +702,7 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
* the initial empty data invalid for rog_ryujin_read() without the need for
* a special case there.
*/
- priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY);
+ priv->updated = ktime_sub_ms(ktime_get(), STATUS_VALIDITY + 1);
priv->source_changed = jiffies - msecs_to_jiffies(RYUJIN_SOURCE_CHANGE_INTERVAL);
ret = hid_parse(hdev);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 020/102] hwmon: (asus_wmi_sensors) Use 64-bit jiffies for source cache timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (18 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 019/102] hwmon: (asus_rog_ryujin) Use ktime for status validity timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 021/102] hwmon: (atxp1) Use 64-bit jiffies and record update timestamp Guenter Roeck
` (81 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Ed Brindley, Denis Pauk
asus_wmi_get_cached_value_or_update() uses 32-bit jiffies and
time_after() to cache sensor source readings for 1 second. On 32-bit
architectures, if a sensor source is not polled for about 24.8 days at
HZ=1000 (or during the first 5 minutes after boot before INITIAL_JIFFIES
wraps past zero), time_after() evaluates to false and sensor values are
not updated.
Convert source_last_updated[] to u64 and use get_jiffies_64() and
time_after64() under sensor_data->lock to prevent 32-bit jiffies
wraparound.
Fixes: 548820e21ce1 ("hwmon: (asus_wmi_sensors) Support X370 Asus WMI.")
Cc: Ed Brindley <kernel@maidavale.org>
Cc: Denis Pauk <pauk.denis@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/asus_wmi_sensors.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/asus_wmi_sensors.c b/drivers/hwmon/asus_wmi_sensors.c
index 0feab3f62496..e2313a1286b5 100644
--- a/drivers/hwmon/asus_wmi_sensors.c
+++ b/drivers/hwmon/asus_wmi_sensors.c
@@ -155,7 +155,7 @@ struct asus_wmi_sensor_info {
};
struct asus_wmi_wmi_info {
- unsigned long source_last_updated[3]; /* in jiffies */
+ u64 source_last_updated[3]; /* in jiffies */
int sensor_count;
const struct asus_wmi_sensor_info **info[hwmon_max];
@@ -423,7 +423,8 @@ static int asus_wmi_get_cached_value_or_update(const struct asus_wmi_sensor_info
mutex_lock(&sensor_data->lock);
- if (time_after(jiffies, sensor_data->wmi.source_last_updated[sensor->source] + HZ)) {
+ if (time_after64(get_jiffies_64(),
+ sensor_data->wmi.source_last_updated[sensor->source] + HZ)) {
ret = asus_wmi_update_buffer(sensor->source);
if (ret)
goto unlock;
@@ -432,7 +433,7 @@ static int asus_wmi_get_cached_value_or_update(const struct asus_wmi_sensor_info
if (ret)
goto unlock;
- sensor_data->wmi.source_last_updated[sensor->source] = jiffies;
+ sensor_data->wmi.source_last_updated[sensor->source] = get_jiffies_64();
}
*value = sensor->cached_value;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 021/102] hwmon: (atxp1) Use 64-bit jiffies and record update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (19 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 020/102] hwmon: (asus_wmi_sensors) Use 64-bit jiffies for source cache timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 022/102] hwmon: (dme1737) Use 64-bit jiffies for update timestamps Guenter Roeck
` (80 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
atxp1_update_device() compares jiffies against data->last_updated + HZ
using 32-bit time_after(), which wraps on 32-bit architectures if the
device is not polled for more than ~24.8 days (at HZ=1000). In addition,
data->last_updated was never updated when reading registers from the
chip, rendering the 1-second cache expiration check ineffective once
jiffies moved past HZ.
Convert last_updated to u64, update it with get_jiffies_64() when the
register cache is refreshed, and use time_after64() for the comparison.
Fixes: 9cb7d18433ea ("[PATCH] I2C: add new atxp1 driver")
Fixes: 0cacdf298211 ("[PATCH] I2C: use time_after in 3 chip drivers")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/atxp1.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
index f5de4894f0a2..8559c301e1d1 100644
--- a/drivers/hwmon/atxp1.c
+++ b/drivers/hwmon/atxp1.c
@@ -37,7 +37,7 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
struct atxp1_data {
struct i2c_client *client;
struct mutex update_lock;
- unsigned long last_updated;
+ u64 last_updated;
bool valid;
struct {
u8 vid; /* VID output register */
@@ -55,7 +55,8 @@ static struct atxp1_data *atxp1_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
/* Update local register data */
data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID);
@@ -64,6 +65,7 @@ static struct atxp1_data *atxp1_update_device(struct device *dev)
data->reg.gpio1 = i2c_smbus_read_byte_data(client, ATXP1_GPIO1);
data->reg.gpio2 = i2c_smbus_read_byte_data(client, ATXP1_GPIO2);
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 022/102] hwmon: (dme1737) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (20 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 021/102] hwmon: (atxp1) Use 64-bit jiffies and record update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 023/102] hwmon: (ds1621) Use ktime for update timestamp Guenter Roeck
` (79 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Juerg Haefliger
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
Vbat monitoring and cached register values from updating.
Convert last_update and last_vbat to u64 and use get_jiffies_64() and
time_after64() to avoid wraparound issues on 32-bit systems.
Fixes: 9431996f55f8 ("hwmon: New SMSC DME1737 driver")
Cc: Juerg Haefliger <juergh@proton.me>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/dme1737.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 7e839308e58f..b1bd3682c5fb 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -204,8 +204,8 @@ struct dme1737_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_update; /* in jiffies */
- unsigned long last_vbat; /* in jiffies */
+ u64 last_update; /* in jiffies */
+ u64 last_vbat; /* in jiffies */
enum chips type;
const int *in_nominal; /* pointer to IN_NOMINAL array */
@@ -600,14 +600,16 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
mutex_lock(&data->update_lock);
/* Enable a Vbat monitoring cycle every 10 mins */
- if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_vbat + 600 * HZ) ||
+ !data->valid) {
dme1737_write(data, DME1737_REG_CONFIG, dme1737_read(data,
DME1737_REG_CONFIG) | 0x10);
- data->last_vbat = jiffies;
+ data->last_vbat = get_jiffies_64();
}
/* Sample register contents every 1 sec */
- if (time_after(jiffies, data->last_update + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_update + HZ) ||
+ !data->valid) {
if (data->has_features & HAS_VID) {
data->vid = dme1737_read(data, DME1737_REG_VID) &
0x3f;
@@ -777,7 +779,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
dme1737_write(data, DME1737_REG_ALARM1, 0xff);
}
- data->last_update = jiffies;
+ data->last_update = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 023/102] hwmon: (ds1621) Use ktime for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (21 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 022/102] hwmon: (dme1737) Use 64-bit jiffies for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 024/102] hwmon: (ds620) Use 64-bit jiffies " Guenter Roeck
` (78 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
ds1621_update_client() checks cache expiration with
time_after(jiffies, data->last_updated + data->update_interval). On
32-bit architectures, 32-bit jiffies comparisons can overflow after
~24.8 days at HZ=1000 if the sensor is not polled, preventing further
updates. Furthermore, data->update_interval is stored in milliseconds
rather than jiffies, causing mismatched units whenever HZ != 1000.
Convert last_updated to ktime_t and use ktime_get(), ktime_add_ms(), and
ktime_after() so millisecond conversion intervals are handled directly
without 32-bit jiffies wraparound or HZ scaling issues.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Fixes: cd6c8a4297ad ("hwmon: (ds1621) Add ds1721 chip support")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ds1621.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 0618f6de9679..fd4550b0ddd0 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -24,7 +24,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
@@ -110,7 +110,7 @@ struct ds1621_data {
struct i2c_client *client;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ ktime_t last_updated;
enum chips kind; /* device type */
u16 temp[3]; /* Register values, word */
@@ -190,7 +190,9 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + data->update_interval) ||
+ if (ktime_after(ktime_get(),
+ ktime_add_ms(data->last_updated,
+ data->update_interval)) ||
!data->valid) {
int i;
@@ -212,7 +214,7 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
i2c_smbus_write_byte_data(client, DS1621_REG_CONF,
new_conf);
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 024/102] hwmon: (ds620) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (22 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 023/102] hwmon: (ds1621) Use ktime for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 025/102] hwmon: (emc2103) " Guenter Roeck
` (77 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the sensor is not polled for longer
than half the wrap period, time_after() can return false and prevent
cached temperature values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 6099469805c2 ("hwmon: Support for Dallas Semiconductor DS620")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ds620.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c
index 25287f0fa4c2..bb8534c5e2d2 100644
--- a/drivers/hwmon/ds620.c
+++ b/drivers/hwmon/ds620.c
@@ -57,7 +57,7 @@ struct ds620_data {
struct i2c_client *client;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
s16 temp[3]; /* Register values, word */
};
@@ -99,7 +99,7 @@ static struct ds620_data *ds620_update_client(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
int i;
int res;
@@ -117,7 +117,7 @@ static struct ds620_data *ds620_update_client(struct device *dev)
data->temp[i] = res;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
abort:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 025/102] hwmon: (emc2103) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (23 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 024/102] hwmon: (ds620) Use 64-bit jiffies " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 026/102] hwmon: (emc6w201) " Guenter Roeck
` (76 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Steve Glendinning
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the sensor is not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 9df7305b5a86 ("hwmon: Add driver for SMSC EMC2103 temperature monitor and fan controller")
Cc: Steve Glendinning <steve.glendinning@shawell.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/emc2103.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c
index 4adc23ffaf72..47e12897f56f 100644
--- a/drivers/hwmon/emc2103.c
+++ b/drivers/hwmon/emc2103.c
@@ -59,7 +59,7 @@ struct emc2103_data {
bool valid; /* registers are valid */
bool fan_rpm_control;
int temp_count; /* num of temp sensors */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
struct temperature temp[4]; /* internal + 3 external */
s8 temp_min[4]; /* no fractional part */
s8 temp_max[4]; /* no fractional part */
@@ -139,7 +139,7 @@ static struct emc2103_data *emc2103_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
int i;
@@ -162,7 +162,7 @@ static struct emc2103_data *emc2103_update_device(struct device *dev)
REG_FAN_TARGET_HI, REG_FAN_TARGET_LO);
read_fan_config_from_i2c(client);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 026/102] hwmon: (emc6w201) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (24 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 025/102] hwmon: (emc2103) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 027/102] hwmon: (f71805f) Use 64-bit jiffies for update timestamps Guenter Roeck
` (75 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the sensor is not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: b0b349a85d3d ("hwmon: New driver for the SMSC EMC6W201")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/emc6w201.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
index c13ea8748683..b17688a9b55a 100644
--- a/drivers/hwmon/emc6w201.c
+++ b/drivers/hwmon/emc6w201.c
@@ -46,7 +46,7 @@ struct emc6w201_data {
struct i2c_client *client;
struct mutex update_lock;
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* registers values */
u8 in[3][6];
@@ -127,7 +127,8 @@ static struct emc6w201_data *emc6w201_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
for (nr = 0; nr < 6; nr++) {
data->in[input][nr] =
emc6w201_read8(client,
@@ -161,7 +162,7 @@ static struct emc6w201_data *emc6w201_update_device(struct device *dev)
EMC6W201_REG_FAN_MIN(nr));
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 027/102] hwmon: (f71805f) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (25 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 026/102] hwmon: (emc6w201) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 028/102] hwmon: (f71882fg) " Guenter Roeck
` (74 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached values from updating. In addition, the 60-second limit cache
check compared against data->last_updated instead of data->last_limits,
preventing limit registers from refreshing whenever measurement
registers were polled more frequently than once per minute.
Convert last_updated and last_limits to u64, check data->last_limits for
the 60-second limit cache expiration, and use get_jiffies_64() and
time_after64() to avoid wraparound issues on 32-bit systems.
Fixes: e53004e20a58 ("[PATCH] hwmon: New f71805f driver")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/f71805f.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 820f894d9ffd..fca779b157a0 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -166,8 +166,8 @@ struct f71805f_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
- unsigned long last_limits; /* In jiffies */
+ u64 last_updated; /* In jiffies */
+ u64 last_limits; /* In jiffies */
/* Register values */
u8 in[11];
@@ -337,7 +337,7 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
mutex_lock(&data->update_lock);
/* Limit registers cache is refreshed after 60 seconds */
- if (time_after(jiffies, data->last_updated + 60 * HZ)
+ if (time_after64(get_jiffies_64(), data->last_limits + 60 * HZ)
|| !data->valid) {
for (nr = 0; nr < 11; nr++) {
if (!(data->has_in & (1 << nr)))
@@ -375,11 +375,11 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
}
}
- data->last_limits = jiffies;
+ data->last_limits = get_jiffies_64();
}
/* Measurement registers cache is refreshed after 1 second */
- if (time_after(jiffies, data->last_updated + HZ)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ)
|| !data->valid) {
for (nr = 0; nr < 11; nr++) {
if (!(data->has_in & (1 << nr)))
@@ -403,7 +403,7 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
+ (f71805f_read8(data, F71805F_REG_STATUS(1)) << 8)
+ (f71805f_read8(data, F71805F_REG_STATUS(2)) << 16);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 028/102] hwmon: (f71882fg) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (26 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 027/102] hwmon: (f71805f) Use 64-bit jiffies for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 029/102] hwmon: (f75375s) " Guenter Roeck
` (73 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached measurement and limit values from updating.
Convert last_updated and last_limits to u64 and use get_jiffies_64() and
time_after64() to avoid wraparound issues on 32-bit systems.
Fixes: 45fb366940d5 ("hwmon: add support for Fintek F71882FG and F71883FG")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/f71882fg.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 204059d2de6c..08ca0bda0006 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -251,8 +251,8 @@ struct f71882fg_data {
int temp_start; /* temp numbering start (0 or 1) */
bool valid; /* true if following fields are valid */
char auto_point_temp_signed;
- unsigned long last_updated; /* In jiffies */
- unsigned long last_limits; /* In jiffies */
+ u64 last_updated; /* In jiffies */
+ u64 last_limits; /* In jiffies */
/* Register Values */
u8 in[F71882FG_MAX_INS];
@@ -346,8 +346,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
mutex_lock(&data->update_lock);
/* Update once every 60 seconds */
- if (time_after(jiffies, data->last_limits + 60 * HZ) ||
- !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_limits + 60 * HZ) ||
+ !data->valid) {
if (f71882fg_has_in1_alarm[data->type]) {
if (data->type == f81866a) {
data->in1_max =
@@ -450,11 +450,12 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
break;
}
}
- data->last_limits = jiffies;
+ data->last_limits = get_jiffies_64();
}
/* Update every second */
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
data->temp_status = f71882fg_read8(data,
F71882FG_REG_TEMP_STATUS);
data->temp_diode_open = f71882fg_read8(data,
@@ -502,7 +503,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
data->in[nr] = f71882fg_read8(data,
F71882FG_REG_IN(nr));
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 029/102] hwmon: (f75375s) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (27 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 028/102] hwmon: (f71882fg) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 030/102] hwmon: (fschmd) Use 64-bit jiffies for update timestamp Guenter Roeck
` (72 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Riku Voipio
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached measurement and limit values from updating.
Convert last_updated and last_limits to u64 and use get_jiffies_64() and
time_after64() to avoid wraparound issues on 32-bit systems.
Fixes: 84f1e442968a ("hwmon: Add f75375s driver")
Cc: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/f75375s.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index cc3a9612f2c0..ec51051ba09d 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -86,8 +86,8 @@ struct f75375_data {
int kind;
struct mutex update_lock; /* protect register access */
bool valid;
- unsigned long last_updated; /* In jiffies */
- unsigned long last_limits; /* In jiffies */
+ u64 last_updated; /* In jiffies */
+ u64 last_limits; /* In jiffies */
/* Register values */
u8 in[4];
@@ -157,7 +157,7 @@ static struct f75375_data *f75375_update_device(struct device *dev)
mutex_lock(&data->update_lock);
/* Limit registers cache is refreshed after 60 seconds */
- if (time_after(jiffies, data->last_limits + 60 * HZ)
+ if (time_after64(get_jiffies_64(), data->last_limits + 60 * HZ)
|| !data->valid) {
for (nr = 0; nr < 2; nr++) {
data->temp_high[nr] =
@@ -178,11 +178,11 @@ static struct f75375_data *f75375_update_device(struct device *dev)
f75375_read8(client, F75375_REG_VOLT_LOW(nr));
}
data->fan_timer = f75375_read8(client, F75375_REG_FAN_TIMER);
- data->last_limits = jiffies;
+ data->last_limits = get_jiffies_64();
}
/* Measurement registers cache is refreshed after 2 second */
- if (time_after(jiffies, data->last_updated + 2 * HZ)
+ if (time_after64(get_jiffies_64(), data->last_updated + 2 * HZ)
|| !data->valid) {
for (nr = 0; nr < 2; nr++) {
data->pwm[nr] = f75375_read8(client,
@@ -202,7 +202,7 @@ static struct f75375_data *f75375_update_device(struct device *dev)
data->in[nr] =
f75375_read8(client, F75375_REG_VOLT(nr));
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 030/102] hwmon: (fschmd) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (28 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 029/102] hwmon: (f75375s) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 031/102] hwmon: (ftsteutates) " Guenter Roeck
` (71 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 569ff1022662 ("hwmon: Add new combined driver for FSC chips")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/fschmd.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index df9418a86c83..2f5c3e3b644d 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -266,7 +266,7 @@ struct fschmd_data {
char watchdog_expect_close;
char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* register values */
u8 revision; /* chip revision */
@@ -1301,7 +1301,8 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + 2 * HZ) ||
+ !data->valid) {
for (i = 0; i < FSCHMD_NO_TEMP_SENSORS[data->kind]; i++) {
data->temp_act[i] = i2c_smbus_read_byte_data(client,
@@ -1353,7 +1354,7 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
data->volt[i] = i2c_smbus_read_byte_data(client,
FSCHMD_REG_VOLT[data->kind][i]);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 031/102] hwmon: (ftsteutates) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (29 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 030/102] hwmon: (fschmd) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 032/102] hwmon: (g760a) " Guenter Roeck
` (70 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 08426eda58e0 ("hwmon: Add driver for FTS BMC chip "Teutates"")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ftsteutates.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c
index 10d786960ed6..e9cd7c672733 100644
--- a/drivers/hwmon/ftsteutates.c
+++ b/drivers/hwmon/ftsteutates.c
@@ -62,7 +62,7 @@ enum WATCHDOG_RESOLUTION {
struct fts_data {
struct i2c_client *client;
struct device *hwmon_dev;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
struct watchdog_device wdd;
enum WATCHDOG_RESOLUTION resolution;
bool valid; /* false until following fields are valid */
@@ -131,7 +131,8 @@ static int fts_update_device(struct fts_data *data)
{
int i, err;
- if (!time_after(jiffies, data->last_updated + 2 * HZ) && data->valid)
+ if (!time_after64(get_jiffies_64(), data->last_updated + 2 * HZ) &&
+ data->valid)
return 0;
err = fts_read_byte(data->client, FTS_DEVICE_STATUS_REG);
@@ -188,7 +189,7 @@ static int fts_update_device(struct fts_data *data)
return err;
data->volt[i] = err;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
return 0;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 032/102] hwmon: (g760a) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (30 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 031/102] hwmon: (ftsteutates) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 033/102] hwmon: (g762) " Guenter Roeck
` (69 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the device is not polled for longer
than half the wrap period, time_after() can return false and prevent
cached fan values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 3bcfa9e47a7d ("hwmon: add support for GMT G760A fan speed PWM controller")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/g760a.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c
index e2166ee76286..3253e55f1d59 100644
--- a/drivers/hwmon/g760a.c
+++ b/drivers/hwmon/g760a.c
@@ -42,7 +42,7 @@ struct g760a_data {
/* g760a register cache */
unsigned int valid:1;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 set_cnt; /* PWM (period) count number; 0xff stops fan */
u8 act_cnt; /* formula: cnt = (CLK * 30)/(rpm * P) */
@@ -86,7 +86,8 @@ static struct g760a_data *g760a_update_client(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + G760A_UPDATE_INTERVAL)
+ if (time_after64(get_jiffies_64(),
+ data->last_updated + G760A_UPDATE_INTERVAL)
|| !data->valid) {
dev_dbg(&client->dev, "Starting g760a update\n");
@@ -94,7 +95,7 @@ static struct g760a_data *g760a_update_client(struct device *dev)
data->act_cnt = g760a_read_value(client, G760A_REG_ACT_CNT);
data->fan_sta = g760a_read_value(client, G760A_REG_FAN_STA);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 033/102] hwmon: (g762) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (31 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 032/102] hwmon: (g760a) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 034/102] hwmon: (gigabyte_waterforce) Use ktime for status validity timestamp Guenter Roeck
` (68 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_before() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the device is not polled for longer
than half the wrap period, time_before() can return true and prevent
cached fan values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_before64()
to avoid wraparound issues on 32-bit systems.
Fixes: 594fbe713bf6 ("Add support for GMT G762/G763 PWM fan controllers")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/g762.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c
index 407cf7af4fdd..119a79eb8d4f 100644
--- a/drivers/hwmon/g762.c
+++ b/drivers/hwmon/g762.c
@@ -128,7 +128,7 @@ struct g762_data {
/* g762 register cache */
bool valid;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
u8 set_cnt; /* controls fan rotation speed in closed-loop mode */
u8 act_cnt; /* provides access to current fan RPM value */
@@ -202,7 +202,8 @@ static struct g762_data *g762_update_client(struct device *dev)
int ret = 0;
mutex_lock(&data->update_lock);
- if (time_before(jiffies, data->last_updated + G762_UPDATE_INTERVAL) &&
+ if (time_before64(get_jiffies_64(),
+ data->last_updated + G762_UPDATE_INTERVAL) &&
likely(data->valid))
goto out;
@@ -236,7 +237,7 @@ static struct g762_data *g762_update_client(struct device *dev)
goto out;
data->fan_cmd2 = ret;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
out:
mutex_unlock(&data->update_lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 034/102] hwmon: (gigabyte_waterforce) Use ktime for status validity timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (32 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 033/102] hwmon: (g762) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 035/102] hwmon: (gl518sm) Use 64-bit jiffies for update timestamp Guenter Roeck
` (67 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Aleksa Savic
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
status reports from being refreshed.
Since STATUS_VALIDITY is defined in milliseconds, convert updated to
ktime_t and use ktime_get(), ktime_add_ms(), ktime_sub_ms(), and
ktime_after() to avoid 32-bit jiffies wraparound issues.
Fixes: 42ac68e3d4ba ("hwmon: Add driver for Gigabyte AORUS Waterforce AIO coolers")
Cc: Aleksa Savic <savicaleksa83@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/gigabyte_waterforce.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/gigabyte_waterforce.c b/drivers/hwmon/gigabyte_waterforce.c
index 34471852fe21..85f69353ed45 100644
--- a/drivers/hwmon/gigabyte_waterforce.c
+++ b/drivers/hwmon/gigabyte_waterforce.c
@@ -9,6 +9,7 @@
#include <linux/hid.h>
#include <linux/hwmon.h>
#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/unaligned.h>
@@ -67,7 +68,7 @@ struct waterforce_data {
u8 *buffer;
int firmware_version;
- unsigned long updated; /* jiffies */
+ ktime_t updated;
};
static umode_t waterforce_is_visible(const void *data,
@@ -129,7 +130,7 @@ static int waterforce_get_status(struct waterforce_data *priv)
return ret;
spin_lock_irq(&priv->status_report_request_lock);
- if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) {
+ if (!ktime_after(ktime_get(), ktime_add_ms(priv->updated, STATUS_VALIDITY))) {
/* Data is up to date */
spin_unlock_irq(&priv->status_report_request_lock);
goto unlock_and_return;
@@ -288,7 +289,7 @@ static int waterforce_raw_event(struct hid_device *hdev, struct hid_report *repo
priv->speed_input[1] = get_unaligned_le16(data + WATERFORCE_PUMP_SPEED);
priv->duty_input[0] = data[WATERFORCE_FAN_DUTY];
priv->duty_input[1] = data[WATERFORCE_PUMP_DUTY];
- priv->updated = jiffies;
+ priv->updated = ktime_get();
if (!completion_done(&priv->status_report_received))
complete_all(&priv->status_report_received);
spin_unlock_irqrestore(&priv->status_report_request_lock, flags);
@@ -332,11 +333,11 @@ static int waterforce_probe(struct hid_device *hdev, const struct hid_device_id
hid_set_drvdata(hdev, priv);
/*
- * Initialize priv->updated to STATUS_VALIDITY seconds in the past, making
+ * Initialize priv->updated to STATUS_VALIDITY in the past, making
* the initial empty data invalid for waterforce_read() without the need for
* a special case there.
*/
- priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY);
+ priv->updated = ktime_sub_ms(ktime_get(), STATUS_VALIDITY + 1);
ret = hid_parse(hdev);
if (ret) {
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 035/102] hwmon: (gl518sm) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (33 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 034/102] hwmon: (gigabyte_waterforce) Use ktime for status validity timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 036/102] hwmon: (gl520sm) " Guenter Roeck
` (66 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/gl518sm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index 742c130cec7f..8cf1d6cbf2c0 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -108,7 +108,7 @@ struct gl518_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 voltage_in[4]; /* Register values; [0] = VDD */
u8 voltage_min[4]; /* Register values; [0] = VDD */
@@ -155,7 +155,7 @@ static struct gl518_data *gl518_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
dev_dbg(&client->dev, "Starting gl518 update\n");
@@ -210,7 +210,7 @@ static struct gl518_data *gl518_update_device(struct device *dev)
data->voltage_in[3] =
gl518_read_value(client, GL518_REG_VIN3);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 036/102] hwmon: (gl520sm) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (34 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 035/102] hwmon: (gl518sm) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 037/102] hwmon: (hih6130) " Guenter Roeck
` (65 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 0cacdf298211 ("[PATCH] I2C: use time_after in 3 chip drivers")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/gl520sm.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index f4fe39912ee2..330bae7c1a95 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -65,7 +65,7 @@ struct gl520_data {
const struct attribute_group *groups[3];
struct mutex update_lock;
bool valid; /* false until the following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
u8 vid;
u8 vrm;
@@ -114,7 +114,8 @@ static struct gl520_data *gl520_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + 2 * HZ) ||
+ !data->valid) {
dev_dbg(&client->dev, "Starting gl520sm update\n");
@@ -173,7 +174,7 @@ static struct gl520_data *gl520_update_device(struct device *dev)
GL520_REG_IN_MAX[4]);
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 037/102] hwmon: (hih6130) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (35 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 036/102] hwmon: (gl520sm) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 038/102] hwmon: (hp-wmi-sensors) Use 64-bit jiffies for sensor cache timestamps Guenter Roeck
` (64 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the sensor is not polled for longer
than half the wrap period, time_after() can return false and prevent
cached temperature and humidity measurements from updating.
Convert last_update to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 27f8b1355504 ("hwmon: Honeywell Humidicon HIH-6130/HIH-6131 humidity and temperature sensor driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/hih6130.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/hih6130.c b/drivers/hwmon/hih6130.c
index 6a79aab5d128..581a0250c142 100644
--- a/drivers/hwmon/hih6130.c
+++ b/drivers/hwmon/hih6130.c
@@ -36,7 +36,7 @@ struct hih6130 {
struct i2c_client *client;
struct mutex lock;
bool valid;
- unsigned long last_update;
+ u64 last_update;
int temperature;
int humidity;
size_t write_length;
@@ -107,7 +107,8 @@ static int hih6130_update_measurements(struct device *dev)
* than it can react against better response times in conditions more
* favourable than specified in the datasheet.
*/
- if (time_after(jiffies, hih6130->last_update + HZ) || !hih6130->valid) {
+ if (time_after64(get_jiffies_64(), hih6130->last_update + HZ) ||
+ !hih6130->valid) {
/*
* Write to slave address to request a measurement.
@@ -140,7 +141,7 @@ static int hih6130_update_measurements(struct device *dev)
t = (tmp[2] << 8) + tmp[3];
hih6130->temperature = hih6130_temp_ticks_to_millicelsius(t);
- hih6130->last_update = jiffies;
+ hih6130->last_update = get_jiffies_64();
hih6130->valid = true;
}
out:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 038/102] hwmon: (hp-wmi-sensors) Use 64-bit jiffies for sensor cache timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (36 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 037/102] hwmon: (hih6130) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-03 3:41 ` James Seo
2026-11-02 22:51 ` [PATCH 039/102] hwmon: (ibmaem) Use 64-bit jiffies and record update timestamps Guenter Roeck
` (63 subsequent siblings)
101 siblings, 1 reply; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, James Seo
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If a sensor is not polled for longer
than half the wrap period, time_after() can return false and prevent
cached readings from updating.
Convert last_updated to u64, use get_jiffies_64() and time_after64(),
and acquire state->lock before checking info->last_updated so 64-bit
timestamp reads and writes are properly serialized on 32-bit systems.
Fixes: 23902f98f8d4 ("hwmon: add HP WMI Sensors driver")
Cc: James Seo <james@equiv.tech>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/hp-wmi-sensors.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/hp-wmi-sensors.c b/drivers/hwmon/hp-wmi-sensors.c
index 1953d672edaf..db309cb0c471 100644
--- a/drivers/hwmon/hp-wmi-sensors.c
+++ b/drivers/hwmon/hp-wmi-sensors.c
@@ -375,7 +375,7 @@ struct hp_wmi_info {
bool alarm;
enum hwmon_sensor_types type;
long cached_val;
- unsigned long last_updated; /* In jiffies. */
+ u64 last_updated; /* In jiffies. */
};
@@ -1196,7 +1196,7 @@ static void interpret_info(struct hp_wmi_info *info)
const struct hp_wmi_numeric_sensor *nsensor = &info->nsensor;
info->cached_val = scale_numeric_sensor(nsensor);
- info->last_updated = jiffies;
+ info->last_updated = get_jiffies_64();
}
/*
@@ -1215,9 +1215,9 @@ static int hp_wmi_update_info(struct hp_wmi_sensors *state,
u8 instance = info->instance;
int ret = 0;
- if (time_after(jiffies, info->last_updated + HZ)) {
- mutex_lock(&state->lock);
+ mutex_lock(&state->lock);
+ if (time_after64(get_jiffies_64(), info->last_updated + HZ)) {
wobj = wmidev_block_query(state->wdev, instance);
if (!wobj) {
ret = -EIO;
@@ -1229,10 +1229,10 @@ static int hp_wmi_update_info(struct hp_wmi_sensors *state,
interpret_info(info);
kfree(wobj);
+ }
out_unlock:
- mutex_unlock(&state->lock);
- }
+ mutex_unlock(&state->lock);
return ret;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 039/102] hwmon: (ibmaem) Use 64-bit jiffies and record update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (37 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 038/102] hwmon: (hp-wmi-sensors) Use 64-bit jiffies for sensor cache timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 040/102] hwmon: (ibmpex) Use 64-bit jiffies for update timestamp Guenter Roeck
` (62 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
update_aem1_sensors() and update_aem2_sensors() check cache freshness
with 32-bit time_before(jiffies, data->last_updated + REFRESH_INTERVAL),
which can overflow on 32-bit architectures after ~24.8 days at HZ=1000.
In addition, neither data->last_updated nor data->valid was ever set
after reading sensor values from the BMC.
Convert last_updated to u64, record last_updated and valid only when all
sensor reads succeed so IPMI read errors are not cached as valid data,
and use get_jiffies_64() and time_before64() to avoid 32-bit wraparound
issues.
Fixes: 8808a793f052 ("ibmaem: new driver for power/energy/temp meters in IBM System X hardware")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ibmaem.c | 53 ++++++++++++++++++++++++++++--------------
1 file changed, 35 insertions(+), 18 deletions(-)
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 0a9c3a29e6f2..b083d0d3ec85 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -128,7 +128,7 @@ struct aem_data {
struct platform_device *pdev;
struct mutex lock;
bool valid;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 ver_major;
u8 ver_minor;
u8 module_handle;
@@ -417,29 +417,37 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
}
/* Update AEM energy registers */
-static void update_aem_energy_one(struct aem_data *data, int which)
+static int update_aem_energy_one(struct aem_data *data, int which)
{
- aem_read_sensor(data, AEM_ENERGY_ELEMENT, which,
- &data->energy[which], 8);
+ return aem_read_sensor(data, AEM_ENERGY_ELEMENT, which,
+ &data->energy[which], 8);
}
-static void update_aem_energy(struct aem_data *data)
+static int update_aem_energy(struct aem_data *data)
{
- update_aem_energy_one(data, 0);
+ int err, ret;
+
+ err = update_aem_energy_one(data, 0);
if (data->ver_major < 2)
- return;
- update_aem_energy_one(data, 1);
+ return err;
+
+ ret = update_aem_energy_one(data, 1);
+ return err ? err : ret;
}
/* Update all AEM1 sensors */
static void update_aem1_sensors(struct aem_data *data)
{
mutex_lock(&data->lock);
- if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) &&
+ if (time_before64(get_jiffies_64(),
+ data->last_updated + REFRESH_INTERVAL) &&
data->valid)
goto out;
- update_aem_energy(data);
+ if (!update_aem_energy(data)) {
+ data->last_updated = get_jiffies_64();
+ data->valid = true;
+ }
out:
mutex_unlock(&data->lock);
}
@@ -447,20 +455,29 @@ static void update_aem1_sensors(struct aem_data *data)
/* Update all AEM2 sensors */
static void update_aem2_sensors(struct aem_data *data)
{
- int i;
+ int i, err;
mutex_lock(&data->lock);
- if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) &&
+ if (time_before64(get_jiffies_64(),
+ data->last_updated + REFRESH_INTERVAL) &&
data->valid)
goto out;
- update_aem_energy(data);
- aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 0, &data->temp[0], 1);
- aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 1, &data->temp[1], 1);
+ err = update_aem_energy(data);
+ if (aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 0, &data->temp[0], 1))
+ err = -EIO;
+ if (aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 1, &data->temp[1], 1))
+ err = -EIO;
- for (i = POWER_CAP; i <= POWER_AUX; i++)
- aem_read_sensor(data, AEM_POWER_CAP_ELEMENT, i,
- &data->pcap[i], 2);
+ for (i = POWER_CAP; i <= POWER_AUX; i++) {
+ if (aem_read_sensor(data, AEM_POWER_CAP_ELEMENT, i,
+ &data->pcap[i], 2))
+ err = -EIO;
+ }
+ if (!err) {
+ data->last_updated = get_jiffies_64();
+ data->valid = true;
+ }
out:
mutex_unlock(&data->lock);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 040/102] hwmon: (ibmpex) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (38 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 039/102] hwmon: (ibmaem) Use 64-bit jiffies and record update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 041/102] hwmon: (ina209) Use ktime " Guenter Roeck
` (61 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_before() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_before() can return true and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_before64()
to avoid wraparound issues on 32-bit systems.
Fixes: 57c7c3a0fdea ("hwmon: IBM power meter driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ibmpex.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index dec730798d58..3a119be0d339 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -67,7 +67,7 @@ struct ibmpex_bmc_data {
struct device *bmc_device;
struct mutex lock;
bool valid;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
struct ipmi_addr address;
struct completion read_complete;
@@ -220,7 +220,8 @@ static void ibmpex_update_device(struct ibmpex_bmc_data *data)
int i, err;
mutex_lock(&data->lock);
- if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) &&
+ if (time_before64(get_jiffies_64(),
+ data->last_updated + REFRESH_INTERVAL) &&
data->valid)
goto out;
@@ -238,7 +239,7 @@ static void ibmpex_update_device(struct ibmpex_bmc_data *data)
extract_value(data->rx_msg_data, 20);
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
out:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 041/102] hwmon: (ina209) Use ktime for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (39 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 040/102] hwmon: (ibmpex) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 042/102] hwmon: (it87) Use 64-bit jiffies " Guenter Roeck
` (60 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
ina209_update_device() checks cache expiration with
time_after(jiffies, data->last_updated + data->update_interval). On
32-bit architectures, 32-bit jiffies comparisons wrap after ~24.8 days
at HZ=1000 and can prevent cached readings from updating if unpolled.
Furthermore, data->update_interval is in milliseconds (up to 68 ms)
rather than jiffies, causing mismatched units whenever HZ != 1000.
Convert last_updated to ktime_t and use ktime_get(), ktime_add_ms(), and
ktime_after() with a 1 ms minimum cache window (matching the ~1.06 ms
default single-sample shunt+bus conversion cycle when update_interval
truncates to 0 ms) so rapid sequential sysfs reads still coalesce into a
single I2C register dump.
Fixes: ceeadc5c5187 ("hwmon: Driver for Texas Instruments INA209")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ina209.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/ina209.c b/drivers/hwmon/ina209.c
index 39aca2cdf27f..e52ba7d97300 100644
--- a/drivers/hwmon/ina209.c
+++ b/drivers/hwmon/ina209.c
@@ -18,6 +18,7 @@
*/
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
@@ -62,7 +63,7 @@ struct ina209_data {
struct mutex update_lock;
bool valid;
- unsigned long last_updated; /* in jiffies */
+ ktime_t last_updated;
u16 regs[INA209_REGISTERS]; /* All chip registers */
@@ -81,8 +82,15 @@ static struct ina209_data *ina209_update_device(struct device *dev)
mutex_lock(&data->update_lock);
+ /*
+ * Single-sample conversion takes 532 us per channel (~1.06 ms for
+ * shunt and bus), which truncates to 0 ms in update_interval. Enforce
+ * at least a 1 ms cache window so rapid sequential sysfs reads coalesce.
+ */
if (!data->valid ||
- time_after(jiffies, data->last_updated + data->update_interval)) {
+ ktime_after(ktime_get(),
+ ktime_add_ms(data->last_updated,
+ max_t(u16, data->update_interval, 1)))) {
for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
val = i2c_smbus_read_word_swapped(client, i);
if (val < 0) {
@@ -91,7 +99,7 @@ static struct ina209_data *ina209_update_device(struct device *dev)
}
data->regs[i] = val;
}
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
abort:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 042/102] hwmon: (it87) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (40 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 041/102] hwmon: (ina209) Use ktime " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 043/102] hwmon: (kbatt) Use 64-bit jiffies for update deadline Guenter Roeck
` (59 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/it87.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 14800a56513e..13dc1480471e 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -680,7 +680,7 @@ struct it87_data {
const char *name;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u16 in_scaled; /* Internal voltage sensors are scaled */
u16 in_internal; /* Bitfield, internal sensors (for labels) */
@@ -1050,8 +1050,8 @@ static struct it87_data *it87_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
- !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
err = smbus_disable(data);
if (err) {
ret = ERR_PTR(err);
@@ -1157,7 +1157,7 @@ static struct it87_data *it87_update_device(struct device *dev)
*/
data->vid &= 0x3f;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
smbus_enable(data);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 043/102] hwmon: (kbatt) Use 64-bit jiffies for update deadline
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (41 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 042/102] hwmon: (it87) Use 64-bit jiffies " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 044/102] hwmon: (lineage-pem) Use 64-bit jiffies for update timestamp Guenter Roeck
` (58 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the battery alarm is not polled for
longer than half the wrap period, time_after() can return false and
prevent the battery status from being re-tested.
Include <linux/jiffies.h> explicitly, convert next_update to u64, and
use get_jiffies_64() and time_after64() to avoid wraparound issues on
32-bit systems.
Fixes: 7e581c193bde ("hwmon: Add KEBA battery monitoring controller support")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/kbatt.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/kbatt.c b/drivers/hwmon/kbatt.c
index 501b8f4ded33..69bc9c2f14ee 100644
--- a/drivers/hwmon/kbatt.c
+++ b/drivers/hwmon/kbatt.c
@@ -8,6 +8,7 @@
#include <linux/hwmon.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/auxiliary_bus.h>
@@ -30,7 +31,7 @@ struct kbatt {
struct mutex lock;
void __iomem *base;
- unsigned long next_update; /* in jiffies */
+ u64 next_update; /* in jiffies */
bool alarm;
};
@@ -38,7 +39,8 @@ static bool kbatt_alarm(struct kbatt *kbatt)
{
mutex_lock(&kbatt->lock);
- if (!kbatt->next_update || time_after(jiffies, kbatt->next_update)) {
+ if (!kbatt->next_update ||
+ time_after64(get_jiffies_64(), kbatt->next_update)) {
/* switch load on */
iowrite8(KBATT_CONTROL_BAT_TEST,
kbatt->base + KBATT_CONTROL_REG);
@@ -56,7 +58,7 @@ static bool kbatt_alarm(struct kbatt *kbatt)
/* switch load off */
iowrite8(0, kbatt->base + KBATT_CONTROL_REG);
- kbatt->next_update = jiffies + KBATT_MAX_UPD_INTERVAL;
+ kbatt->next_update = get_jiffies_64() + KBATT_MAX_UPD_INTERVAL;
}
mutex_unlock(&kbatt->lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 044/102] hwmon: (lineage-pem) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (42 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 043/102] hwmon: (kbatt) Use 64-bit jiffies for update deadline Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 045/102] hwmon: (lm63) Use ktime for update timestamps Guenter Roeck
` (57 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 502b5a019920 ("hwmon: Add support for Lineage Compact Power Line PEM devices")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lineage-pem.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c
index 75a44b0639dc..7487ab1657a8 100644
--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -119,7 +119,7 @@ struct pem_data {
bool valid;
bool fans_supported;
int input_length;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
u8 firmware_rev[FIRMWARE_REV_LEN];
u8 data_string[DATA_STRING_LEN];
@@ -149,7 +149,8 @@ static struct pem_data *pem_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
int result;
/* Read data string */
@@ -185,7 +186,7 @@ static struct pem_data *pem_update_device(struct device *dev)
i2c_smbus_write_byte(client, PEM_CLEAR_INFO_FLAGS);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
abort:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 045/102] hwmon: (lm63) Use ktime for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (43 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 044/102] hwmon: (lineage-pem) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 046/102] hwmon: (lm77) Use 64-bit jiffies for update timestamp Guenter Roeck
` (56 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor and lookup-table registers from updating.
Since update_interval is stored in milliseconds, convert last_updated
and lut_last_updated to ktime_t and use ktime_get(), ktime_add_ms(), and
ktime_after() to avoid 32-bit jiffies wraparound issues.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm63.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 607758bf7c58..6ae2d42fb30f 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -27,7 +27,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/i2c.h>
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
@@ -156,8 +156,8 @@ struct lm63_data {
const struct attribute_group *groups[5];
bool valid; /* false until following fields are valid */
char lut_valid; /* zero until lut fields are valid */
- unsigned long last_updated; /* in jiffies */
- unsigned long lut_last_updated; /* in jiffies */
+ ktime_t last_updated;
+ ktime_t lut_last_updated;
enum chips kind;
int temp2_offset;
@@ -222,7 +222,8 @@ static void lm63_update_lut(struct lm63_data *data)
struct i2c_client *client = data->client;
int i;
- if (time_after(jiffies, data->lut_last_updated + 5 * HZ) ||
+ if (ktime_after(ktime_get(),
+ ktime_add_ms(data->lut_last_updated, 5000)) ||
!data->lut_valid) {
for (i = 0; i < data->lut_size; i++) {
data->pwm1[1 + i] = i2c_smbus_read_byte_data(client,
@@ -233,7 +234,7 @@ static void lm63_update_lut(struct lm63_data *data)
data->lut_temp_hyst = i2c_smbus_read_byte_data(client,
LM63_REG_LUT_TEMP_HYST);
- data->lut_last_updated = jiffies;
+ data->lut_last_updated = ktime_get();
data->lut_valid = 1;
}
}
@@ -242,14 +243,13 @@ static struct lm63_data *lm63_update_device(struct device *dev)
{
struct lm63_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- unsigned long next_update;
+ ktime_t next_update;
int msb, lsb;
mutex_lock(&data->update_lock);
- next_update = data->last_updated +
- msecs_to_jiffies(data->update_interval);
- if (time_after(jiffies, next_update) || !data->valid) {
+ next_update = ktime_add_ms(data->last_updated, data->update_interval);
+ if (ktime_after(ktime_get(), next_update) || !data->valid) {
if (data->config & 0x04) { /* tachometer enabled */
/* order matters for fan1_input */
data->fan[0] = i2c_smbus_read_byte_data(client,
@@ -321,7 +321,7 @@ static struct lm63_data *lm63_update_device(struct device *dev)
data->alarms = i2c_smbus_read_byte_data(client,
LM63_REG_ALERT_STATUS) & 0x7F;
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 046/102] hwmon: (lm77) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (44 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 045/102] hwmon: (lm63) Use ktime for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 047/102] hwmon: (lm78) " Guenter Roeck
` (55 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If the sensor is not polled for longer
than half the wrap period, time_after() can return false and prevent
cached temperature values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm77.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 96c5c2584d37..9f66cb761e11 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -56,7 +56,7 @@ struct lm77_data {
struct i2c_client *client;
struct mutex update_lock;
bool valid;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
int temp[t_num_temp]; /* index using temp_index */
u8 alarms;
};
@@ -107,7 +107,7 @@ static struct lm77_data *lm77_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
dev_dbg(&client->dev, "Starting lm77 update\n");
for (i = 0; i < t_num_temp; i++) {
@@ -117,7 +117,7 @@ static struct lm77_data *lm77_update_device(struct device *dev)
}
data->alarms =
lm77_read_value(client, LM77_REG_TEMP) & 0x0007;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 047/102] hwmon: (lm78) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (45 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 046/102] hwmon: (lm77) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 048/102] hwmon: (lm80) " Guenter Roeck
` (54 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm78.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index e4834f9eca6a..928936cec849 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -118,7 +118,7 @@ struct lm78_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[7]; /* Register value */
u8 in_max[7]; /* Register value */
@@ -733,7 +733,7 @@ static struct lm78_data *lm78_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
dev_dbg(dev, "Starting lm78 update\n");
@@ -769,7 +769,7 @@ static struct lm78_data *lm78_update_device(struct device *dev)
data->fan_div[1] = i >> 6;
data->alarms = lm78_read_value(data, LM78_REG_ALARM1) +
(lm78_read_value(data, LM78_REG_ALARM2) << 8);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
data->fan_div[2] = 1;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 048/102] hwmon: (lm80) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (46 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 047/102] hwmon: (lm78) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 049/102] hwmon: (lm85) Use 64-bit jiffies for update timestamps Guenter Roeck
` (53 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm80.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
index 94f3dabaaa6f..a81f14bc73e5 100644
--- a/drivers/hwmon/lm80.c
+++ b/drivers/hwmon/lm80.c
@@ -118,7 +118,7 @@ struct lm80_data {
struct mutex update_lock;
char error; /* !=0 if error occurred during last update */
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[i_num_in][7]; /* Register value, 1st index is enum in_index */
u8 fan[f_num_fan][2]; /* Register value, 1st index enum fan_index */
@@ -167,7 +167,8 @@ static struct lm80_data *lm80_update_device(struct device *dev)
if (data->error)
lm80_init_client(client);
- if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + 2 * HZ) ||
+ !data->valid) {
dev_dbg(dev, "Starting lm80 update\n");
for (i = 0; i <= 6; i++) {
rv = lm80_read_value(client, LM80_REG_IN(i));
@@ -235,7 +236,7 @@ static struct lm80_data *lm80_update_device(struct device *dev)
goto abort;
data->alarms = prev_rv + (rv << 8);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
data->error = 0;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 049/102] hwmon: (lm85) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (47 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 048/102] hwmon: (lm80) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 050/102] hwmon: (lm87) Use 64-bit jiffies for update timestamp Guenter Roeck
` (52 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor and configuration values from updating.
Convert last_reading and last_config to u64 and use get_jiffies_64() and
time_after64() to avoid wraparound issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm85.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index 27ef127ccc2c..de223db48b59 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -295,8 +295,8 @@ struct lm85_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_reading; /* In jiffies */
- unsigned long last_config; /* In jiffies */
+ u64 last_reading; /* In jiffies */
+ u64 last_config; /* In jiffies */
u8 in[8]; /* Register value */
u8 in_max[8]; /* Register value */
@@ -374,7 +374,8 @@ static struct lm85_data *lm85_update_device(struct device *dev)
mutex_lock(&data->update_lock);
if (!data->valid ||
- time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) {
+ time_after64(get_jiffies_64(),
+ data->last_reading + LM85_DATA_INTERVAL)) {
/* Things that change quickly */
dev_dbg(&client->dev, "Reading sensor values\n");
@@ -463,11 +464,12 @@ static struct lm85_data *lm85_update_device(struct device *dev)
data->temp_ext[2] = ext1 >> 4;
}
- data->last_reading = jiffies;
+ data->last_reading = get_jiffies_64();
} /* last_reading */
if (!data->valid ||
- time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) {
+ time_after64(get_jiffies_64(),
+ data->last_config + LM85_CONFIG_INTERVAL)) {
/* Things that don't change often */
dev_dbg(&client->dev, "Reading config values\n");
@@ -538,7 +540,7 @@ static struct lm85_data *lm85_update_device(struct device *dev)
data->zone[2].hyst = i >> 4;
}
- data->last_config = jiffies;
+ data->last_config = get_jiffies_64();
} /* last_config */
data->valid = true;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 050/102] hwmon: (lm87) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (48 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 049/102] hwmon: (lm85) Use 64-bit jiffies for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 051/102] hwmon: (lm90) Use ktime for update timestamps Guenter Roeck
` (51 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm87.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index bb4e15b66355..902fc617cee8 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -148,7 +148,7 @@ static int fan_from_reg(int reg, int div)
struct lm87_data {
struct mutex update_lock;
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 channel; /* register value */
u8 config; /* original register value */
@@ -193,7 +193,8 @@ static struct lm87_data *lm87_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
int i, j;
dev_dbg(&client->dev, "Updating data.\n");
@@ -256,7 +257,7 @@ static struct lm87_data *lm87_update_device(struct device *dev)
<< 8);
data->aout = lm87_read_value(client, LM87_REG_AOUT);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 051/102] hwmon: (lm90) Use ktime for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (49 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 050/102] hwmon: (lm87) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 052/102] hwmon: (lm93) Use 64-bit jiffies for update timestamp Guenter Roeck
` (50 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors or alarms are not polled
for longer than half the wrap period, time_after() can return false and
prevent cached temperature and alarm registers from updating.
Since update_interval is stored in milliseconds, convert last_updated
and alarms_updated to ktime_t and use ktime_get(), ktime_add_ms(), and
ktime_after() to avoid 32-bit jiffies wraparound issues.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm90.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 3faeb2c6ab01..3e511bdf2872 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -108,6 +108,7 @@
#include <linux/jiffies.h>
#include <linux/hwmon.h>
#include <linux/kstrtox.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
@@ -740,8 +741,8 @@ struct lm90_data {
bool shutdown; /* true if shutting down */
bool valid; /* true if register values are valid */
bool alarms_valid; /* true if status register values are valid */
- unsigned long last_updated; /* in jiffies */
- unsigned long alarms_updated; /* in jiffies */
+ ktime_t last_updated;
+ ktime_t alarms_updated;
int kind;
u32 flags;
@@ -1160,7 +1161,9 @@ static int lm90_update_alarms_locked(struct lm90_data *data, bool force)
return 0;
if (force || !data->alarms_valid ||
- time_after(jiffies, data->alarms_updated + msecs_to_jiffies(data->update_interval))) {
+ ktime_after(ktime_get(),
+ ktime_add_ms(data->alarms_updated,
+ data->update_interval))) {
struct i2c_client *client = data->client;
bool check_enable;
u16 alarms;
@@ -1219,7 +1222,7 @@ static int lm90_update_alarms_locked(struct lm90_data *data, bool force)
max_t(int, HZ, msecs_to_jiffies(data->update_interval)));
}
}
- data->alarms_updated = jiffies;
+ data->alarms_updated = ktime_get();
data->alarms_valid = true;
}
return 0;
@@ -1247,7 +1250,7 @@ static int lm90_update_device(struct device *dev)
{
struct lm90_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- unsigned long next_update;
+ ktime_t next_update;
int val;
if (!data->valid) {
@@ -1256,9 +1259,8 @@ static int lm90_update_device(struct device *dev)
return val;
}
- next_update = data->last_updated +
- msecs_to_jiffies(data->update_interval);
- if (time_after(jiffies, next_update) || !data->valid) {
+ next_update = ktime_add_ms(data->last_updated, data->update_interval);
+ if (ktime_after(ktime_get(), next_update) || !data->valid) {
dev_dbg(&client->dev, "Updating lm90 data.\n");
data->valid = false;
@@ -1304,7 +1306,7 @@ static int lm90_update_device(struct device *dev)
if (val < 0)
return val;
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 052/102] hwmon: (lm93) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (50 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 051/102] hwmon: (lm90) Use ktime for update timestamps Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 053/102] hwmon: (lm95241) Use ktime " Guenter Roeck
` (49 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor values from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: e46957edfb85 ("hwmon: Add LM93 support")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm93.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index 2cbf0af22f61..09bc7fe650ad 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -197,7 +197,7 @@ struct lm93_data {
struct i2c_client *client;
struct mutex update_lock;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/* client update function */
void (*update)(struct lm93_data *, struct i2c_client *);
@@ -904,11 +904,10 @@ static struct lm93_data *lm93_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + interval) ||
- !data->valid) {
-
+ if (time_after64(get_jiffies_64(), data->last_updated + interval) ||
+ !data->valid) {
data->update(data, client);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 053/102] hwmon: (lm95241) Use ktime for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (51 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 052/102] hwmon: (lm93) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 054/102] hwmon: (ltc4151) " Guenter Roeck
` (48 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached temperature values from updating.
Since interval is stored in milliseconds, convert last_updated to
ktime_t and use ktime_get(), ktime_add_ms(), and ktime_after() to avoid
32-bit jiffies wraparound issues.
Fixes: 061603275814 ("hwmon: LM95241 driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/lm95241.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index 0cb0edb3845d..8359a7fdd6b4 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -12,7 +12,7 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/hwmon.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -74,7 +74,7 @@ static const u8 lm95241_reg_address[] = {
/* Client data (each client gets its own) */
struct lm95241_data {
struct i2c_client *client;
- unsigned long last_updated; /* in jiffies */
+ ktime_t last_updated;
unsigned long interval; /* in milli-seconds */
bool valid; /* false until following fields are valid */
/* registers values */
@@ -100,8 +100,8 @@ static struct lm95241_data *lm95241_update_device(struct device *dev)
struct lm95241_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- if (time_after(jiffies, data->last_updated
- + msecs_to_jiffies(data->interval)) ||
+ if (ktime_after(ktime_get(),
+ ktime_add_ms(data->last_updated, data->interval)) ||
!data->valid) {
int i;
@@ -113,7 +113,7 @@ static struct lm95241_data *lm95241_update_device(struct device *dev)
data->status = i2c_smbus_read_byte_data(client,
LM95241_REG_R_STATUS);
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
return data;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 054/102] hwmon: (ltc4151) Use ktime for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (52 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 053/102] hwmon: (lm95241) Use ktime " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 055/102] hwmon: (ltc4215) " Guenter Roeck
` (47 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached ADC readings from updating.
Convert last_updated to ktime_t and use ktime_get(), ktime_add_ns() with
NSEC_PER_SEC / 6, and ktime_after() to avoid 32-bit jiffies wraparound
and coarse HZ rounding issues.
Fixes: de7790155f74 ("hwmon: Add support for LTC4151")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ltc4151.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c
index fa7c57aae5f5..8115b2a34a47 100644
--- a/drivers/hwmon/ltc4151.c
+++ b/drivers/hwmon/ltc4151.c
@@ -23,7 +23,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
/* chip registers */
#define LTC4151_SENSE_H 0x00
@@ -38,7 +38,7 @@ struct ltc4151_data {
struct mutex update_lock;
bool valid;
- unsigned long last_updated; /* in jiffies */
+ ktime_t last_updated;
unsigned int shunt; /* in micro ohms */
/* Registers */
@@ -57,7 +57,9 @@ static struct ltc4151_data *ltc4151_update_device(struct device *dev)
* The chip's A/D updates 6 times per second
* (Conversion Rate 6 - 9 Hz)
*/
- if (time_after(jiffies, data->last_updated + HZ / 6) || !data->valid) {
+ if (ktime_after(ktime_get(),
+ ktime_add_ns(data->last_updated, NSEC_PER_SEC / 6)) ||
+ !data->valid) {
int i;
dev_dbg(&client->dev, "Starting ltc4151 update\n");
@@ -76,7 +78,7 @@ static struct ltc4151_data *ltc4151_update_device(struct device *dev)
}
data->regs[i] = val;
}
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
abort:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 055/102] hwmon: (ltc4215) Use ktime for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (53 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 054/102] hwmon: (ltc4151) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 056/102] hwmon: (ltc4245) Use 64-bit jiffies " Guenter Roeck
` (46 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached ADC readings from updating.
Convert last_updated to ktime_t and use ktime_get(), ktime_add_ms(), and
ktime_after() for the 100 ms update interval to avoid 32-bit jiffies
wraparound issues.
Fixes: 72f5de92e199 ("hwmon: Add LTC4215 driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ltc4215.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 3d439fbbbef9..4436ca1517e0 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -16,7 +16,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4215_cmd {
@@ -34,7 +34,7 @@ struct ltc4215_data {
struct mutex update_lock;
bool valid;
- unsigned long last_updated; /* in jiffies */
+ ktime_t last_updated;
/* Registers */
u8 regs[7];
@@ -50,7 +50,8 @@ static struct ltc4215_data *ltc4215_update_device(struct device *dev)
mutex_lock(&data->update_lock);
/* The chip's A/D updates 10 times per second */
- if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) {
+ if (ktime_after(ktime_get(), ktime_add_ms(data->last_updated, 100)) ||
+ !data->valid) {
dev_dbg(&client->dev, "Starting ltc4215 update\n");
@@ -63,7 +64,7 @@ static struct ltc4215_data *ltc4215_update_device(struct device *dev)
data->regs[i] = val;
}
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 056/102] hwmon: (ltc4245) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (54 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 055/102] hwmon: (ltc4215) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 057/102] hwmon: (ltc4261) Use ktime " Guenter Roeck
` (45 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached sensor and GPIO readings from updating properly.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 6e34b187bc21 ("hwmon: Add LTC4245 driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ltc4245.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index d87aa9c32c87..46d521ee5aca 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -51,7 +51,7 @@ struct ltc4245_data {
struct i2c_client *client;
bool valid;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* Control registers */
u8 cregs[0x08];
@@ -88,7 +88,7 @@ static void ltc4245_update_gpios(struct device *dev)
* If the last reading was too long ago, then we mark all old GPIO
* readings as stale by setting them to -EAGAIN
*/
- if (time_after(jiffies, data->last_updated + 5 * HZ)) {
+ if (time_after64(get_jiffies_64(), data->last_updated + 5 * HZ)) {
for (i = 0; i < ARRAY_SIZE(data->gpios); i++)
data->gpios[i] = -EAGAIN;
}
@@ -130,7 +130,8 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev)
s32 val;
int i;
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
/* Read control registers -- 0x00 to 0x07 */
for (i = 0; i < ARRAY_SIZE(data->cregs); i++) {
val = i2c_smbus_read_byte_data(client, i);
@@ -152,7 +153,7 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev)
/* Update GPIO readings */
ltc4245_update_gpios(dev);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 057/102] hwmon: (ltc4261) Use ktime for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (55 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 056/102] hwmon: (ltc4245) Use 64-bit jiffies " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 058/102] hwmon: (max16065) Use 64-bit jiffies " Guenter Roeck
` (44 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached ADC readings from updating.
Convert last_updated to ktime_t and use ktime_get(), ktime_add_ms(), and
ktime_after() for the 250 ms update interval to avoid 32-bit jiffies
wraparound issues.
Fixes: e5f5c99a3937 ("hwmon: LTC4261 Hardware monitoring driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/ltc4261.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c
index a2e52ca0b06e..7c2e08b850d5 100644
--- a/drivers/hwmon/ltc4261.c
+++ b/drivers/hwmon/ltc4261.c
@@ -20,7 +20,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
/* chip registers */
#define LTC4261_STATUS 0x00 /* readonly */
@@ -46,7 +46,7 @@ struct ltc4261_data {
struct mutex update_lock;
bool valid;
- unsigned long last_updated; /* in jiffies */
+ ktime_t last_updated;
/* Registers */
u8 regs[10];
@@ -60,7 +60,8 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ / 4) || !data->valid) {
+ if (ktime_after(ktime_get(), ktime_add_ms(data->last_updated, 250)) ||
+ !data->valid) {
int i;
/* Read registers -- 0x00 to 0x09 */
@@ -78,7 +79,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev)
}
data->regs[i] = val;
}
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
abort:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 058/102] hwmon: (max16065) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (56 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 057/102] hwmon: (ltc4261) Use ktime " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 059/102] hwmon: (max31790) " Guenter Roeck
` (43 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached ADC and fault readings from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: f5bae2642e3d ("hwmon: Driver for MAX16065 System Manager and compatibles")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/max16065.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
index f8b421754220..1cad2b54ed6d 100644
--- a/drivers/hwmon/max16065.c
+++ b/drivers/hwmon/max16065.c
@@ -84,7 +84,7 @@ struct max16065_data {
const struct attribute_group *groups[4];
struct mutex update_lock;
bool valid;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
int num_adc;
bool have_current;
int curr_gain;
@@ -147,7 +147,8 @@ static struct max16065_data *max16065_update_device(struct device *dev)
struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
int i;
for (i = 0; i < data->num_adc; i++)
@@ -173,7 +174,7 @@ static struct max16065_data *max16065_update_device(struct device *dev)
WRITE_ONCE(data->fault[0],
data->fault[0] | data->fault[1]);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
mutex_unlock(&data->update_lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 059/102] hwmon: (max31790) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (57 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 058/102] hwmon: (max16065) Use 64-bit jiffies " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 060/102] hwmon: (max6620) " Guenter Roeck
` (42 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, jiffies and time_after() use 32-bit values and
wrap after ~24.8 days at HZ=1000. If sensors are not polled for longer
than half the wrap period, time_after() can return false and prevent
cached fan readings from updating.
Convert last_updated to u64 and use get_jiffies_64() and time_after64()
to avoid wraparound issues on 32-bit systems.
Fixes: 195a4b4298a7 ("hwmon: Driver for Maxim MAX31790")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/max31790.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c
index db8a0f6f1829..8551b8a26ff6 100644
--- a/drivers/hwmon/max31790.c
+++ b/drivers/hwmon/max31790.c
@@ -58,7 +58,7 @@
struct max31790_data {
struct i2c_client *client;
bool valid; /* zero until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* register values */
u8 fan_config[NR_CHANNEL];
@@ -75,7 +75,8 @@ static struct max31790_data *max31790_update_device(struct device *dev)
struct i2c_client *client = data->client;
int i, rv;
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
data->valid = false;
rv = i2c_smbus_read_byte_data(client,
MAX31790_REG_FAN_FAULT_STATUS1);
@@ -119,7 +120,7 @@ static struct max31790_data *max31790_update_device(struct device *dev)
}
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
return data;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 060/102] hwmon: (max6620) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (58 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 059/102] hwmon: (max31790) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 061/102] hwmon: (max6650) " Guenter Roeck
` (41 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
max6620 uses 32-bit jiffies and time_after() to determine when cached
fan and fault register values should be refreshed. On 32-bit
architectures, if the sensor is not polled for about 24.8 days at
HZ=1000, time_after() wraps around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: e8ac01e5db32 ("hwmon: Add Maxim MAX6620 hardware monitoring driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/max6620.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/max6620.c b/drivers/hwmon/max6620.c
index 100acf357b5f..dc39f247825f 100644
--- a/drivers/hwmon/max6620.c
+++ b/drivers/hwmon/max6620.c
@@ -131,7 +131,7 @@ static const u8 target_reg[] = {
struct max6620_data {
struct i2c_client *client;
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* register values */
u8 fancfg[4];
@@ -162,7 +162,8 @@ static int max6620_update_device(struct device *dev)
struct i2c_client *client = data->client;
int i, ret;
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
for (i = 0; i < 4; i++) {
ret = i2c_smbus_read_byte_data(client, config_reg[i]);
if (ret < 0)
@@ -203,7 +204,7 @@ static int max6620_update_device(struct device *dev)
return ret;
data->fault |= (ret >> 4) & (ret & 0x0F);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
return 0;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 061/102] hwmon: (max6650) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (59 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 060/102] hwmon: (max6620) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 062/102] hwmon: (menf21bmc_hwmon) " Guenter Roeck
` (40 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
max6650 uses 32-bit jiffies and time_after() to determine when cached
tachometer and alarm register values should be refreshed. On 32-bit
architectures, if the sensor is not polled for about 24.8 days at
HZ=1000, time_after() wraps around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: d20620de0c3d ("hwmon: New max6650 driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/max6650.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index 90c37f5647bc..62909a19a238 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -105,7 +105,7 @@ struct max6650_data {
struct mutex update_lock; /* protect alarm register updates */
int nr_fans;
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* register values */
u8 speed;
@@ -163,7 +163,8 @@ static struct max6650_data *max6650_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
for (i = 0; i < data->nr_fans; i++) {
reg = i2c_smbus_read_byte_data(client, tach_reg[i]);
if (reg < 0) {
@@ -184,7 +185,7 @@ static struct max6650_data *max6650_update_device(struct device *dev)
goto error;
}
data->alarm |= reg;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 062/102] hwmon: (menf21bmc_hwmon) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (60 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 061/102] hwmon: (max6650) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 063/102] hwmon: (nct6683) " Guenter Roeck
` (39 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
menf21bmc_hwmon uses 32-bit jiffies and time_after() to determine when
cached voltage readings should be refreshed. On 32-bit architectures,
if the sensor is not polled for about 24.8 days at HZ=1000, time_after()
wraps around and cached values stop updating.
Switch last_update to u64, use get_jiffies_64() with time_after64(), and
serialize sensor updates and 64-bit timestamp accesses in
menf21bmc_hwmon_update() with hwmon_lock.
Fixes: 964356938fcd ("hwmon: (menf21bmc) Introduce MEN14F021P00 BMC HWMON driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/menf21bmc_hwmon.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/menf21bmc_hwmon.c b/drivers/hwmon/menf21bmc_hwmon.c
index adb50115c32b..9d0aaa773991 100644
--- a/drivers/hwmon/menf21bmc_hwmon.c
+++ b/drivers/hwmon/menf21bmc_hwmon.c
@@ -35,7 +35,7 @@
struct menf21bmc_hwmon {
bool valid;
struct i2c_client *i2c_client;
- unsigned long last_update;
+ u64 last_update;
int in_val[BMC_VOLT_COUNT];
int in_min[BMC_VOLT_COUNT];
int in_max[BMC_VOLT_COUNT];
@@ -54,24 +54,23 @@ static struct menf21bmc_hwmon *menf21bmc_hwmon_update(struct device *dev)
int i;
int val;
struct menf21bmc_hwmon *drv_data = dev_get_drvdata(dev);
- struct menf21bmc_hwmon *data_ret = drv_data;
- if (time_after(jiffies, drv_data->last_update + HZ)
+ guard(hwmon_lock)(dev);
+
+ if (time_after64(get_jiffies_64(), drv_data->last_update + HZ)
|| !drv_data->valid) {
for (i = 0; i < BMC_VOLT_COUNT; i++) {
val = i2c_smbus_read_word_data(drv_data->i2c_client,
IDX_TO_VOLT_INP_CMD(i));
- if (val < 0) {
- data_ret = ERR_PTR(val);
- goto abort;
- }
+ if (val < 0)
+ return ERR_PTR(val);
drv_data->in_val[i] = val;
}
- drv_data->last_update = jiffies;
+ drv_data->last_update = get_jiffies_64();
drv_data->valid = true;
}
-abort:
- return data_ret;
+
+ return drv_data;
}
static int menf21bmc_hwmon_get_volt_limits(struct menf21bmc_hwmon *drv_data)
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 063/102] hwmon: (nct6683) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (61 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 062/102] hwmon: (menf21bmc_hwmon) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 064/102] hwmon: (nct6775) " Guenter Roeck
` (38 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
nct6683 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 41082d66bfd6 ("hwmon: Driver for NCT6683D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/nct6683.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c
index 2d4117c2415c..d0ae3daaf049 100644
--- a/drivers/hwmon/nct6683.c
+++ b/drivers/hwmon/nct6683.c
@@ -338,7 +338,7 @@ struct nct6683_data {
struct mutex update_lock; /* used to protect sensor updates */
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/* Voltage attribute values */
u8 in[3][NCT6683_NUM_REG_MON]; /* [0]=in, [1]=in_max, [2]=in_min */
@@ -630,7 +630,8 @@ static struct nct6683_data *nct6683_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
/* Measured voltages and limits */
for (i = 0; i < data->in_num; i++) {
for (j = 0; j < 3; j++) {
@@ -670,7 +671,7 @@ static struct nct6683_data *nct6683_update_device(struct device *dev)
nct6683_update_pwm(dev);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 064/102] hwmon: (nct6775) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (62 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 063/102] hwmon: (nct6683) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 065/102] hwmon: (nsa320-hwmon) " Guenter Roeck
` (37 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
nct6775 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 9de2e2e84e7d ("hwmon: Driver for Nuvoton NCT6775F, NCT6776F, and NCT6779D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/nct6775-core.c | 6 +++---
drivers/hwmon/nct6775.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c
index cf27b9c7a89e..7aaa8c397b5b 100644
--- a/drivers/hwmon/nct6775-core.c
+++ b/drivers/hwmon/nct6775-core.c
@@ -1611,7 +1611,7 @@ struct nct6775_data *nct6775_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
/* Fan clock dividers */
err = nct6775_update_fan_div_common(data);
@@ -1735,7 +1735,7 @@ struct nct6775_data *nct6775_update_device(struct device *dev)
data->beeps |= ((u64)beep) << (i << 3);
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
out:
@@ -2114,7 +2114,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
if (err)
goto write_min;
/* Give the chip time to sample a new speed value */
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
}
write_min:
diff --git a/drivers/hwmon/nct6775.h b/drivers/hwmon/nct6775.h
index d18ac91be497..2c90a512d18a 100644
--- a/drivers/hwmon/nct6775.h
+++ b/drivers/hwmon/nct6775.h
@@ -93,7 +93,7 @@ struct nct6775_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/* Register values */
u8 bank; /* current register bank */
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 065/102] hwmon: (nsa320-hwmon) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (63 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 064/102] hwmon: (nct6775) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:51 ` [PATCH 066/102] hwmon: (nzxt-kraken2) Use ktime for status report validity timestamp Guenter Roeck
` (36 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
nsa320-hwmon uses 32-bit jiffies and time_after() to determine when
cached MCU sensor data should be refreshed. On 32-bit architectures, if
the sensor is not polled for about 24.8 days at HZ=1000, time_after()
wraps around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 630300d5fcb6 ("hwmon: Create an NSA320 hardware monitoring driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/nsa320-hwmon.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/nsa320-hwmon.c b/drivers/hwmon/nsa320-hwmon.c
index 5c99acc09677..e1a871b837de 100644
--- a/drivers/hwmon/nsa320-hwmon.c
+++ b/drivers/hwmon/nsa320-hwmon.c
@@ -37,7 +37,7 @@
struct nsa320_hwmon {
struct mutex update_lock; /* lock GPIO operations */
- unsigned long last_updated; /* jiffies */
+ u64 last_updated; /* jiffies */
unsigned long mcu_data;
struct gpio_desc *act;
struct gpio_desc *clk;
@@ -73,7 +73,8 @@ static s32 nsa320_hwmon_update(struct device *dev)
mcu_data = hwmon->mcu_data;
- if (time_after(jiffies, hwmon->last_updated + HZ) || mcu_data == 0) {
+ if (time_after64(get_jiffies_64(), hwmon->last_updated + HZ) ||
+ mcu_data == 0) {
gpiod_set_value(hwmon->act, 1);
msleep(100);
@@ -95,7 +96,7 @@ static s32 nsa320_hwmon_update(struct device *dev)
mcu_data = -EIO;
} else {
hwmon->mcu_data = mcu_data;
- hwmon->last_updated = jiffies;
+ hwmon->last_updated = get_jiffies_64();
}
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 066/102] hwmon: (nzxt-kraken2) Use ktime for status report validity timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (64 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 065/102] hwmon: (nsa320-hwmon) " Guenter Roeck
@ 2026-11-02 22:51 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 067/102] hwmon: (nzxt-kraken3) " Guenter Roeck
` (35 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:51 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jonas Malaco
nzxt-kraken2 uses 32-bit jiffies and time_after() to check whether the
most recent asynchronous HID status report is older than 2 seconds. On
32-bit architectures, if status reports stop arriving and the device is
not polled for about 24.8 days at HZ=1000, time_after() wraps around and
stale readings are reported instead of -ENODATA.
Convert updated to ktime_t using ktime_get(), ktime_add_ms(), and
ktime_after(), and protect sensor values and the 64-bit timestamp
between kraken2_raw_event() and kraken2_read() with a spinlock.
Fixes: 82e3430dfa8c ("hwmon: add driver for NZXT Kraken X42/X52/X62/X72")
Cc: Jonas Malaco <jonas@protocubo.io>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/nzxt-kraken2.c | 37 ++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/nzxt-kraken2.c b/drivers/hwmon/nzxt-kraken2.c
index 034698232758..79fb07bffd3f 100644
--- a/drivers/hwmon/nzxt-kraken2.c
+++ b/drivers/hwmon/nzxt-kraken2.c
@@ -12,11 +12,12 @@
#include <linux/unaligned.h>
#include <linux/hid.h>
#include <linux/hwmon.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/module.h>
+#include <linux/spinlock.h>
#define STATUS_REPORT_ID 0x04
-#define STATUS_VALIDITY 2 /* seconds; equivalent to 4 missed updates */
+#define STATUS_VALIDITY (2 * MSEC_PER_SEC) /* equivalent to 4 missed updates */
static const char *const kraken2_temp_label[] = {
"Coolant",
@@ -30,18 +31,24 @@ static const char *const kraken2_fan_label[] = {
struct kraken2_priv_data {
struct hid_device *hid_dev;
struct device *hwmon_dev;
+ spinlock_t lock; /* protects sensor values and updated */
s32 temp_input[1];
u16 fan_input[2];
- unsigned long updated; /* jiffies */
+ ktime_t updated;
};
static int kraken2_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{
struct kraken2_priv_data *priv = dev_get_drvdata(dev);
+ int ret = 0;
- if (time_after(jiffies, priv->updated + STATUS_VALIDITY * HZ))
- return -ENODATA;
+ spin_lock_irq(&priv->lock);
+
+ if (ktime_after(ktime_get(), ktime_add_ms(priv->updated, STATUS_VALIDITY))) {
+ ret = -ENODATA;
+ goto unlock;
+ }
switch (type) {
case hwmon_temp:
@@ -51,10 +58,13 @@ static int kraken2_read(struct device *dev, enum hwmon_sensor_types type,
*val = priv->fan_input[channel];
break;
default:
- return -EOPNOTSUPP; /* unreachable */
+ ret = -EOPNOTSUPP; /* unreachable */
+ break;
}
- return 0;
+unlock:
+ spin_unlock_irq(&priv->lock);
+ return ret;
}
static int kraken2_read_string(struct device *dev, enum hwmon_sensor_types type,
@@ -97,12 +107,15 @@ static int kraken2_raw_event(struct hid_device *hdev,
struct hid_report *report, u8 *data, int size)
{
struct kraken2_priv_data *priv;
+ unsigned long flags;
if (size < 7 || report->id != STATUS_REPORT_ID)
return 0;
priv = hid_get_drvdata(hdev);
+ spin_lock_irqsave(&priv->lock, flags);
+
/*
* The fractional byte of the coolant temperature has been observed to
* be in the interval [1,9], but some of these steps are also
@@ -117,7 +130,9 @@ static int kraken2_raw_event(struct hid_device *hdev,
priv->fan_input[0] = get_unaligned_be16(data + 3);
priv->fan_input[1] = get_unaligned_be16(data + 5);
- priv->updated = jiffies;
+ priv->updated = ktime_get();
+
+ spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
@@ -135,12 +150,14 @@ static int kraken2_probe(struct hid_device *hdev,
priv->hid_dev = hdev;
hid_set_drvdata(hdev, priv);
+ spin_lock_init(&priv->lock);
+
/*
- * Initialize ->updated to STATUS_VALIDITY seconds in the past, making
+ * Initialize ->updated to STATUS_VALIDITY in the past, making
* the initial empty data invalid for kraken2_read without the need for
* a special case there.
*/
- priv->updated = jiffies - STATUS_VALIDITY * HZ;
+ priv->updated = ktime_sub_ms(ktime_get(), STATUS_VALIDITY + 1);
ret = hid_parse(hdev);
if (ret) {
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 067/102] hwmon: (nzxt-kraken3) Use ktime for status report validity timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (65 preceding siblings ...)
2026-11-02 22:51 ` [PATCH 066/102] hwmon: (nzxt-kraken2) Use ktime for status report validity timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 068/102] hwmon: (occ) Use 64-bit jiffies for poll and safe-state timestamps Guenter Roeck
` (34 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Aleksa Savic, Jonas Malaco
nzxt-kraken3 uses 32-bit jiffies and time_after() with a 2000 ms
validity window to check whether status report data is stale. On 32-bit
architectures, if status reports are not updated or polled for about
24.8 days at HZ=1000, time_after() wraps around and stale readings are
treated as fresh.
Convert updated to ktime_t using ktime_get(), ktime_add_ms(), and
ktime_after(), and serialize 64-bit updated accesses using
status_completion_lock.
Fixes: f3b4b146eb10 ("hwmon: Add driver for NZXT Kraken X and Z series AIO CPU coolers")
Cc: Aleksa Savic <savicaleksa83@gmail.com>
Cc: Jonas Malaco <jonas@protocubo.io>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/nzxt-kraken3.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/nzxt-kraken3.c b/drivers/hwmon/nzxt-kraken3.c
index a185e8b27532..02703741f1e5 100644
--- a/drivers/hwmon/nzxt-kraken3.c
+++ b/drivers/hwmon/nzxt-kraken3.c
@@ -14,6 +14,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
@@ -105,7 +106,7 @@ struct kraken3_data {
* was processed after requesting one.
*/
struct completion status_report_processed;
- /* For locking the above completion */
+ /* For locking the above completion and updated timestamp */
spinlock_t status_completion_lock;
u8 *buffer;
@@ -119,7 +120,7 @@ struct kraken3_data {
enum kinds kind;
u8 firmware_version[3];
- unsigned long updated; /* jiffies */
+ ktime_t updated;
};
static umode_t kraken3_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
@@ -248,6 +249,17 @@ static int kraken3_read_x53(struct kraken3_data *priv)
return 0;
}
+static bool kraken3_is_stale(struct kraken3_data *priv)
+{
+ ktime_t updated;
+
+ spin_lock_bh(&priv->status_completion_lock);
+ updated = priv->updated;
+ spin_unlock_bh(&priv->status_completion_lock);
+
+ return ktime_after(ktime_get(), ktime_add_ms(updated, STATUS_VALIDITY));
+}
+
/* Covers Z53 and KRAKEN2023 device kinds */
static int kraken3_read_z53(struct kraken3_data *priv)
{
@@ -256,7 +268,7 @@ static int kraken3_read_z53(struct kraken3_data *priv)
if (ret < 0)
return ret;
- if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) {
+ if (!kraken3_is_stale(priv)) {
/* Data is up to date */
goto unlock_and_return;
}
@@ -294,7 +306,7 @@ static int kraken3_read(struct device *dev, enum hwmon_sensor_types type, u32 at
struct kraken3_data *priv = dev_get_drvdata(dev);
int ret;
- if (time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) {
+ if (kraken3_is_stale(priv)) {
if (priv->kind == X53)
ret = kraken3_read_x53(priv);
else
@@ -780,6 +792,7 @@ static int kraken3_raw_event(struct hid_device *hdev, struct hid_report *report,
priv->channel_info[0].reported_duty = kraken3_percent_to_pwm(data[PUMP_DUTY_OFFSET]);
spin_lock(&priv->status_completion_lock);
+ priv->updated = ktime_get();
if (priv->kind == X53 && !completion_done(&priv->status_report_processed)) {
/* Mark first X-series device report as received */
complete_all(&priv->status_report_processed);
@@ -794,8 +807,6 @@ static int kraken3_raw_event(struct hid_device *hdev, struct hid_report *report,
}
spin_unlock(&priv->status_completion_lock);
- priv->updated = jiffies;
-
return 0;
}
@@ -886,11 +897,11 @@ static int kraken3_probe(struct hid_device *hdev, const struct hid_device_id *id
hid_set_drvdata(hdev, priv);
/*
- * Initialize ->updated to STATUS_VALIDITY seconds in the past, making
+ * Initialize ->updated to STATUS_VALIDITY in the past, making
* the initial empty data invalid for kraken3_read without the need for
* a special case there.
*/
- priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY);
+ priv->updated = ktime_sub_ms(ktime_get(), STATUS_VALIDITY + 1);
ret = hid_parse(hdev);
if (ret) {
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 068/102] hwmon: (occ) Use 64-bit jiffies for poll and safe-state timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (66 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 067/102] hwmon: (nzxt-kraken3) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 069/102] hwmon: (pc87360) Use 64-bit jiffies for update timestamp Guenter Roeck
` (33 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
The OCC hwmon driver uses 32-bit jiffies and time_after() for both the
polling rate limit (next_update) and the 60-second safe-state timeout
(last_safe). On 32-bit architectures, if the device is not polled for
about 24.8 days at HZ=1000, time_after() wraps around and sensor polling
or safe-state timeout detection stops working.
Switch next_update and last_safe to u64 and use get_jiffies_64() with
time_after64() to avoid wrap-around issues on 32-bit systems.
Fixes: c10e753d43eb ("hwmon (occ): Add sensor types and versions")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/occ/common.c | 12 ++++++------
drivers/hwmon/occ/common.h | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c
index 175208d712b0..67e8dd1c77fa 100644
--- a/drivers/hwmon/occ/common.c
+++ b/drivers/hwmon/occ/common.c
@@ -164,11 +164,11 @@ static int occ_poll(struct occ *occ)
header = (struct occ_poll_response_header *)occ->resp.data;
if (header->occ_state == OCC_STATE_SAFE) {
if (occ->last_safe) {
- if (time_after(jiffies,
- occ->last_safe + OCC_SAFE_TIMEOUT))
+ if (time_after64(get_jiffies_64(),
+ occ->last_safe + OCC_SAFE_TIMEOUT))
occ->error = -EHOSTDOWN;
} else {
- occ->last_safe = jiffies;
+ occ->last_safe = get_jiffies_64();
}
} else {
occ->last_safe = 0;
@@ -220,9 +220,9 @@ int occ_update_response(struct occ *occ)
}
/* limit the maximum rate of polling the OCC */
- if (time_after(jiffies, occ->next_update)) {
+ if (time_after64(get_jiffies_64(), occ->next_update)) {
rc = occ_poll(occ);
- occ->next_update = jiffies + OCC_UPDATE_FREQUENCY;
+ occ->next_update = get_jiffies_64() + OCC_UPDATE_FREQUENCY;
} else {
rc = occ->last_error;
}
@@ -1158,7 +1158,7 @@ int occ_active(struct occ *occ, bool active)
goto unlock;
}
- occ->next_update = jiffies + OCC_UPDATE_FREQUENCY;
+ occ->next_update = get_jiffies_64() + OCC_UPDATE_FREQUENCY;
rc = occ_parse_poll_response(occ);
if (rc)
goto unlock;
diff --git a/drivers/hwmon/occ/common.h b/drivers/hwmon/occ/common.h
index 82f600093c7f..d968c42cd122 100644
--- a/drivers/hwmon/occ/common.h
+++ b/drivers/hwmon/occ/common.h
@@ -99,7 +99,7 @@ struct occ {
int (*send_cmd)(struct occ *occ, u8 *cmd, size_t len, void *resp,
size_t resp_len);
- unsigned long next_update;
+ u64 next_update;
struct mutex lock; /* lock OCC access */
struct mutex hwmon_lock; /* serialize hwmon registration/removal */
@@ -112,7 +112,7 @@ struct occ {
int error; /* final transfer error after retry */
int last_error; /* latest transfer error */
unsigned int error_count; /* number of xfr errors observed */
- unsigned long last_safe; /* time OCC entered "safe" state */
+ u64 last_safe; /* time OCC entered "safe" state */
/*
* Store the previous state data for comparison in order to notify
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 069/102] hwmon: (pc87360) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (67 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 068/102] hwmon: (occ) Use 64-bit jiffies for poll and safe-state timestamps Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 070/102] hwmon: (pc87427) " Guenter Roeck
` (32 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jim Cromie
pc87360 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: Jim Cromie <jim.cromie@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/pc87360.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 0f8aa6b42164..d2702d409d0d 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -191,7 +191,7 @@ struct pc87360_data {
struct mutex lock;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
int address[3];
@@ -296,7 +296,8 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ * 2) ||
+ !data->valid) {
dev_dbg(dev, "Data update\n");
/* Fans */
@@ -394,7 +395,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
& 0x3F;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 070/102] hwmon: (pc87427) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (68 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 069/102] hwmon: (pc87360) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 071/102] hwmon: (peci) Use 64-bit jiffies for sensor update timestamps Guenter Roeck
` (31 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
pc87427 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: ba224e2c4f0a ("hwmon: New PC87427 hardware monitoring driver")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/pc87427.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 571402a89368..28ceee620d36 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -49,7 +49,7 @@ struct pc87427_data {
int address[2];
const char *name;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
u8 fan_enabled; /* bit vector */
u16 fan[8]; /* register values */
u16 fan_min[8]; /* register values */
@@ -352,8 +352,8 @@ static struct pc87427_data *pc87427_update_device(struct device *dev)
int i;
mutex_lock(&data->lock);
- if (!time_after(jiffies, data->last_updated + HZ)
- && data->last_updated)
+ if (!time_after64(get_jiffies_64(), data->last_updated + HZ) &&
+ data->last_updated)
goto done;
/* Fans */
@@ -377,7 +377,7 @@ static struct pc87427_data *pc87427_update_device(struct device *dev)
pc87427_readall_temp(data, i);
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
done:
mutex_unlock(&data->lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 071/102] hwmon: (peci) Use 64-bit jiffies for sensor update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (69 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 070/102] hwmon: (pc87427) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 072/102] hwmon: (powr1220) Use 64-bit jiffies for ADC " Guenter Roeck
` (30 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Iwona Winiarska
The PECI hwmon drivers (cputemp and dimmtemp) use 32-bit jiffies and
time_after() in struct peci_sensor_state to determine when cached sensor
readings should be refreshed. On 32-bit architectures, if a sensor is
not polled for about 24.8 days at HZ=1000, time_after() wraps around and
cached values stop updating.
Switch last_updated in struct peci_sensor_state to u64 and use
get_jiffies_64() with time_after64() to avoid wrap-around issues on
32-bit systems.
Fixes: bf3608f338e9 ("hwmon: peci: Add cputemp driver")
Cc: Iwona Winiarska <iwona.winiarska@intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/peci/common.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/peci/common.h b/drivers/hwmon/peci/common.h
index 5eae9681e385..5495907ab46d 100644
--- a/drivers/hwmon/peci/common.h
+++ b/drivers/hwmon/peci/common.h
@@ -1,11 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2021 Intel Corporation */
-#include <linux/types.h>
-
#ifndef __PECI_HWMON_COMMON_H
#define __PECI_HWMON_COMMON_H
+#include <linux/jiffies.h>
+#include <linux/types.h>
+
#define PECI_HWMON_UPDATE_INTERVAL HZ
/**
@@ -15,7 +16,7 @@
*/
struct peci_sensor_state {
bool valid;
- unsigned long last_updated;
+ u64 last_updated;
};
/**
@@ -39,7 +40,8 @@ struct peci_sensor_data {
static inline bool peci_sensor_need_update(struct peci_sensor_state *state)
{
return !state->valid ||
- time_after(jiffies, state->last_updated + PECI_HWMON_UPDATE_INTERVAL);
+ time_after64(get_jiffies_64(),
+ state->last_updated + PECI_HWMON_UPDATE_INTERVAL);
}
/**
@@ -49,7 +51,7 @@ static inline bool peci_sensor_need_update(struct peci_sensor_state *state)
static inline void peci_sensor_mark_updated(struct peci_sensor_state *state)
{
state->valid = true;
- state->last_updated = jiffies;
+ state->last_updated = get_jiffies_64();
}
#endif /* __PECI_HWMON_COMMON_H */
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 072/102] hwmon: (powr1220) Use 64-bit jiffies for ADC update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (70 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 071/102] hwmon: (peci) Use 64-bit jiffies for sensor update timestamps Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 073/102] hwmon: (sch5627) Use 64-bit jiffies for " Guenter Roeck
` (29 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
powr1220 uses 32-bit jiffies and time_after() to determine when per-ADC
channel readings should be refreshed. On 32-bit architectures, if an ADC
channel is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached readings stop updating.
Switch adc_last_updated[] to u64 and use get_jiffies_64() with
time_after64() to avoid wrap-around issues on 32-bit systems.
Fixes: f4ff415564cb ("hwmon: Add support for Lattice's POWR1220 power manager IC")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/powr1220.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/powr1220.c b/drivers/hwmon/powr1220.c
index 6e211601ea26..4a4a2f3b5b87 100644
--- a/drivers/hwmon/powr1220.c
+++ b/drivers/hwmon/powr1220.c
@@ -77,7 +77,7 @@ struct powr1220_data {
u8 max_channels;
bool adc_valid[MAX_POWR1220_ADC_VALUES];
/* the next value is in jiffies */
- unsigned long adc_last_updated[MAX_POWR1220_ADC_VALUES];
+ u64 adc_last_updated[MAX_POWR1220_ADC_VALUES];
/* values */
int adc_maxes[MAX_POWR1220_ADC_VALUES];
@@ -109,7 +109,7 @@ static int powr1220_read_adc(struct device *dev, int ch_num)
int result;
int adc_range = 0;
- if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) ||
+ if (time_after64(get_jiffies_64(), data->adc_last_updated[ch_num] + HZ) ||
!data->adc_valid[ch_num]) {
/*
* figure out if we need to use the attenuator for
@@ -151,7 +151,7 @@ static int powr1220_read_adc(struct device *dev, int ch_num)
reading *= ADC_STEP_MV;
data->adc_values[ch_num] = reading;
data->adc_valid[ch_num] = true;
- data->adc_last_updated[ch_num] = jiffies;
+ data->adc_last_updated[ch_num] = get_jiffies_64();
result = reading;
if (reading > data->adc_maxes[ch_num])
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 073/102] hwmon: (sch5627) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (71 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 072/102] hwmon: (powr1220) Use 64-bit jiffies for ADC " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 074/102] hwmon: (sch5636) Use 64-bit jiffies for update timestamp Guenter Roeck
` (28 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Hans de Goede
sch5627 uses 32-bit jiffies and time_after() for temperature, fan,
voltage, and 5-minute Vbat measurement timestamps. On 32-bit
architectures, if a sensor is not polled for about 24.8 days at HZ=1000,
time_after() wraps around and cached readings or periodic Vbat
measurements stop updating.
Switch last_battery, temp_last_updated, fan_last_updated, and
in_last_updated to u64 and use get_jiffies_64() with time_after64() to
avoid wrap-around issues on 32-bit systems.
Fixes: a98d506c08ff ("hwmon: New driver for SMSC SCH5627")
Cc: Hans de Goede <hansg@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/sch5627.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c
index 04e701ce2e74..5dfd34c469da 100644
--- a/drivers/hwmon/sch5627.c
+++ b/drivers/hwmon/sch5627.c
@@ -79,13 +79,13 @@ struct sch5627_data {
u8 control;
struct mutex update_lock;
- unsigned long last_battery; /* In jiffies */
+ u64 last_battery; /* In jiffies */
char temp_valid; /* !=0 if following fields are valid */
char fan_valid;
char in_valid;
- unsigned long temp_last_updated; /* In jiffies */
- unsigned long fan_last_updated;
- unsigned long in_last_updated;
+ u64 temp_last_updated; /* In jiffies */
+ u64 fan_last_updated;
+ u64 in_last_updated;
u16 temp[SCH5627_NO_TEMPS];
u16 fan[SCH5627_NO_FANS];
u16 in[SCH5627_NO_IN];
@@ -129,7 +129,7 @@ static int sch5627_update_temp(struct sch5627_data *data)
mutex_lock(&data->update_lock);
/* Cache the values for 1 second */
- if (time_after(jiffies, data->temp_last_updated + HZ) || !data->temp_valid) {
+ if (time_after64(get_jiffies_64(), data->temp_last_updated + HZ) || !data->temp_valid) {
for (i = 0; i < SCH5627_NO_TEMPS; i++) {
val = sch56xx_read_virtual_reg12(data->addr, SCH5627_REG_TEMP_MSB[i],
SCH5627_REG_TEMP_LSN[i],
@@ -140,7 +140,7 @@ static int sch5627_update_temp(struct sch5627_data *data)
}
data->temp[i] = val;
}
- data->temp_last_updated = jiffies;
+ data->temp_last_updated = get_jiffies_64();
data->temp_valid = 1;
}
abort:
@@ -156,7 +156,7 @@ static int sch5627_update_fan(struct sch5627_data *data)
mutex_lock(&data->update_lock);
/* Cache the values for 1 second */
- if (time_after(jiffies, data->fan_last_updated + HZ) || !data->fan_valid) {
+ if (time_after64(get_jiffies_64(), data->fan_last_updated + HZ) || !data->fan_valid) {
for (i = 0; i < SCH5627_NO_FANS; i++) {
val = sch56xx_read_virtual_reg16(data->addr, SCH5627_REG_FAN[i]);
if (unlikely(val < 0)) {
@@ -165,7 +165,7 @@ static int sch5627_update_fan(struct sch5627_data *data)
}
data->fan[i] = val;
}
- data->fan_last_updated = jiffies;
+ data->fan_last_updated = get_jiffies_64();
data->fan_valid = 1;
}
abort:
@@ -181,14 +181,14 @@ static int sch5627_update_in(struct sch5627_data *data)
mutex_lock(&data->update_lock);
/* Trigger a Vbat voltage measurement every 5 minutes */
- if (time_after(jiffies, data->last_battery + 300 * HZ)) {
+ if (time_after64(get_jiffies_64(), data->last_battery + 300 * HZ)) {
sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,
data->control | SCH5627_CTRL_VBAT);
- data->last_battery = jiffies;
+ data->last_battery = get_jiffies_64();
}
/* Cache the values for 1 second */
- if (time_after(jiffies, data->in_last_updated + HZ) || !data->in_valid) {
+ if (time_after64(get_jiffies_64(), data->in_last_updated + HZ) || !data->in_valid) {
for (i = 0; i < SCH5627_NO_IN; i++) {
val = sch56xx_read_virtual_reg12(data->addr, SCH5627_REG_IN_MSB[i],
SCH5627_REG_IN_LSN[i],
@@ -199,7 +199,7 @@ static int sch5627_update_in(struct sch5627_data *data)
}
data->in[i] = val;
}
- data->in_last_updated = jiffies;
+ data->in_last_updated = get_jiffies_64();
data->in_valid = 1;
}
abort:
@@ -594,7 +594,7 @@ static int sch5627_probe(struct platform_device *pdev)
/* Trigger a Vbat voltage measurement, so that we get a valid reading
the first time we read Vbat */
sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | SCH5627_CTRL_VBAT);
- data->last_battery = jiffies;
+ data->last_battery = get_jiffies_64();
pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);
pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 074/102] hwmon: (sch5636) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (72 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 073/102] hwmon: (sch5627) Use 64-bit jiffies for " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 075/102] hwmon: (sht15) Use 64-bit jiffies for status and measurement timestamps Guenter Roeck
` (27 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
sch5636 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 0772a6407939 ("hwmon: New driver sch5636")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/sch5636.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c
index 8c9b6e24d09f..2aaca407be7b 100644
--- a/drivers/hwmon/sch5636.c
+++ b/drivers/hwmon/sch5636.c
@@ -57,7 +57,7 @@ struct sch5636_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[SCH5636_NO_INS];
u8 temp_val[SCH5636_NO_TEMPS];
u8 temp_ctrl[SCH5636_NO_TEMPS];
@@ -74,7 +74,8 @@ static struct sch5636_data *sch5636_update_device(struct device *dev)
mutex_lock(&data->update_lock);
/* Cache the values for 1 second */
- if (data->valid && !time_after(jiffies, data->last_updated + HZ))
+ if (data->valid &&
+ !time_after64(get_jiffies_64(), data->last_updated + HZ))
goto abort;
for (i = 0; i < SCH5636_NO_INS; i++) {
@@ -139,7 +140,7 @@ static struct sch5636_data *sch5636_update_device(struct device *dev)
}
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
abort:
mutex_unlock(&data->update_lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 075/102] hwmon: (sht15) Use 64-bit jiffies for status and measurement timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (73 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 074/102] hwmon: (sch5636) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 076/102] hwmon: (sht21) Use ktime for measurement update timestamp Guenter Roeck
` (26 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
sht15 uses 32-bit jiffies and time_after() for both status register and
sensor measurement caching. On 32-bit architectures, if the sensor is
not polled for about 24.8 days at HZ=1000, time_after() wraps around and
cached values stop updating.
Switch last_measurement and last_status to u64 and use get_jiffies_64()
with time_after64() to avoid wrap-around issues on 32-bit systems.
Fixes: 251eb40f5ccd ("hwmon: sht15 humidity sensor driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/sht15.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 48d93c61345c..395d8ab88c2e 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -160,8 +160,8 @@ struct sht15_data {
enum sht15_state state;
bool measurements_valid;
bool status_valid;
- unsigned long last_measurement;
- unsigned long last_status;
+ u64 last_measurement;
+ u64 last_status;
struct mutex read_lock;
struct device *dev;
struct device *hwmon_dev;
@@ -457,8 +457,8 @@ static int sht15_update_status(struct sht15_data *data)
int timeout = HZ;
mutex_lock(&data->read_lock);
- if (time_after(jiffies, data->last_status + timeout)
- || !data->status_valid) {
+ if (time_after64(get_jiffies_64(), data->last_status + timeout) ||
+ !data->status_valid) {
ret = sht15_send_cmd(data, SHT15_READ_STATUS);
if (ret)
goto unlock;
@@ -502,7 +502,7 @@ static int sht15_update_status(struct sht15_data *data)
data->val_status = status;
data->status_valid = true;
- data->last_status = jiffies;
+ data->last_status = get_jiffies_64();
}
unlock:
@@ -589,8 +589,8 @@ static int sht15_update_measurements(struct sht15_data *data)
int timeout = HZ;
mutex_lock(&data->read_lock);
- if (time_after(jiffies, data->last_measurement + timeout)
- || !data->measurements_valid) {
+ if (time_after64(get_jiffies_64(), data->last_measurement + timeout) ||
+ !data->measurements_valid) {
data->state = SHT15_READING_HUMID;
ret = sht15_measurement(data, SHT15_MEASURE_RH, 160);
if (ret)
@@ -600,7 +600,7 @@ static int sht15_update_measurements(struct sht15_data *data)
if (ret)
goto unlock;
data->measurements_valid = true;
- data->last_measurement = jiffies;
+ data->last_measurement = get_jiffies_64();
}
unlock:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 076/102] hwmon: (sht21) Use ktime for measurement update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (74 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 075/102] hwmon: (sht15) Use 64-bit jiffies for status and measurement timestamps Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 077/102] hwmon: (sht3x) Use ktime for periodic mode " Guenter Roeck
` (25 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
sht21 uses 32-bit jiffies and time_after() with a 500 ms (HZ / 2)
interval to rate-limit sensor measurements. On 32-bit architectures, if
the sensor is not polled for about 24.8 days at HZ=1000, time_after()
wraps around and cached values stop updating.
Convert last_update to ktime_t with a 500 ms interval using ktime_get(),
ktime_add_ms(), and ktime_after().
Fixes: 430400b86304 ("hwmon: driver for Sensirion SHT21 humidity and temperature sensor")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/sht21.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index 085492669eeb..d0864b5f219d 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -15,7 +15,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/device.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
/* I2C command bytes */
#define SHT21_TRIG_T_MEASUREMENT_HM 0xe3
@@ -29,7 +29,7 @@
* struct sht21 - SHT21 device specific data
* @client: I2C client device
* @lock: mutex to protect measurement values
- * @last_update: time of last update (jiffies)
+ * @last_update: time of last update
* @temperature: cached temperature measurement value
* @humidity: cached humidity measurement value
* @valid: only 0 before first measurement is taken
@@ -38,7 +38,7 @@
struct sht21 {
struct i2c_client *client;
struct mutex lock;
- unsigned long last_update;
+ ktime_t last_update;
int temperature;
int humidity;
bool valid;
@@ -93,7 +93,8 @@ static int sht21_update_measurements(struct device *dev)
* SHT2x should not be active for more than 10% of the time - e.g.
* maximum two measurements per second at 12bit accuracy shall be made.
*/
- if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) {
+ if (!sht21->valid ||
+ ktime_after(ktime_get(), ktime_add_ms(sht21->last_update, 500))) {
ret = i2c_smbus_read_word_swapped(client,
SHT21_TRIG_T_MEASUREMENT_HM);
if (ret < 0)
@@ -104,7 +105,7 @@ static int sht21_update_measurements(struct device *dev)
if (ret < 0)
goto out;
sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret);
- sht21->last_update = jiffies;
+ sht21->last_update = ktime_get();
sht21->valid = true;
}
out:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 077/102] hwmon: (sht3x) Use ktime for periodic mode update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (75 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 076/102] hwmon: (sht21) Use ktime for measurement update timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 078/102] hwmon: (sht4x) Use 64-bit jiffies for poll timestamp Guenter Roeck
` (24 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
sht3x uses 32-bit jiffies and time_after() with millisecond intervals
converted via msecs_to_jiffies() to rate-limit reads in periodic mode.
On 32-bit architectures, if the sensor is not polled for about 24.8 days
at HZ=1000, time_after() wraps around and cached values stop updating.
Since mode_to_update_interval[] already stores intervals in
milliseconds, convert last_update to ktime_t using ktime_get(),
ktime_add_ms(), and ktime_after().
Fixes: 7c84f7f80d6f ("hwmon: add support for Sensirion SHT3x sensors")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/sht3x.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c
index a0f5ba5c888d..216f3a4e6ccf 100644
--- a/drivers/hwmon/sht3x.c
+++ b/drivers/hwmon/sht3x.c
@@ -18,9 +18,9 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/jiffies.h>
#include <linux/unaligned.h>
/* commands (high repeatability mode) */
@@ -170,7 +170,7 @@ struct sht3x_data {
u8 mode;
const unsigned char *command;
u32 wait_time; /* in us*/
- unsigned long last_update; /* last update in periodic mode*/
+ ktime_t last_update; /* last update in periodic mode */
enum sht3x_repeatability repeatability;
u32 serial_number;
@@ -257,7 +257,6 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
struct sht3x_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
u16 interval_ms = mode_to_update_interval[data->mode];
- unsigned long interval_jiffies = msecs_to_jiffies(interval_ms);
unsigned char buf[SHT3X_RESPONSE_LENGTH];
u16 val;
int ret = 0;
@@ -271,7 +270,9 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
* internally by the sensor and reading out sensor values only makes
* sense if a new reading is available.
*/
- if (time_after(jiffies, data->last_update + interval_jiffies)) {
+ if (interval_ms == 0 ||
+ ktime_after(ktime_get(),
+ ktime_add_ms(data->last_update, interval_ms))) {
ret = sht3x_read_from_command(client, data, data->command, buf,
sizeof(buf), data->wait_time);
if (ret)
@@ -281,7 +282,7 @@ static struct sht3x_data *sht3x_update_client(struct device *dev)
data->temperature = sht3x_extract_temperature(val);
val = get_unaligned_be16(buf + 3);
data->humidity = sht3x_extract_humidity(val);
- data->last_update = jiffies;
+ data->last_update = ktime_get();
}
out:
@@ -902,7 +903,7 @@ static int sht3x_probe(struct i2c_client *client)
data->repeatability = high_repeatability;
data->mode = 0;
- data->last_update = jiffies - msecs_to_jiffies(3000);
+ data->last_update = ktime_sub_ms(ktime_get(), 3000);
data->client = client;
data->chip_id = (uintptr_t)i2c_get_match_data(client);
crc8_populate_msb(sht3x_crc8_table, SHT3X_CRC8_POLYNOMIAL);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 078/102] hwmon: (sht4x) Use 64-bit jiffies for poll timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (76 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 077/102] hwmon: (sht3x) Use ktime for periodic mode " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 079/102] hwmon: (shtc1) Use ktime for measurement update timestamp Guenter Roeck
` (23 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
sht4x already uses u64 jiffies and time_before64() for heating_complete,
but stores last_updated as signed long and compares next_update using
32-bit time_before_eq(jiffies, ...). On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_before_eq()
wraps around and cached values stop updating.
Switch last_updated and next_update to u64 and use get_jiffies_64() with
time_before_eq64() to match heating_complete and avoid 32-bit wrap-around.
Fixes: 505c2549373f ("hwmon: Add sht4x Temperature and Humidity Sensor Driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/sht4x.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c
index 020a523bf863..009c4c2a63a5 100644
--- a/drivers/hwmon/sht4x.c
+++ b/drivers/hwmon/sht4x.c
@@ -81,7 +81,7 @@ struct sht4x_data {
u32 heater_time; /* in milli-seconds */
bool valid; /* validity of fields below */
long update_interval; /* in milli-seconds */
- long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
s32 temperature;
s32 humidity;
};
@@ -95,7 +95,7 @@ static int sht4x_read_values(struct sht4x_data *data)
{
int ret;
u16 t_ticks, rh_ticks;
- unsigned long next_update;
+ u64 next_update;
struct i2c_client *client = data->client;
u8 crc;
u8 cmd[SHT4X_CMD_LEN] = {SHT4X_CMD_MEASURE_HPM};
@@ -119,7 +119,7 @@ static int sht4x_read_values(struct sht4x_data *data)
next_update = data->last_updated +
msecs_to_jiffies(data->update_interval);
- if (data->valid && time_before_eq(jiffies, next_update))
+ if (data->valid && time_before_eq64(get_jiffies_64(), next_update))
return 0;
ret = i2c_master_send(client, cmd, SHT4X_CMD_LEN);
@@ -157,7 +157,7 @@ static int sht4x_read_values(struct sht4x_data *data)
data->humidity = ((15625 * (int32_t)rh_ticks) >> 13) - 6000;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
return 0;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 079/102] hwmon: (shtc1) Use ktime for measurement update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (77 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 078/102] hwmon: (sht4x) Use 64-bit jiffies for poll timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 080/102] hwmon: (sis5595) Use 64-bit jiffies for " Guenter Roeck
` (22 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
shtc1 uses 32-bit jiffies and time_after() with a 100 ms (HZ / 10)
interval to cache measurements. On 32-bit architectures, if the sensor
is not polled for about 24.8 days at HZ=1000, time_after() wraps around
and cached values stop updating.
Convert last_updated to ktime_t with a 100 ms interval using
ktime_get(), ktime_add_ms(), and ktime_after().
Fixes: 1a539d372edd ("hwmon: add support for Sensirion SHTC1 sensor")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/shtc1.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/shtc1.c b/drivers/hwmon/shtc1.c
index 362a73cf661b..83dd24fdd0da 100644
--- a/drivers/hwmon/shtc1.c
+++ b/drivers/hwmon/shtc1.c
@@ -13,6 +13,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/delay.h>
+#include <linux/ktime.h>
#include <linux/platform_data/shtc1.h>
#include <linux/of.h>
@@ -56,7 +57,7 @@ struct shtc1_data {
struct i2c_client *client;
struct mutex update_lock;
bool valid;
- unsigned long last_updated; /* in jiffies */
+ ktime_t last_updated;
const unsigned char *command;
unsigned int nonblocking_wait_time; /* in us */
@@ -108,7 +109,8 @@ static struct shtc1_data *shtc1_update_client(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) {
+ if (!data->valid ||
+ ktime_after(ktime_get(), ktime_add_ms(data->last_updated, 100))) {
ret = shtc1_update_values(client, data, buf, sizeof(buf));
if (ret)
goto out;
@@ -125,7 +127,7 @@ static struct shtc1_data *shtc1_update_client(struct device *dev)
val = be16_to_cpup((__be16 *)(buf + 3));
data->humidity = ((12500 * val) >> 13);
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 080/102] hwmon: (sis5595) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (78 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 079/102] hwmon: (shtc1) Use ktime for measurement update timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 081/102] hwmon: (smsc47b397) " Guenter Roeck
` (21 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
sis5595 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/sis5595.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index b7a7bcd6d3af..b66e8f47df90 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -170,7 +170,7 @@ struct sis5595_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
char maxins; /* == 3 if temp enabled, otherwise == 4 */
u8 revision; /* Reg. value */
@@ -215,7 +215,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
for (i = 0; i <= data->maxins; i++) {
@@ -249,7 +249,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev)
data->alarms =
sis5595_read_value(data, SIS5595_REG_ALARM1) |
(sis5595_read_value(data, SIS5595_REG_ALARM2) << 8);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 081/102] hwmon: (smsc47b397) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (79 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 080/102] hwmon: (sis5595) Use 64-bit jiffies for " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 082/102] hwmon: (smsc47m1) " Guenter Roeck
` (20 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
smsc47b397 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/smsc47b397.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index c26d6eae0e4e..6096ba255183 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -95,7 +95,7 @@ struct smsc47b397_data {
struct mutex lock;
struct mutex update_lock;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
bool valid;
/* register values */
@@ -121,7 +121,8 @@ static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
dev_dbg(dev, "starting device update...\n");
/* 4 temperature inputs, 4 fan inputs */
@@ -136,7 +137,7 @@ static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
SMSC47B397_REG_FAN_MSB(i)) << 8;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
dev_dbg(dev, "... device update complete\n");
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 082/102] hwmon: (smsc47m1) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (80 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 081/102] hwmon: (smsc47b397) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 083/102] hwmon: (smsc47m192) " Guenter Roeck
` (19 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
smsc47m1 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/smsc47m1.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 595bceb78d76..5502da2d8f8e 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -120,7 +120,7 @@ struct smsc47m1_data {
struct device *hwmon_dev;
struct mutex update_lock;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 fan[3]; /* Register value */
u8 fan_preload[3]; /* Register value */
@@ -152,7 +152,8 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ init) {
int i, fan_nr;
fan_nr = data->type == smsc47m2 ? 3 : 2;
@@ -187,7 +188,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
0x40);
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
}
mutex_unlock(&data->update_lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 083/102] hwmon: (smsc47m192) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (81 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 082/102] hwmon: (smsc47m1) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 084/102] hwmon: (stts751) Use ktime for temperature and alert cache timestamps Guenter Roeck
` (18 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
smsc47m192 uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 59ac83677f72 ("[PATCH] smsc47m192: New hwmon driver for SMSC LPC47M192/997")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/smsc47m192.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c
index 1429b66e09b0..00acce370913 100644
--- a/drivers/hwmon/smsc47m192.c
+++ b/drivers/hwmon/smsc47m192.c
@@ -87,7 +87,7 @@ struct smsc47m192_data {
const struct attribute_group *groups[3];
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[8]; /* Register value */
u8 in_max[8]; /* Register value */
@@ -109,8 +109,8 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
dev_dbg(&client->dev, "Starting smsc47m192 update\n");
@@ -156,7 +156,7 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
(i2c_smbus_read_byte_data(client,
SMSC47M192_REG_ALARM2) << 8);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 084/102] hwmon: (stts751) Use ktime for temperature and alert cache timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (82 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 083/102] hwmon: (smsc47m192) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 085/102] hwmon: (tc654) Use 64-bit jiffies for update timestamp Guenter Roeck
` (17 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
stts751 uses 32-bit jiffies and time_after() with millisecond intervals
converted via msecs_to_jiffies() to cache temperature and alert status
readings. On 32-bit architectures, if the sensor is not polled for about
24.8 days at HZ=1000, time_after() wraps around and cached values stop
updating.
Since stts751_intervals[] already stores intervals in milliseconds (down
to 31 ms, where adding a 10% alert margin also suffers from coarse
jiffies rounding at low HZ), convert last_update and last_alert_update
to ktime_t using ktime_get(), ktime_add_ms(), ktime_add_us(), and
ktime_after().
Fixes: 7f07ec0fa17a ("hwmon: new driver for ST stts751 thermal sensor")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/stts751.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/hwmon/stts751.c b/drivers/hwmon/stts751.c
index ce23681f7981..e90168dbc497 100644
--- a/drivers/hwmon/stts751.c
+++ b/drivers/hwmon/stts751.c
@@ -18,7 +18,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/property.h>
@@ -92,7 +92,7 @@ struct stts751_priv {
int therm;
int hyst;
int temp;
- unsigned long last_update, last_alert_update;
+ ktime_t last_update, last_alert_update;
u8 config;
bool min_alert, max_alert, therm_trip;
bool data_valid, alert_valid;
@@ -260,13 +260,13 @@ static int stts751_update_alert(struct stts751_priv *priv)
{
int ret;
bool conv_done;
- int cache_time = msecs_to_jiffies(stts751_intervals[priv->interval]);
+ int cache_time_us = stts751_intervals[priv->interval] * USEC_PER_MSEC;
/*
* Add another 10% because if we run faster than the HW conversion
* rate we will end up in reporting incorrectly alarms.
*/
- cache_time += cache_time / 10;
+ cache_time_us += cache_time_us / 10;
ret = i2c_smbus_read_byte_data(priv->client, STTS751_REG_STATUS);
if (ret < 0)
@@ -286,12 +286,13 @@ static int stts751_update_alert(struct stts751_priv *priv)
* Note that updating the cache timestamp when we get an alarm flag
* is required, otherwise we could incorrectly report alarms to be zero.
*/
- if (time_after(jiffies, priv->last_alert_update + cache_time) ||
- conv_done || !priv->alert_valid) {
+ if (conv_done || !priv->alert_valid ||
+ ktime_after(ktime_get(),
+ ktime_add_us(priv->last_alert_update, cache_time_us))) {
priv->max_alert = false;
priv->min_alert = false;
priv->alert_valid = true;
- priv->last_alert_update = jiffies;
+ priv->last_alert_update = ktime_get();
dev_dbg(&priv->client->dev, "invalidating alert cache\n");
}
@@ -354,10 +355,11 @@ static void stts751_alert(struct i2c_client *client,
static int stts751_update(struct stts751_priv *priv)
{
int ret;
- int cache_time = msecs_to_jiffies(stts751_intervals[priv->interval]);
+ int cache_time_ms = stts751_intervals[priv->interval];
- if (time_after(jiffies, priv->last_update + cache_time) ||
- !priv->data_valid) {
+ if (!priv->data_valid ||
+ ktime_after(ktime_get(),
+ ktime_add_ms(priv->last_update, cache_time_ms))) {
ret = stts751_update_temp(priv);
if (ret)
return ret;
@@ -366,7 +368,7 @@ static int stts751_update(struct stts751_priv *priv)
if (ret)
return ret;
priv->data_valid = true;
- priv->last_update = jiffies;
+ priv->last_update = ktime_get();
}
return 0;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 085/102] hwmon: (tc654) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (83 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 084/102] hwmon: (stts751) Use ktime for temperature and alert cache timestamps Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 086/102] hwmon: (tc74) Use ktime for temperature cache timestamp Guenter Roeck
` (16 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
tc654 uses 32-bit jiffies and time_before() to determine whether cached
register values are still fresh. On 32-bit architectures, if the sensor
is not polled for about 24.8 days at HZ=1000, time_before() wraps around
and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_before64()
to avoid wrap-around issues on 32-bit systems.
Fixes: aaf6fabf1be8 ("hwmon: Add tc654 driver")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/tc654.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/tc654.c b/drivers/hwmon/tc654.c
index 4af9f0e2c0bc..b7c3b702db2a 100644
--- a/drivers/hwmon/tc654.c
+++ b/drivers/hwmon/tc654.c
@@ -64,7 +64,7 @@ struct tc654_data {
/* tc654 register cache */
bool valid;
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
u8 rpm_output[2]; /* The fan RPM data for fans 1 and 2 is then
* written to registers RPM1 and RPM2
@@ -138,7 +138,8 @@ static struct tc654_data *tc654_update_client(struct device *dev)
int ret = 0;
mutex_lock(&data->update_lock);
- if (time_before(jiffies, data->last_updated + TC654_UPDATE_INTERVAL) &&
+ if (time_before64(get_jiffies_64(),
+ data->last_updated + TC654_UPDATE_INTERVAL) &&
likely(data->valid))
goto out;
@@ -177,7 +178,7 @@ static struct tc654_data *tc654_update_client(struct device *dev)
goto out;
data->duty_cycle = ret & 0x0f;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
out:
mutex_unlock(&data->update_lock);
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 086/102] hwmon: (tc74) Use ktime for temperature cache timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (84 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 085/102] hwmon: (tc654) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 087/102] hwmon: (thmc50) Use ktime for register " Guenter Roeck
` (15 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
tc74 uses 32-bit jiffies and time_after() with a 250 ms (HZ / 4)
interval to cache temperature readings. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Convert next_update to ktime_t with a 250 ms interval using ktime_get(),
ktime_add_ms(), and ktime_after().
Fixes: 761c1770f2bf ("hwmon: add driver for Microchip TC74")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/tc74.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/tc74.c b/drivers/hwmon/tc74.c
index e9113519be53..d997dfa45269 100644
--- a/drivers/hwmon/tc74.c
+++ b/drivers/hwmon/tc74.c
@@ -15,7 +15,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/i2c.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
@@ -29,7 +29,7 @@ struct tc74_data {
struct i2c_client *client;
struct mutex lock; /* atomic read data updates */
bool valid; /* validity of fields below */
- unsigned long next_update; /* In jiffies */
+ ktime_t next_update; /* Next update time */
s8 temp_input; /* Temp value in dC */
};
@@ -43,7 +43,7 @@ static int tc74_update_device(struct device *dev)
if (ret)
return ret;
- if (time_after(jiffies, data->next_update) || !data->valid) {
+ if (!data->valid || ktime_after(ktime_get(), data->next_update)) {
s32 value;
value = i2c_smbus_read_byte_data(client, TC74_REG_CONFIG);
@@ -72,7 +72,7 @@ static int tc74_update_device(struct device *dev)
}
data->temp_input = value;
- data->next_update = jiffies + HZ / 4;
+ data->next_update = ktime_add_ms(ktime_get(), 250);
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 087/102] hwmon: (thmc50) Use ktime for register cache timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (85 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 086/102] hwmon: (tc74) Use ktime for temperature cache timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 088/102] hwmon: (tmp421) Use ktime for temperature " Guenter Roeck
` (14 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
thmc50 uses 32-bit jiffies and time_after() with a 200 ms (ADM1022) or
1200 ms (THMC50) timeout to cache register values. On 32-bit
architectures, if the sensor is not polled for about 24.8 days at
HZ=1000, time_after() wraps around and cached values stop updating.
Convert last_updated to ktime_t with 200 ms / 1200 ms intervals using
ktime_get(), ktime_add_ms(), and ktime_after().
Fixes: add77c64ca8b ("hwmon: add support for THMC50 and ADM1022")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/thmc50.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index b385ef64af75..73755791af56 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -15,7 +15,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
MODULE_LICENSE("GPL");
@@ -60,7 +60,7 @@ struct thmc50_data {
struct mutex update_lock;
enum chips type;
- unsigned long last_updated; /* In jiffies */
+ ktime_t last_updated;
char has_temp3; /* !=0 if it is ADM1022 in temp3 mode */
bool valid; /* true if following fields are valid */
@@ -77,12 +77,13 @@ static struct thmc50_data *thmc50_update_device(struct device *dev)
{
struct thmc50_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
+ unsigned int timeout_ms = data->type == thmc50 ? 1200 : 200;
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + timeout)
- || !data->valid) {
+ if (!data->valid ||
+ ktime_after(ktime_get(),
+ ktime_add_ms(data->last_updated, timeout_ms))) {
int temps = data->has_temp3 ? 3 : 2;
int i;
@@ -106,7 +107,7 @@ static struct thmc50_data *thmc50_update_device(struct device *dev)
i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
data->alarms =
i2c_smbus_read_byte_data(client, THMC50_REG_INTR);
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 088/102] hwmon: (tmp421) Use ktime for temperature cache timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (86 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 087/102] hwmon: (thmc50) Use ktime for register " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 089/102] hwmon: (tmp464) Use ktime for fault register " Guenter Roeck
` (13 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
tmp421 uses 32-bit jiffies and time_after() with a 500 ms (HZ / 2)
interval to cache temperature readings. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Convert last_updated to ktime_t with a 500 ms interval using
ktime_get(), ktime_add_ms(), and ktime_after().
Fixes: 9410700b881f ("hwmon: Add driver for Texas Instruments TMP421/422/423 sensor chips")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/tmp421.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index ed00ccfdd7b3..be36f4982c18 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -14,7 +14,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
@@ -103,7 +103,7 @@ struct tmp421_data {
const struct hwmon_channel_info *info[2];
struct hwmon_chip_info chip;
bool valid;
- unsigned long last_updated;
+ ktime_t last_updated;
unsigned long channels;
u8 config;
struct tmp421_channel channel[MAX_CHANNELS];
@@ -128,8 +128,8 @@ static int tmp421_update_device(struct tmp421_data *data)
int ret = 0;
int i;
- if (time_after(jiffies, data->last_updated + (HZ / 2)) ||
- !data->valid) {
+ if (!data->valid ||
+ ktime_after(ktime_get(), ktime_add_ms(data->last_updated, 500))) {
data->valid = false;
ret = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1);
if (ret < 0)
@@ -147,7 +147,7 @@ static int tmp421_update_device(struct tmp421_data *data)
return ret;
data->channel[i].temp |= ret;
}
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
return 0;
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 089/102] hwmon: (tmp464) Use ktime for fault register cache timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (87 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 088/102] hwmon: (tmp421) Use ktime for temperature " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 090/102] hwmon: (via686a) Use 64-bit jiffies for update timestamp Guenter Roeck
` (12 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
tmp464 uses 32-bit jiffies and time_after() with data->update_interval
(in milliseconds) converted via msecs_to_jiffies() to cache the
clear-on-read remote open fault register. On 32-bit architectures, if a
fault attribute is not polled for about 24.8 days at HZ=1000,
time_after() wraps around and the cached fault value stops updating.
Since update_interval is already stored in milliseconds, convert
last_updated to ktime_t using ktime_get(), ktime_add_ms(), and
ktime_after().
Fixes: 007e433cf037 ("hwmon: Add driver for Texas Instruments TMP464 and TMP468")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/tmp464.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/tmp464.c b/drivers/hwmon/tmp464.c
index c3e031044d1e..00f6d4495eb1 100644
--- a/drivers/hwmon/tmp464.c
+++ b/drivers/hwmon/tmp464.c
@@ -12,6 +12,7 @@
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/init.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
@@ -94,7 +95,7 @@ struct tmp464_data {
int channels;
s16 config_orig;
u16 open_reg;
- unsigned long last_updated;
+ ktime_t last_updated;
bool valid;
int update_interval;
struct tmp464_channel channel[MAX_CHANNELS];
@@ -170,13 +171,15 @@ static int tmp464_temp_read(struct device *dev, u32 attr, int channel, long *val
* complete. That means we have to cache the value internally
* for one measurement cycle and report the cached value.
*/
- if (!data->valid || time_after(jiffies, data->last_updated +
- msecs_to_jiffies(data->update_interval))) {
+ if (!data->valid ||
+ ktime_after(ktime_get(),
+ ktime_add_ms(data->last_updated,
+ data->update_interval))) {
err = regmap_read(regmap, TMP464_REMOTE_OPEN_REG, ®val);
if (err < 0)
break;
data->open_reg = regval;
- data->last_updated = jiffies;
+ data->last_updated = ktime_get();
data->valid = true;
}
*val = !!(data->open_reg & BIT(channel + 7));
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 090/102] hwmon: (via686a) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (88 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 089/102] hwmon: (tmp464) Use ktime for fault register " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 091/102] hwmon: (vt1211) " Guenter Roeck
` (11 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
via686a uses 32-bit jiffies and time_after() to determine when cached
register values should be refreshed. On 32-bit architectures, if the
sensor is not polled for about 24.8 days at HZ=1000, time_after() wraps
around and cached values stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid wrap-around issues on 32-bit systems.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/via686a.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index bbaeb808cc15..56e822201349 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -307,7 +307,7 @@ struct via686a_data {
struct device *hwmon_dev;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[5]; /* Register value */
u8 in_max[5]; /* Register value */
@@ -348,7 +348,7 @@ static struct via686a_data *via686a_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2)
|| !data->valid) {
for (i = 0; i <= 4; i++) {
data->in[i] =
@@ -396,7 +396,7 @@ static struct via686a_data *via686a_update_device(struct device *dev)
via686a_read_value(data,
VIA686A_REG_ALARM1) |
(via686a_read_value(data, VIA686A_REG_ALARM2) << 8);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 091/102] hwmon: (vt1211) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (89 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 090/102] hwmon: (via686a) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 092/102] hwmon: (vt8231) " Guenter Roeck
` (10 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Juerg Haefliger
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: ab41319eab3b ("hwmon: New driver for the VIA VT1211")
Cc: Juerg Haefliger <juergh@proton.me>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/vt1211.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 1e52cabd6e24..675468a77438 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -106,7 +106,7 @@ struct vt1211_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/* Register values */
u8 in[6];
@@ -263,7 +263,8 @@ static struct vt1211_data *vt1211_update_device(struct device *dev)
mutex_lock(&data->update_lock);
/* registers cache is refreshed after 1 second */
- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ) ||
+ !data->valid) {
/* read VID */
data->vid = vt1211_read8(data, VT1211_REG_VID) & 0x1f;
@@ -329,7 +330,7 @@ static struct vt1211_data *vt1211_update_device(struct device *dev)
data->alarms = (vt1211_read8(data, VT1211_REG_ALARM2) << 8) |
vt1211_read8(data, VT1211_REG_ALARM1);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 092/102] hwmon: (vt8231) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (90 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 091/102] hwmon: (vt1211) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 093/102] hwmon: (w83627ehf) " Guenter Roeck
` (9 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Roger Lucas
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 1de9e371b89e ("[PATCH] hwmon: New vt8231 driver")
Cc: Roger Lucas <vt8231@hiddenengine.co.uk>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/vt8231.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index 5757a0979f3f..6e036f123fca 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -152,7 +152,7 @@ struct vt8231_data {
struct mutex update_lock;
struct device *hwmon_dev;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[6]; /* Register value */
u8 in_max[6]; /* Register value */
@@ -188,8 +188,8 @@ static struct vt8231_data *vt8231_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
for (i = 0; i < 6; i++) {
if (ISVOLT(i, data->uch_config)) {
data->in[i] = vt8231_read_value(data,
@@ -239,7 +239,7 @@ static struct vt8231_data *vt8231_update_device(struct device *dev)
else if (data->fan[1] && !data->fan_min[1])
data->alarms &= ~0x80;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 093/102] hwmon: (w83627ehf) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (91 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 092/102] hwmon: (vt8231) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 094/102] hwmon: (w83627hf) " Guenter Roeck
` (8 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 08e7e2789e0d ("[PATCH] I2C: New hardware monitoring driver: w83627ehf")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83627ehf.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index a23edd35c19f..193f4b795dc0 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -321,7 +321,7 @@ struct w83627ehf_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/* Register values */
u8 bank; /* current register bank */
@@ -567,8 +567,8 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ/2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
/* Fan clock dividers */
w83627ehf_update_fan_div(data);
@@ -687,7 +687,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
data->caseopen = w83627ehf_read_value(data,
W83627EHF_REG_CASEOPEN_DET);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
@@ -775,7 +775,7 @@ store_fan_min(struct device *dev, struct w83627ehf_data *data, int channel,
data->fan_div[channel] = new_div;
w83627ehf_write_fan_div(data, channel);
/* Give the chip time to sample a new speed value */
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
}
w83627ehf_write_value(data, W83627EHF_REG_FAN_MIN[channel],
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 094/102] hwmon: (w83627hf) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (92 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 093/102] hwmon: (w83627ehf) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 095/102] hwmon: (w83781d) " Guenter Roeck
` (7 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83627hf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index bb993bb09f40..d65d39c52538 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -356,7 +356,7 @@ struct w83627hf_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[9]; /* Register value */
u8 in_max[9]; /* Register value */
@@ -482,8 +482,8 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
for (i = 0; i <= 8; i++) {
/* skip missing sensors */
if (((data->type == w83697hf) && (i == 1)) ||
@@ -559,7 +559,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
data->beep_mask = (i << 8) |
w83627hf_read_value(data, W83781D_REG_BEEP_INTS1) |
w83627hf_read_value(data, W83781D_REG_BEEP_INTS3) << 16;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 095/102] hwmon: (w83781d) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (93 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 094/102] hwmon: (w83627hf) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 096/102] hwmon: (w83791d) " Guenter Roeck
` (6 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83781d.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index c40f84e53469..4582221ca2f3 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -204,7 +204,7 @@ struct w83781d_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
struct i2c_client *lm75[2]; /* for secondary I2C addresses */
/* array of 2 pointers to subclients */
@@ -1447,8 +1447,8 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
dev_dbg(dev, "Starting device update\n");
for (i = 0; i <= 8; i++) {
@@ -1549,7 +1549,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
w83781d_read_value(data,
W83781D_REG_BEEP_INTS3) << 16;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 096/102] hwmon: (w83791d) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (94 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 095/102] hwmon: (w83781d) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 097/102] hwmon: (w83792d) " Guenter Roeck
` (5 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Marc Hulsman
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 9873964d6eb2 ("[PATCH] HWMON: w83791d: New hardware monitoring driver for the Winbond W83791D")
Cc: Marc Hulsman <m.hulsman@tudelft.nl>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83791d.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 4b07a25ae59e..6858e2a0adb3 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -276,7 +276,7 @@ struct w83791d_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
/* volts */
u8 in[NUMBER_OF_VIN]; /* Register value */
@@ -1488,8 +1488,8 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + (HZ * 3))
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ * 3) ||
+ !data->valid) {
dev_dbg(dev, "Starting w83791d device update\n");
/* Update the voltages measured value and limits */
@@ -1599,7 +1599,7 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
data->vid |= (w83791d_read(client, W83791D_REG_DID_VID4) & 0x01)
<< 4;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 097/102] hwmon: (w83792d) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (95 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 096/102] hwmon: (w83791d) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 098/102] hwmon: (w83793) Use 64-bit jiffies for update timestamps Guenter Roeck
` (4 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
w83792d_update_device() passes a delta (jiffies - data->last_updated) as
an absolute timestamp argument to time_after() alongside a separate
time_before() check, which misuses the jiffies comparison helpers and
suffers from 32-bit jiffies wrap-around issues when the sensor is not
polled for long periods.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to properly check cache expiration without 32-bit wrap-around issues.
Fixes: 5563e27d3a42 ("[PATCH] I2C: W83792D driver 1/3")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83792d.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index f715c79389a5..1e6bb883757b 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -262,7 +262,7 @@ struct w83792d_data {
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
u8 in[9]; /* Register value */
u8 in_max[9]; /* Register value */
@@ -1484,9 +1484,8 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (time_after
- (jiffies - data->last_updated, (unsigned long) (HZ * 3))
- || time_before(jiffies, data->last_updated) || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ * 3) ||
+ !data->valid) {
dev_dbg(dev, "Starting device update\n");
/* Update the voltages measured value and limits */
@@ -1586,7 +1585,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
data->sf2_levels[i][3] = reg_tmp & 0x0f;
}
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 098/102] hwmon: (w83793) Use 64-bit jiffies for update timestamps
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (96 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 097/102] hwmon: (w83792d) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 099/102] hwmon: (w83795) Use 64-bit jiffies for update timestamp Guenter Roeck
` (3 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Rudolf Marek
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor and
nonvolatile register values to stop updating.
Switch last_updated and last_nonvolatile to u64 and use get_jiffies_64()
with time_after64() to avoid 32-bit jiffies wrap-around issues.
Fixes: 6800c3d027b4 ("hwmon: New Winbond W83793 hardware monitoring driver")
Cc: Rudolf Marek <r.marek@assembler.cz>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83793.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index e1f2708b5db6..55ac2907fd2b 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -206,8 +206,8 @@ struct w83793_data {
struct device *hwmon_dev;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
- unsigned long last_nonvolatile; /* In jiffies, last time we update the
+ u64 last_updated; /* In jiffies */
+ u64 last_nonvolatile; /* In jiffies, last time we update the
* nonvolatile registers
*/
@@ -1946,8 +1946,9 @@ static void w83793_update_nonvolatile(struct device *dev)
* takes so much time, it's just not worthy. Update them in a long
* interval to avoid exception.
*/
- if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300)
- || !data->valid))
+ if (!(time_after64(get_jiffies_64(),
+ data->last_nonvolatile + HZ * 300) ||
+ !data->valid))
return;
/* update voltage limits */
for (i = 1; i < 3; i++) {
@@ -2020,7 +2021,7 @@ static void w83793_update_nonvolatile(struct device *dev)
for (i = 0; i < ARRAY_SIZE(data->beeps); i++)
data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i));
- data->last_nonvolatile = jiffies;
+ data->last_nonvolatile = get_jiffies_64();
}
static struct w83793_data *w83793_update_device(struct device *dev)
@@ -2031,8 +2032,8 @@ static struct w83793_data *w83793_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (!(time_after(jiffies, data->last_updated + HZ * 2)
- || !data->valid))
+ if (!(time_after64(get_jiffies_64(), data->last_updated + HZ * 2) ||
+ !data->valid))
goto END;
/* Update the voltages measured value and limits */
@@ -2077,7 +2078,7 @@ static struct w83793_data *w83793_update_device(struct device *dev)
if (data->has_vid & 0x02)
data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB);
w83793_update_nonvolatile(dev);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
END:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 099/102] hwmon: (w83795) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (97 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 098/102] hwmon: (w83793) Use 64-bit jiffies for update timestamps Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 100/102] hwmon: (w83l785ts) " Guenter Roeck
` (2 subsequent siblings)
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Jean Delvare
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 792d376b4f3f ("hwmon: New driver for the W83795G/ADG monitoring chips")
Cc: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83795.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index c5ce0bf1b08e..f349fd96b22c 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -320,7 +320,7 @@ enum chip_types {w83795g, w83795adg};
struct w83795_data {
struct device *hwmon_dev;
struct mutex update_lock;
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
enum chip_types chip_type;
u8 bank;
@@ -598,8 +598,8 @@ static struct w83795_data *w83795_update_device(struct device *dev)
if (!data->valid_limits)
w83795_update_limits(client);
- if (!(time_after(jiffies, data->last_updated + HZ * 2)
- || !data->valid))
+ if (!(time_after64(get_jiffies_64(), data->last_updated + HZ * 2) ||
+ !data->valid))
goto END;
/* Update the voltages value */
@@ -683,7 +683,7 @@ static struct w83795_data *w83795_update_device(struct device *dev)
w83795_write(client, W83795_REG_ALARM_CTRL,
tmp & ~ALARM_CTRL_RTSACS);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
END:
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 100/102] hwmon: (w83l785ts) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (98 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 099/102] hwmon: (w83795) Use 64-bit jiffies for update timestamp Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 101/102] hwmon: (w83l786ng) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 102/102] hwmon: (asus_rog_ryujin) Use ktime for pump source change timestamp Guenter Roeck
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83l785ts.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index e42506a3bcbe..9e7e8ab11f21 100644
--- a/drivers/hwmon/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
@@ -99,7 +99,7 @@ struct w83l785ts_data {
struct device *hwmon_dev;
struct mutex update_lock;
bool valid; /* false until following fields are valid */
- unsigned long last_updated; /* in jiffies */
+ u64 last_updated; /* in jiffies */
/* registers values */
s8 temp[2]; /* 0: input, 1: critical limit */
@@ -260,14 +260,15 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev)
mutex_lock(&data->update_lock);
- if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) {
+ if (!data->valid ||
+ time_after64(get_jiffies_64(), data->last_updated + HZ * 2)) {
dev_dbg(&client->dev, "Updating w83l785ts data.\n");
data->temp[0] = w83l785ts_read_value(client,
W83L785TS_REG_TEMP, data->temp[0]);
data->temp[1] = w83l785ts_read_value(client,
W83L785TS_REG_TEMP_OVER, data->temp[1]);
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 101/102] hwmon: (w83l786ng) Use 64-bit jiffies for update timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (99 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 100/102] hwmon: (w83l785ts) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
2026-11-02 22:52 ` [PATCH 102/102] hwmon: (asus_rog_ryujin) Use ktime for pump source change timestamp Guenter Roeck
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck
On 32-bit architectures, time_after() overflows after about 24.8 days
at HZ=1000 if the sensor is not polled, causing cached sensor values to
stop updating.
Switch last_updated to u64 and use get_jiffies_64() with time_after64()
to avoid 32-bit jiffies wrap-around issues.
Fixes: 85f03bccd6e0 ("hwmon: Add support for Winbond W83L786NG/NR")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/w83l786ng.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index a72397083cc4..061469fc5b6c 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -123,7 +123,7 @@ struct w83l786ng_data {
struct i2c_client *client;
struct mutex update_lock;
bool valid; /* true if following fields are valid */
- unsigned long last_updated; /* In jiffies */
+ u64 last_updated; /* In jiffies */
unsigned long last_nonvolatile; /* In jiffies, last time we update the
* nonvolatile registers */
@@ -164,8 +164,8 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
u8 reg_tmp, pwmcfg;
mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
+ if (time_after64(get_jiffies_64(), data->last_updated + HZ + HZ / 2) ||
+ !data->valid) {
dev_dbg(&client->dev, "Updating w83l786ng data.\n");
/* Update the voltages measured value and limits */
@@ -217,7 +217,7 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
data->tolerance[0] = reg_tmp & 0x0f;
data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
- data->last_updated = jiffies;
+ data->last_updated = get_jiffies_64();
data->valid = true;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread* [PATCH 102/102] hwmon: (asus_rog_ryujin) Use ktime for pump source change timestamp
2026-11-02 22:50 [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps Guenter Roeck
` (100 preceding siblings ...)
2026-11-02 22:52 ` [PATCH 101/102] hwmon: (w83l786ng) " Guenter Roeck
@ 2026-11-02 22:52 ` Guenter Roeck
101 siblings, 0 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:52 UTC (permalink / raw)
To: linux-hwmon; +Cc: Guenter Roeck, Aleksa Savic
rog_ryujin_write_cooler_duty() tracks the last pump control source change
in 32-bit jiffies (priv->source_changed) and computes jiffies -
priv->source_changed to enforce RYUJIN_SOURCE_CHANGE_INTERVAL (1000 ms).
On 32-bit architectures, jiffies wraps every ~49.7 days at HZ=1000, so an
unpolled source_changed timestamp can falsely appear recent after
wraparound and trigger an unnecessary sleep.
Since RYUJIN_SOURCE_CHANGE_INTERVAL and RYUJIN_SOURCE_CHANGE_TIMEOUT are
defined in milliseconds and the driver already uses ktime_t for status
caching, convert priv->source_changed and the source-change polling
timeout to ktime_t using ktime_get(), ktime_ms_delta(), ktime_add_ms(),
ktime_sub_ms(), and ktime_before().
Fixes: 054395a539cd ("hwmon: (asus_rog_ryujin) Add pwm1_enable for the Ryujin III pump")
Cc: Aleksa Savic <savicaleksa83@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/asus_rog_ryujin.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
index 34b1150520ca..c0d2f9463220 100644
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -134,7 +134,7 @@ struct rog_ryujin_data {
u16 speed_input[6]; /* Pump, internal fan and four controller fan speeds in RPM */
u8 duty_input[3]; /* Pump, internal fan and controller fan duty in PWM */
u8 pump_source; /* Pump control source from the cooler duty report */
- unsigned long source_changed; /* jiffies */
+ ktime_t source_changed;
u8 *buffer;
ktime_t updated;
@@ -340,25 +340,25 @@ static int rog_ryujin_read_string(struct device *dev, enum hwmon_sensor_types ty
*/
static int rog_ryujin_write_cooler_duty(struct rog_ryujin_data *priv, const u8 *set_cmd)
{
- unsigned long interval = msecs_to_jiffies(RYUJIN_SOURCE_CHANGE_INTERVAL);
u8 source = set_cmd[RYUJIN_SET_COOLER_CHANNEL_OFFSET];
- unsigned long elapsed, timeout;
+ ktime_t timeout;
+ s64 elapsed;
int ret;
if (!priv->info->duty_channel || source == priv->pump_source)
return rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH,
&priv->cooler_duty_set);
- elapsed = jiffies - priv->source_changed;
- if (elapsed < interval)
- msleep(jiffies_to_msecs(interval - elapsed));
+ elapsed = ktime_ms_delta(ktime_get(), priv->source_changed);
+ if (elapsed < RYUJIN_SOURCE_CHANGE_INTERVAL)
+ msleep(RYUJIN_SOURCE_CHANGE_INTERVAL - elapsed);
ret = rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH, &priv->cooler_duty_set);
if (ret < 0)
return ret;
- priv->source_changed = jiffies;
- timeout = jiffies + msecs_to_jiffies(RYUJIN_SOURCE_CHANGE_TIMEOUT);
+ priv->source_changed = ktime_get();
+ timeout = ktime_add_ms(priv->source_changed, RYUJIN_SOURCE_CHANGE_TIMEOUT);
do {
msleep(100);
ret = rog_ryujin_execute_cmd(priv, get_cooler_duty_cmd, GET_CMD_LENGTH,
@@ -367,7 +367,7 @@ static int rog_ryujin_write_cooler_duty(struct rog_ryujin_data *priv, const u8 *
return ret;
if (priv->pump_source == source)
return 0;
- } while (time_before(jiffies, timeout));
+ } while (ktime_before(ktime_get(), timeout));
return -ETIMEDOUT;
}
@@ -703,7 +703,7 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
* a special case there.
*/
priv->updated = ktime_sub_ms(ktime_get(), STATUS_VALIDITY + 1);
- priv->source_changed = jiffies - msecs_to_jiffies(RYUJIN_SOURCE_CHANGE_INTERVAL);
+ priv->source_changed = ktime_sub_ms(ktime_get(), RYUJIN_SOURCE_CHANGE_INTERVAL);
ret = hid_parse(hdev);
if (ret) {
--
2.45.2
^ permalink raw reply related [flat|nested] 104+ messages in thread