All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 000/102] hwmon: Fix 32-bit jiffies wraparound in sensor cache timestamps
@ 2026-11-02 22:50 Guenter Roeck
  2026-11-02 22:50 ` [PATCH 001/102] hwmon: (abituguru) Use 64-bit jiffies for update timestamp Guenter Roeck
                   ` (101 more replies)
  0 siblings, 102 replies; 104+ messages in thread
From: Guenter Roeck @ 2026-11-02 22:50 UTC (permalink / raw)
  To: linux-hwmon
  Cc: Guenter Roeck, Aleksa Savic, Alistair John Strachan,
	Corentin Labbe, Denis Pauk, Ed Brindley, George Joseph,
	Hans de Goede, Iwona Winiarska, Jack Doan, James Seo,
	Jean Delvare, Jim Cromie, Jonas Malaco, Juerg Haefliger,
	Luca Tettamanti, Marc Hulsman, Riku Voipio, Roger Lucas,
	Rudolf Marek, Steve Glendinning

Many hwmon drivers cache hardware register values and use 32-bit
jiffies comparisons (time_after(), time_before(), time_after_eq(),
time_before_eq(), or unsigned jiffies deltas) to determine when cached
readings or rate-limit intervals have expired. On 32-bit architectures,
unsigned long jiffies is 32 bits wide and signed delta comparisons wrap
around after MAX_JIFFY_OFFSET ticks (about 24.85 days at HZ=1000). If a
sensor is not polled for longer than that window, time_after()
evaluates to false (or time_before() to true) for another ~24.85 days
and stale cached values are returned instead of reading fresh values
from the hardware.

Sashiko finds more and more instances of this problem in drivers, and I
started seeing patches fixing individual drivers. So, instead of going
slow, I decided to handle all of them in one series.

This series audits drivers/hwmon and fixes all 101 remaining affected
drivers across 102 patches (two patches for asus_rog_ryujin), choosing
between 64-bit jiffies and ktime on a per-driver basis:

- 64-bit jiffies (78 drivers): Used where refresh intervals are
  expressed directly in HZ ticks (e.g., HZ, HZ + HZ / 2, 2 * HZ,
  60 * HZ) or where helper logic already operates in jiffies. These
  drivers are converted to u64 (or atomic64_t in adt7470 to preserve
  its lockless sysfs read fast-path), get_jiffies_64(), and the
  corresponding time_*64() helpers.

- ktime (23 drivers, 24 patches): Used where intervals are naturally
  expressed in milliseconds or microseconds (configurable millisecond
  conversion tables, sub-second intervals, or asynchronous USB HID
  status and control timeouts). These drivers are converted to ktime_t
  with ktime_get(), ktime_add_ms() / ktime_add_us(), ktime_ms_delta(),
  and ktime_after() / ktime_before(), avoiding both 32-bit jiffies
  wraparound and coarse msecs_to_jiffies() rounding on low-HZ kernels.

Because 64-bit timestamp loads and stores are non-atomic on 32-bit
architectures, all timestamp read/write paths were also checked for
serialization:

- Drivers registered via [devm_]hwmon_device_register_with_info()
  without unlocked custom paths are already serialized by hwdev->lock
  in the hwmon core.
- Where additional synchronization was required, locks were added or
  extended: hwmon_lock in asus_atk0110 and menf21bmc_hwmon, atomic64_t
  with acquire/release ordering on validity flags in adt7470, spinlocks
  synchronizing HID .raw_event and .read callbacks in
  aquacomputer_d5next, nzxt-kraken2, and nzxt-kraken3, and acquiring
  state->lock before checking last_updated in hp-wmi-sensors.

Auditing the timestamp logic also uncovered a few existing driver bugs
that are fixed in their respective patches:

- atxp1, ibmaem: Updated last_updated (and valid in ibmaem when all
  IPMI reads succeed), which were previously never written despite
  being checked.
- ds1621, ina209: Fixed millisecond update_interval values previously
  added directly to jiffies without unit conversion (enforcing a 1 ms
  minimum cache window in ina209 when single-sample conversion time
  truncates update_interval to 0 ms).
- f71805f: Fixed the limit cache expiration check comparing against
  data->last_updated instead of data->last_limits.
- w83792d: Fixed time_after() being passed a relative jiffies delta
  rather than absolute jiffies timestamps.

Note on tooling and testing:
This series was generated with an AI coding assistant (Jetski / Gemini)
prompted to audit drivers/hwmon for 32-bit jiffies wraparound issues
and convert affected drivers to 64-bit jiffies or ktime as appropriate,
followed by automated review (Sashiko) and manual inspection of flagged
drivers. All 102 patches were build-tested on arm, arm64, and x86_64
across all modified object files with zero warnings and verified with
scripts/checkpatch.pl --strict; they were not tested on physical sensor
hardware.

I plan to apply the series to hwmon-next. Some of the patches will find
their way into the 'hwmon' branch and be sent upstream, especially those
fixing other bugs or if the problem is reported by Sashiko in some other
context.

Cc: Aleksa Savic <savicaleksa83@gmail.com>
Cc: Alistair John Strachan <alistair@devzero.co.uk>
Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
Cc: Denis Pauk <pauk.denis@gmail.com>
Cc: Ed Brindley <kernel@maidavale.org>
Cc: George Joseph <george.joseph@fairview5.com>
Cc: Hans de Goede <hansg@kernel.org>
Cc: Iwona Winiarska <iwona.winiarska@intel.com>
Cc: Jack Doan <me@jackdoan.com>
Cc: James Seo <james@equiv.tech>
Cc: Jean Delvare <jdelvare@suse.com>
Cc: Jim Cromie <jim.cromie@gmail.com>
Cc: Jonas Malaco <jonas@protocubo.io>
Cc: Juerg Haefliger <juergh@proton.me>
Cc: Luca Tettamanti <kronos.it@gmail.com>
Cc: Marc Hulsman <m.hulsman@tudelft.nl>
Cc: Riku Voipio <riku.voipio@iki.fi>
Cc: Roger Lucas <vt8231@hiddenengine.co.uk>
Cc: Rudolf Marek <r.marek@assembler.cz>
Cc: Steve Glendinning <steve.glendinning@shawell.net>

---
Guenter Roeck (102):
  hwmon: (abituguru) Use 64-bit jiffies for update timestamp
  hwmon: (abituguru3) Use 64-bit jiffies for update timestamp
  hwmon: (acpi_power_meter) Use ktime for sensor sampling interval
  hwmon: (ad7414) Use 64-bit jiffies for update deadline
  hwmon: (ad7418) Use 64-bit jiffies for update timestamp
  hwmon: (adc128d818) Use 64-bit jiffies for update timestamp
  hwmon: (adm1025) Use 64-bit jiffies for update timestamp
  hwmon: (adm1026) Use 64-bit jiffies for update timestamps
  hwmon: (adm1029) Use 64-bit jiffies for update timestamp
  hwmon: (adm1031) Use ktime for sensor update interval
  hwmon: (adt7411) Use 64-bit jiffies for vref update deadline
  hwmon: (adt7462) Use 64-bit jiffies for update timestamps
  hwmon: (adt7470) Use 64-bit jiffies for update timestamps
  hwmon: (adt7475) Use 64-bit jiffies for measurement timestamp
  hwmon: (aquacomputer_d5next) Use ktime for status update timestamp
  hwmon: (asb100) Use 64-bit jiffies for update timestamp
  hwmon: (asc7621) Use 64-bit jiffies for update timestamps
  hwmon: (asus_atk0110) Use 64-bit jiffies for sensor cache timestamp
  hwmon: (asus_rog_ryujin) Use ktime for status validity timestamp
  hwmon: (asus_wmi_sensors) Use 64-bit jiffies for source cache
    timestamps
  hwmon: (atxp1) Use 64-bit jiffies and record update timestamp
  hwmon: (dme1737) Use 64-bit jiffies for update timestamps
  hwmon: (ds1621) Use ktime for update timestamp
  hwmon: (ds620) Use 64-bit jiffies for update timestamp
  hwmon: (emc2103) Use 64-bit jiffies for update timestamp
  hwmon: (emc6w201) Use 64-bit jiffies for update timestamp
  hwmon: (f71805f) Use 64-bit jiffies for update timestamps
  hwmon: (f71882fg) Use 64-bit jiffies for update timestamps
  hwmon: (f75375s) Use 64-bit jiffies for update timestamps
  hwmon: (fschmd) Use 64-bit jiffies for update timestamp
  hwmon: (ftsteutates) Use 64-bit jiffies for update timestamp
  hwmon: (g760a) Use 64-bit jiffies for update timestamp
  hwmon: (g762) Use 64-bit jiffies for update timestamp
  hwmon: (gigabyte_waterforce) Use ktime for status validity timestamp
  hwmon: (gl518sm) Use 64-bit jiffies for update timestamp
  hwmon: (gl520sm) Use 64-bit jiffies for update timestamp
  hwmon: (hih6130) Use 64-bit jiffies for update timestamp
  hwmon: (hp-wmi-sensors) Use 64-bit jiffies for sensor cache timestamps
  hwmon: (ibmaem) Use 64-bit jiffies and record update timestamps
  hwmon: (ibmpex) Use 64-bit jiffies for update timestamp
  hwmon: (ina209) Use ktime for update timestamp
  hwmon: (it87) Use 64-bit jiffies for update timestamp
  hwmon: (kbatt) Use 64-bit jiffies for update deadline
  hwmon: (lineage-pem) Use 64-bit jiffies for update timestamp
  hwmon: (lm63) Use ktime for update timestamps
  hwmon: (lm77) Use 64-bit jiffies for update timestamp
  hwmon: (lm78) Use 64-bit jiffies for update timestamp
  hwmon: (lm80) Use 64-bit jiffies for update timestamp
  hwmon: (lm85) Use 64-bit jiffies for update timestamps
  hwmon: (lm87) Use 64-bit jiffies for update timestamp
  hwmon: (lm90) Use ktime for update timestamps
  hwmon: (lm93) Use 64-bit jiffies for update timestamp
  hwmon: (lm95241) Use ktime for update timestamp
  hwmon: (ltc4151) Use ktime for update timestamp
  hwmon: (ltc4215) Use ktime for update timestamp
  hwmon: (ltc4245) Use 64-bit jiffies for update timestamp
  hwmon: (ltc4261) Use ktime for update timestamp
  hwmon: (max16065) Use 64-bit jiffies for update timestamp
  hwmon: (max31790) Use 64-bit jiffies for update timestamp
  hwmon: (max6620) Use 64-bit jiffies for update timestamp
  hwmon: (max6650) Use 64-bit jiffies for update timestamp
  hwmon: (menf21bmc_hwmon) Use 64-bit jiffies for update timestamp
  hwmon: (nct6683) Use 64-bit jiffies for update timestamp
  hwmon: (nct6775) Use 64-bit jiffies for update timestamp
  hwmon: (nsa320-hwmon) Use 64-bit jiffies for update timestamp
  hwmon: (nzxt-kraken2) Use ktime for status report validity timestamp
  hwmon: (nzxt-kraken3) Use ktime for status report validity timestamp
  hwmon: (occ) Use 64-bit jiffies for poll and safe-state timestamps
  hwmon: (pc87360) Use 64-bit jiffies for update timestamp
  hwmon: (pc87427) Use 64-bit jiffies for update timestamp
  hwmon: (peci) Use 64-bit jiffies for sensor update timestamps
  hwmon: (powr1220) Use 64-bit jiffies for ADC update timestamps
  hwmon: (sch5627) Use 64-bit jiffies for update timestamps
  hwmon: (sch5636) Use 64-bit jiffies for update timestamp
  hwmon: (sht15) Use 64-bit jiffies for status and measurement
    timestamps
  hwmon: (sht21) Use ktime for measurement update timestamp
  hwmon: (sht3x) Use ktime for periodic mode update timestamp
  hwmon: (sht4x) Use 64-bit jiffies for poll timestamp
  hwmon: (shtc1) Use ktime for measurement update timestamp
  hwmon: (sis5595) Use 64-bit jiffies for update timestamp
  hwmon: (smsc47b397) Use 64-bit jiffies for update timestamp
  hwmon: (smsc47m1) Use 64-bit jiffies for update timestamp
  hwmon: (smsc47m192) Use 64-bit jiffies for update timestamp
  hwmon: (stts751) Use ktime for temperature and alert cache timestamps
  hwmon: (tc654) Use 64-bit jiffies for update timestamp
  hwmon: (tc74) Use ktime for temperature cache timestamp
  hwmon: (thmc50) Use ktime for register cache timestamp
  hwmon: (tmp421) Use ktime for temperature cache timestamp
  hwmon: (tmp464) Use ktime for fault register cache timestamp
  hwmon: (via686a) Use 64-bit jiffies for update timestamp
  hwmon: (vt1211) Use 64-bit jiffies for update timestamp
  hwmon: (vt8231) Use 64-bit jiffies for update timestamp
  hwmon: (w83627ehf) Use 64-bit jiffies for update timestamp
  hwmon: (w83627hf) Use 64-bit jiffies for update timestamp
  hwmon: (w83781d) Use 64-bit jiffies for update timestamp
  hwmon: (w83791d) Use 64-bit jiffies for update timestamp
  hwmon: (w83792d) Use 64-bit jiffies for update timestamp
  hwmon: (w83793) Use 64-bit jiffies for update timestamps
  hwmon: (w83795) Use 64-bit jiffies for update timestamp
  hwmon: (w83l785ts) Use 64-bit jiffies for update timestamp
  hwmon: (w83l786ng) Use 64-bit jiffies for update timestamp
  hwmon: (asus_rog_ryujin) Use ktime for pump source change timestamp

 drivers/hwmon/abituguru.c           |  8 ++---
 drivers/hwmon/abituguru3.c          |  7 ++--
 drivers/hwmon/acpi_power_meter.c    | 15 ++++----
 drivers/hwmon/ad7414.c              |  6 ++--
 drivers/hwmon/ad7418.c              |  8 ++---
 drivers/hwmon/adc128d818.c          |  7 ++--
 drivers/hwmon/adm1025.c             |  7 ++--
 drivers/hwmon/adm1026.c             | 17 ++++-----
 drivers/hwmon/adm1029.c             |  7 ++--
 drivers/hwmon/adm1031.c             | 14 ++++----
 drivers/hwmon/adt7411.c             | 10 +++---
 drivers/hwmon/adt7462.c             | 19 ++++++-----
 drivers/hwmon/adt7470.c             | 48 +++++++++++++++++---------
 drivers/hwmon/adt7475.c             |  6 ++--
 drivers/hwmon/aquacomputer_d5next.c | 27 +++++++++++----
 drivers/hwmon/asb100.c              |  8 ++---
 drivers/hwmon/asc7621.c             | 14 ++++----
 drivers/hwmon/asus_atk0110.c        |  9 ++---
 drivers/hwmon/asus_rog_ryujin.c     | 30 ++++++++--------
 drivers/hwmon/asus_wmi_sensors.c    |  7 ++--
 drivers/hwmon/atxp1.c               |  6 ++--
 drivers/hwmon/dme1737.c             | 14 ++++----
 drivers/hwmon/ds1621.c              | 10 +++---
 drivers/hwmon/ds620.c               |  6 ++--
 drivers/hwmon/emc2103.c             |  6 ++--
 drivers/hwmon/emc6w201.c            |  7 ++--
 drivers/hwmon/f71805f.c             | 12 +++----
 drivers/hwmon/f71882fg.c            | 13 +++----
 drivers/hwmon/f75375s.c             | 12 +++----
 drivers/hwmon/fschmd.c              |  7 ++--
 drivers/hwmon/ftsteutates.c         |  7 ++--
 drivers/hwmon/g760a.c               |  7 ++--
 drivers/hwmon/g762.c                |  7 ++--
 drivers/hwmon/gigabyte_waterforce.c | 11 +++---
 drivers/hwmon/gl518sm.c             |  6 ++--
 drivers/hwmon/gl520sm.c             |  7 ++--
 drivers/hwmon/hih6130.c             |  7 ++--
 drivers/hwmon/hp-wmi-sensors.c      | 12 +++----
 drivers/hwmon/ibmaem.c              | 53 +++++++++++++++++++----------
 drivers/hwmon/ibmpex.c              |  7 ++--
 drivers/hwmon/ina209.c              | 14 ++++++--
 drivers/hwmon/it87.c                |  6 ++--
 drivers/hwmon/kbatt.c               |  8 +++--
 drivers/hwmon/lineage-pem.c         |  7 ++--
 drivers/hwmon/lm63.c                | 20 +++++------
 drivers/hwmon/lm77.c                |  6 ++--
 drivers/hwmon/lm78.c                |  6 ++--
 drivers/hwmon/lm80.c                |  7 ++--
 drivers/hwmon/lm85.c                | 14 ++++----
 drivers/hwmon/lm87.c                |  7 ++--
 drivers/hwmon/lm90.c                | 20 ++++++-----
 drivers/hwmon/lm93.c                |  6 ++--
 drivers/hwmon/lm95241.c             | 10 +++---
 drivers/hwmon/ltc4151.c             | 10 +++---
 drivers/hwmon/ltc4215.c             |  9 ++---
 drivers/hwmon/ltc4245.c             |  9 ++---
 drivers/hwmon/ltc4261.c             |  9 ++---
 drivers/hwmon/max16065.c            |  7 ++--
 drivers/hwmon/max31790.c            |  7 ++--
 drivers/hwmon/max6620.c             |  7 ++--
 drivers/hwmon/max6650.c             |  7 ++--
 drivers/hwmon/menf21bmc_hwmon.c     | 19 +++++------
 drivers/hwmon/nct6683.c             |  7 ++--
 drivers/hwmon/nct6775-core.c        |  6 ++--
 drivers/hwmon/nct6775.h             |  2 +-
 drivers/hwmon/nsa320-hwmon.c        |  7 ++--
 drivers/hwmon/nzxt-kraken2.c        | 37 ++++++++++++++------
 drivers/hwmon/nzxt-kraken3.c        | 27 ++++++++++-----
 drivers/hwmon/occ/common.c          | 12 +++----
 drivers/hwmon/occ/common.h          |  4 +--
 drivers/hwmon/pc87360.c             |  7 ++--
 drivers/hwmon/pc87427.c             |  8 ++---
 drivers/hwmon/peci/common.h         | 12 ++++---
 drivers/hwmon/powr1220.c            |  6 ++--
 drivers/hwmon/sch5627.c             | 26 +++++++-------
 drivers/hwmon/sch5636.c             |  7 ++--
 drivers/hwmon/sht15.c               | 16 ++++-----
 drivers/hwmon/sht21.c               | 11 +++---
 drivers/hwmon/sht3x.c               | 13 +++----
 drivers/hwmon/sht4x.c               |  8 ++---
 drivers/hwmon/shtc1.c               |  8 +++--
 drivers/hwmon/sis5595.c             |  6 ++--
 drivers/hwmon/smsc47b397.c          |  7 ++--
 drivers/hwmon/smsc47m1.c            |  7 ++--
 drivers/hwmon/smsc47m192.c          |  8 ++---
 drivers/hwmon/stts751.c             | 24 +++++++------
 drivers/hwmon/tc654.c               |  7 ++--
 drivers/hwmon/tc74.c                |  8 ++---
 drivers/hwmon/thmc50.c              | 13 +++----
 drivers/hwmon/tmp421.c              | 10 +++---
 drivers/hwmon/tmp464.c              | 11 +++---
 drivers/hwmon/via686a.c             |  6 ++--
 drivers/hwmon/vt1211.c              |  7 ++--
 drivers/hwmon/vt8231.c              |  8 ++---
 drivers/hwmon/w83627ehf.c           | 10 +++---
 drivers/hwmon/w83627hf.c            |  8 ++---
 drivers/hwmon/w83781d.c             |  8 ++---
 drivers/hwmon/w83791d.c             |  8 ++---
 drivers/hwmon/w83792d.c             |  9 +++--
 drivers/hwmon/w83793.c              | 17 ++++-----
 drivers/hwmon/w83795.c              |  8 ++---
 drivers/hwmon/w83l785ts.c           |  7 ++--
 drivers/hwmon/w83l786ng.c           |  8 ++---
 103 files changed, 641 insertions(+), 494 deletions(-)

-- 
2.56.0

^ permalink raw reply	[flat|nested] 104+ messages in thread

* [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, &regval);
 			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

* Re: [PATCH 038/102] hwmon: (hp-wmi-sensors) Use 64-bit jiffies for sensor cache timestamps
  2026-11-02 22:51 ` [PATCH 038/102] hwmon: (hp-wmi-sensors) Use 64-bit jiffies for sensor cache timestamps Guenter Roeck
@ 2026-11-03  3:41   ` James Seo
  0 siblings, 0 replies; 104+ messages in thread
From: James Seo @ 2026-11-03  3:41 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: linux-hwmon

On Mon, Nov 02, 2026 at 02:51:31PM -0800, Guenter Roeck wrote:
> 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(-)
>

Acked-by: James Seo <james@equiv.tech>

^ permalink raw reply	[flat|nested] 104+ messages in thread

end of thread, other threads:[~2026-11-03  6:27 UTC | newest]

Thread overview: 104+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 003/102] hwmon: (acpi_power_meter) Use ktime for sensor sampling interval Guenter Roeck
2026-11-02 22:50 ` [PATCH 004/102] hwmon: (ad7414) Use 64-bit jiffies for update deadline Guenter Roeck
2026-11-02 22:50 ` [PATCH 005/102] hwmon: (ad7418) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:50 ` [PATCH 006/102] hwmon: (adc128d818) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 007/102] hwmon: (adm1025) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 008/102] hwmon: (adm1026) Use 64-bit jiffies for update timestamps Guenter Roeck
2026-11-02 22:51 ` [PATCH 009/102] hwmon: (adm1029) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 010/102] hwmon: (adm1031) Use ktime for sensor update interval Guenter Roeck
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 ` [PATCH 012/102] hwmon: (adt7462) Use 64-bit jiffies for update timestamps Guenter Roeck
2026-11-02 22:51 ` [PATCH 013/102] hwmon: (adt7470) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 014/102] hwmon: (adt7475) Use 64-bit jiffies for measurement timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 015/102] hwmon: (aquacomputer_d5next) Use ktime for status update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 016/102] hwmon: (asb100) Use 64-bit jiffies for " Guenter Roeck
2026-11-02 22:51 ` [PATCH 017/102] hwmon: (asc7621) Use 64-bit jiffies for update timestamps Guenter Roeck
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 ` [PATCH 019/102] hwmon: (asus_rog_ryujin) Use ktime for status validity timestamp Guenter Roeck
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 ` [PATCH 021/102] hwmon: (atxp1) Use 64-bit jiffies and record update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 022/102] hwmon: (dme1737) Use 64-bit jiffies for update timestamps Guenter Roeck
2026-11-02 22:51 ` [PATCH 023/102] hwmon: (ds1621) Use ktime for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 024/102] hwmon: (ds620) Use 64-bit jiffies " Guenter Roeck
2026-11-02 22:51 ` [PATCH 025/102] hwmon: (emc2103) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 026/102] hwmon: (emc6w201) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 027/102] hwmon: (f71805f) Use 64-bit jiffies for update timestamps Guenter Roeck
2026-11-02 22:51 ` [PATCH 028/102] hwmon: (f71882fg) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 029/102] hwmon: (f75375s) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 030/102] hwmon: (fschmd) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 031/102] hwmon: (ftsteutates) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 032/102] hwmon: (g760a) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 033/102] hwmon: (g762) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 034/102] hwmon: (gigabyte_waterforce) Use ktime for status validity timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 035/102] hwmon: (gl518sm) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 036/102] hwmon: (gl520sm) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 037/102] hwmon: (hih6130) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 038/102] hwmon: (hp-wmi-sensors) Use 64-bit jiffies for sensor cache timestamps 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
2026-11-02 22:51 ` [PATCH 040/102] hwmon: (ibmpex) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 041/102] hwmon: (ina209) Use ktime " Guenter Roeck
2026-11-02 22:51 ` [PATCH 042/102] hwmon: (it87) Use 64-bit jiffies " Guenter Roeck
2026-11-02 22:51 ` [PATCH 043/102] hwmon: (kbatt) Use 64-bit jiffies for update deadline Guenter Roeck
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 ` [PATCH 045/102] hwmon: (lm63) Use ktime for update timestamps Guenter Roeck
2026-11-02 22:51 ` [PATCH 046/102] hwmon: (lm77) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 047/102] hwmon: (lm78) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 048/102] hwmon: (lm80) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 049/102] hwmon: (lm85) Use 64-bit jiffies for update timestamps Guenter Roeck
2026-11-02 22:51 ` [PATCH 050/102] hwmon: (lm87) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 051/102] hwmon: (lm90) Use ktime for update timestamps Guenter Roeck
2026-11-02 22:51 ` [PATCH 052/102] hwmon: (lm93) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:51 ` [PATCH 053/102] hwmon: (lm95241) Use ktime " Guenter Roeck
2026-11-02 22:51 ` [PATCH 054/102] hwmon: (ltc4151) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 055/102] hwmon: (ltc4215) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 056/102] hwmon: (ltc4245) Use 64-bit jiffies " Guenter Roeck
2026-11-02 22:51 ` [PATCH 057/102] hwmon: (ltc4261) Use ktime " Guenter Roeck
2026-11-02 22:51 ` [PATCH 058/102] hwmon: (max16065) Use 64-bit jiffies " Guenter Roeck
2026-11-02 22:51 ` [PATCH 059/102] hwmon: (max31790) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 060/102] hwmon: (max6620) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 061/102] hwmon: (max6650) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 062/102] hwmon: (menf21bmc_hwmon) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 063/102] hwmon: (nct6683) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 064/102] hwmon: (nct6775) " Guenter Roeck
2026-11-02 22:51 ` [PATCH 065/102] hwmon: (nsa320-hwmon) " Guenter Roeck
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 ` [PATCH 067/102] hwmon: (nzxt-kraken3) " Guenter Roeck
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 ` [PATCH 069/102] hwmon: (pc87360) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 070/102] hwmon: (pc87427) " Guenter Roeck
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 ` [PATCH 072/102] hwmon: (powr1220) Use 64-bit jiffies for ADC " Guenter Roeck
2026-11-02 22:52 ` [PATCH 073/102] hwmon: (sch5627) Use 64-bit jiffies for " Guenter Roeck
2026-11-02 22:52 ` [PATCH 074/102] hwmon: (sch5636) Use 64-bit jiffies for update timestamp Guenter Roeck
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 ` [PATCH 076/102] hwmon: (sht21) Use ktime for measurement update timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 077/102] hwmon: (sht3x) Use ktime for periodic mode " Guenter Roeck
2026-11-02 22:52 ` [PATCH 078/102] hwmon: (sht4x) Use 64-bit jiffies for poll timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 079/102] hwmon: (shtc1) Use ktime for measurement update timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 080/102] hwmon: (sis5595) Use 64-bit jiffies for " Guenter Roeck
2026-11-02 22:52 ` [PATCH 081/102] hwmon: (smsc47b397) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 082/102] hwmon: (smsc47m1) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 083/102] hwmon: (smsc47m192) " Guenter Roeck
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 ` [PATCH 085/102] hwmon: (tc654) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 086/102] hwmon: (tc74) Use ktime for temperature cache timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 087/102] hwmon: (thmc50) Use ktime for register " Guenter Roeck
2026-11-02 22:52 ` [PATCH 088/102] hwmon: (tmp421) Use ktime for temperature " Guenter Roeck
2026-11-02 22:52 ` [PATCH 089/102] hwmon: (tmp464) Use ktime for fault register " Guenter Roeck
2026-11-02 22:52 ` [PATCH 090/102] hwmon: (via686a) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 091/102] hwmon: (vt1211) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 092/102] hwmon: (vt8231) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 093/102] hwmon: (w83627ehf) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 094/102] hwmon: (w83627hf) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 095/102] hwmon: (w83781d) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 096/102] hwmon: (w83791d) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 097/102] hwmon: (w83792d) " Guenter Roeck
2026-11-02 22:52 ` [PATCH 098/102] hwmon: (w83793) Use 64-bit jiffies for update timestamps Guenter Roeck
2026-11-02 22:52 ` [PATCH 099/102] hwmon: (w83795) Use 64-bit jiffies for update timestamp Guenter Roeck
2026-11-02 22:52 ` [PATCH 100/102] hwmon: (w83l785ts) " 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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.