* [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes
@ 2026-10-14 7:43 Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 1/6] platform/chrome: cros_ec_sensorhub: Fix AP/EC TS wrap Satyam Gupta
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Satyam Gupta @ 2026-10-14 7:43 UTC (permalink / raw)
To: Benson Leung, Tzung-Bi Shih
Cc: Guenter Roeck, Gwendal Grignou, Scott Collyer, chrome-platform,
linux-kernel, Satyam Gupta
This series addresses 32-bit EC timestamp rollover across deep AP
suspend and updates the clock drift estimation and timestamp filtering
logic to prevent Out Of Order (OOO) timestamps and large timestamp gaps
during sensor batching:
1. Account for 32-bit EC hardware timestamp wraps across deep AP suspend
and restrict overflow adjustments to forward wraps only.
2. Bound the history shift loop start index with min_t() so existing
entries shift properly without array overrun.
3. Clamp the calculated drift slope (m) within +/- MAX_DRIFT_PPM (5000
Parts Per Million (PPM)) to accommodate standalone EC clock drift
while rejecting large interrupt jitter spikes.
4. Reset the timestamp filter history when the time delta (dx) changes
by more than 10x across Output Data Rate (ODR) or streaming/batching
mode transitions.
5. Increase TS_HISTORY_BORED_US from 0.5s to 2.0s so normal 1-2s batch
flush intervals do not repeatedly reset the filter.
6. Rename cros_ec_sensor_ring_check_for_past_timestamp() to
cros_ec_sensor_ring_is_past_timestamp() and drop strictly past
samples instead of clamping them to last_ts.
Changes in v5:
- Split the clock drift estimation changes into 5 separate patches and
include "platform/chrome: cros_ec_sensorhub: Fix AP/EC TS wrap" in the
same 6-patch series as requested by Tzung-Bi Shih.
- Squash the MAX_DRIFT_PPM = 5000LL update directly into patch 3/6.
- Drop unrelated whitespace changes in cros_ec_sensorhub.c in patch 1/6.
Satyam Gupta (1):
platform/chrome: cros_ec_sensorhub: Fix AP/EC TS wrap
Scott Collyer (5):
platform/chrome: cros_ec_sensorhub: Fix TS filter history shift index
platform/chrome: cros_ec_sensorhub: Clamp clock drift slope to
MAX_DRIFT_PPM
platform/chrome: cros_ec_sensorhub: Reset TS filter on ODR or mode
changes
platform/chrome: cros_ec_sensorhub: Increase TS_HISTORY_BORED_US to 2s
platform/chrome: cros_ec_sensorhub: Drop sensor samples with past
timestamps
drivers/platform/chrome/cros_ec_sensorhub.c | 37 ++++++-
.../platform/chrome/cros_ec_sensorhub_ring.c | 103 ++++++++++++++----
.../linux/platform_data/cros_ec_sensorhub.h | 2 +
3 files changed, 117 insertions(+), 25 deletions(-)
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 1/6] platform/chrome: cros_ec_sensorhub: Fix AP/EC TS wrap
2026-10-14 7:43 [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes Satyam Gupta
@ 2026-10-14 7:43 ` Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 2/6] platform/chrome: cros_ec_sensorhub: Fix TS filter history shift index Satyam Gupta
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Satyam Gupta @ 2026-10-14 7:43 UTC (permalink / raw)
To: Benson Leung, Tzung-Bi Shih
Cc: Guenter Roeck, Gwendal Grignou, Scott Collyer, chrome-platform,
linux-kernel, Satyam Gupta
When the AP goes into deep sleep, the EC physically continues executing
and silently wraps its 32-bit timestamp counter one or more times.
Because Linux natively advances ktime_get_boottime() across suspend,
the AP clock leaps forward but the incoming 32-bit EC timestamp
appears historically delayed.
Calculate how many 71.5 minute epochs were swallowed during sleep by
dividing the AP's recorded sleep duration against the overflow period.
By injecting these missed wraps directly into the running EC offset
tracker, the EC timeline snaps forward instantly and achieves parity
with AP boottime, avoiding fatal negative delta time-skew calculations.
Any massive suspend gaps (>500ms) inherently trigger the
TS_HISTORY_BORED_US fallback during the first post-resume sensor event,
scrubbing the poisoned clock drift data. Because the clocks are
explicitly resynchronized by the math above, newly arriving samples
remain valid and are delivered without being warped by stale filter
history.
Signed-off-by: Satyam Gupta <sgsatyam@google.com>
---
drivers/platform/chrome/cros_ec_sensorhub.c | 37 ++++++++++++++++++-
.../platform/chrome/cros_ec_sensorhub_ring.c | 30 ++++++++++++---
.../linux/platform_data/cros_ec_sensorhub.h | 2 +
3 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_sensorhub.c b/drivers/platform/chrome/cros_ec_sensorhub.c
index 31fb8bdaad5a..5644ff4f8a90 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub.c
@@ -227,6 +227,8 @@ static int cros_ec_sensorhub_suspend(struct device *dev)
struct cros_ec_sensorhub *sensorhub = dev_get_drvdata(dev);
struct cros_ec_dev *ec = sensorhub->ec;
+ sensorhub->suspend_time = ktime_get_boottime();
+
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO))
return cros_ec_sensorhub_ring_fifo_enable(sensorhub, false);
return 0;
@@ -237,8 +239,41 @@ static int cros_ec_sensorhub_resume(struct device *dev)
struct cros_ec_sensorhub *sensorhub = dev_get_drvdata(dev);
struct cros_ec_dev *ec = sensorhub->ec;
- if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO))
+ if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
+ /*
+ * The EC's 32-bit hardware timestamp natively rolls over every
+ * 71.5 minutes. When the AP goes into deep sleep, the EC
+ * physically continues executing and silently wraps its 32-bit
+ * timestamp counter one or more times.
+ *
+ * Because Linux natively advances ktime_get_boottime() across
+ * suspend, the AP clock leaps forward, but the incoming 32-bit
+ * EC timestamp appears massively historically delayed due to
+ * the lost silent overflows.
+ *
+ * Calculate how many 71.5 minute epochs were swallowed during
+ * sleep by dividing the AP's recorded sleep duration against
+ * the overflow period. By injecting these missed wraps directly
+ * into the running EC offset tracker, the EC timeline snaps
+ * forward instantly and achieves active parity with the AP
+ * boottime, avoiding fatal negative delta time-skew
+ * calculations.
+ *
+ * Lastly, massive suspend gaps (>500ms) inherently trigger the
+ * TS_HISTORY_BORED_US fallback during the first post-resume
+ * sensor event, scrubbing the poisoned clock drift data.
+ */
+ u64 sleep_duration = ktime_to_us(ktime_sub(
+ ktime_get_boottime(),
+ sensorhub->suspend_time));
+ u64 missed_overflows = div64_u64(sleep_duration, 1ULL << 32);
+
+ sensorhub->overflow_a.offset += missed_overflows * (1ULL << 32);
+ sensorhub->overflow_b.offset += missed_overflows * (1ULL << 32);
+
return cros_ec_sensorhub_ring_fifo_enable(sensorhub, true);
+ }
+
return 0;
}
#endif
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index 1205219515d6..cc038af59218 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -369,13 +369,31 @@ cros_ec_sensor_ring_fix_overflow(s64 *ts,
struct cros_ec_sensors_ec_overflow_state
*state)
{
- s64 adjust;
-
*ts += state->offset;
- if (abs(state->last - *ts) > (overflow_period / 2)) {
- adjust = state->last > *ts ? overflow_period : -overflow_period;
- state->offset += adjust;
- *ts += adjust;
+
+ /*
+ * We must strictly detect exclusively forward overflows. A naive `abs()`
+ * check paired with a dual-direction adjustment (`+/- overflow_period`)
+ * is fundamentally flawed during deep suspend. If a device sleeps for
+ * longer than half the overflow period (e.g. 45 minutes), the massive
+ * legitimate forward leap in time is mathematically aliased as a backward
+ * jump.
+ *
+ * This would historically cause the logic to forcibly inject a negative
+ * `overflow_period` adjustment, irrevocably corrupting the sensor's
+ * timestamps backwards by ~71 minutes upon resume and failing CTS.
+ *
+ * By eliminating the negative adjustment path and exclusively evaluating
+ * `state->last - *ts > (overflow_period / 2)` via signed arithmetic, we
+ * ensure that multi-minute sleep leaps bypass the threshold safely as
+ * large negative relative differentials, naturally carrying time forward
+ * without bogus timestamp rollbacks. Furthermore, the massive timestamp
+ * differential will naturally trigger the TS_HISTORY_BORED_US threshold
+ * downstream, safely resetting the historical median filter array.
+ */
+ if (state->last - *ts > (overflow_period / 2)) {
+ state->offset += overflow_period;
+ *ts += overflow_period;
}
state->last = *ts;
}
diff --git a/include/linux/platform_data/cros_ec_sensorhub.h b/include/linux/platform_data/cros_ec_sensorhub.h
index 0ecce6aa69d5..498a7d827b19 100644
--- a/include/linux/platform_data/cros_ec_sensorhub.h
+++ b/include/linux/platform_data/cros_ec_sensorhub.h
@@ -175,6 +175,8 @@ struct cros_ec_sensorhub {
s64 future_timestamp_total_ns;
struct cros_ec_sensorhub_sensor_push_data *push_data;
+
+ ktime_t suspend_time;
};
int cros_ec_sensorhub_register_push_data(struct cros_ec_sensorhub *sensorhub,
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 2/6] platform/chrome: cros_ec_sensorhub: Fix TS filter history shift index
2026-10-14 7:43 [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 1/6] platform/chrome: cros_ec_sensorhub: Fix AP/EC TS wrap Satyam Gupta
@ 2026-10-14 7:43 ` Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 3/6] platform/chrome: cros_ec_sensorhub: Clamp clock drift slope to MAX_DRIFT_PPM Satyam Gupta
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Satyam Gupta @ 2026-10-14 7:43 UTC (permalink / raw)
To: Benson Leung, Tzung-Bi Shih
Cc: Guenter Roeck, Gwendal Grignou, Scott Collyer, chrome-platform,
linux-kernel, Satyam Gupta
From: Scott Collyer <scollyer@google.com>
When propagating timestamp filter history entries in
cros_ec_sensor_ring_ts_filter_update(), starting the shift loop at
state->history_len - 1 skips shifting x_history[0] into x_history[1]
when history_len < CROS_EC_SENSORHUB_TS_HISTORY_SIZE. Conversely,
starting unconditionally at state->history_len would overrun the array
once the buffer is full.
Bound the loop starting index with min_t(int, state->history_len,
CROS_EC_SENSORHUB_TS_HISTORY_SIZE - 1) so new entries shift existing
elements properly while dropping the oldest element when full.
Signed-off-by: Scott Collyer <scollyer@google.com>
Signed-off-by: Satyam Gupta <sgsatyam@google.com>
---
drivers/platform/chrome/cros_ec_sensorhub_ring.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index cc038af59218..6975592c6b05 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -259,7 +259,7 @@ cros_ec_sensor_ring_ts_filter_update(struct cros_ec_sensors_ts_filter_state
s64 m; /* stored as *M_PRECISION */
s64 *m_history_copy = state->temp_buf;
s64 *error = state->temp_buf;
- int i;
+ int i, start;
/* we trust b the most, that'll be our independent variable */
x = b;
@@ -277,7 +277,9 @@ cros_ec_sensor_ring_ts_filter_update(struct cros_ec_sensors_ts_filter_state
state->history_len = 0;
/* Move everything over, also update offset to all absolute coords .*/
- for (i = state->history_len - 1; i >= 1; i--) {
+ start = min_t(int, state->history_len,
+ CROS_EC_SENSORHUB_TS_HISTORY_SIZE - 1);
+ for (i = start; i >= 1; i--) {
state->x_history[i] = state->x_history[i - 1] + dx;
state->y_history[i] = state->y_history[i - 1] + dy;
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 3/6] platform/chrome: cros_ec_sensorhub: Clamp clock drift slope to MAX_DRIFT_PPM
2026-10-14 7:43 [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 1/6] platform/chrome: cros_ec_sensorhub: Fix AP/EC TS wrap Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 2/6] platform/chrome: cros_ec_sensorhub: Fix TS filter history shift index Satyam Gupta
@ 2026-10-14 7:43 ` Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 4/6] platform/chrome: cros_ec_sensorhub: Reset TS filter on ODR or mode changes Satyam Gupta
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Satyam Gupta @ 2026-10-14 7:43 UTC (permalink / raw)
To: Benson Leung, Tzung-Bi Shih
Cc: Guenter Roeck, Gwendal Grignou, Scott Collyer, chrome-platform,
linux-kernel, Satyam Gupta
From: Scott Collyer <scollyer@google.com>
Temporary interrupt jitter spikes during sensor batching can produce
extreme instantaneous drift slopes (exceeding 20,000 Parts Per Million
(PPM)) that corrupt the timestamp median filter history and cause Out Of
Order (OOO) sensor events.
Clamp the calculated drift slope m within +/- MAX_DRIFT_PPM (5000 PPM)
so the filter can track expected clock frequency drift across both
Integrated Sensor Hub (ISH) and standalone Embedded Controller (EC)
configurations (which can drift by ~2,500 PPM when running on an
independent crystal/PLL), while rejecting large interrupt jitter spikes.
Signed-off-by: Scott Collyer <scollyer@google.com>
Signed-off-by: Satyam Gupta <sgsatyam@google.com>
---
drivers/platform/chrome/cros_ec_sensorhub_ring.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index 6975592c6b05..ea70847c8792 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -22,6 +22,8 @@
/* Precision of fixed point for the m values from the filter */
#define M_PRECISION BIT(23)
+#define MAX_DRIFT_PPM 5000LL
+#define MAX_M ((s64)(MAX_DRIFT_PPM * M_PRECISION / 1000000))
/* Only activate the filter once we have at least this many elements. */
#define TS_HISTORY_THRESHOLD 8
@@ -271,6 +273,12 @@ cros_ec_sensor_ring_ts_filter_update(struct cros_ec_sensors_ts_filter_state
return; /* we already have this irq in the history */
dy = (state->y_history[0] + state->y_offset) - y;
m = div64_s64(dy * M_PRECISION, dx);
+ /*
+ * Clamp the calculated slope to a realistic range (+/- 5000 ppm).
+ * Temporary large jitter spikes can produce huge slopes (e.g. +/- 20000 ppm)
+ * that would otherwise corrupt the median filter history.
+ */
+ m = clamp(m, -MAX_M, MAX_M);
/* Empty filter if we haven't seen any action in a while. */
if (-dx > TS_HISTORY_BORED_US)
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 4/6] platform/chrome: cros_ec_sensorhub: Reset TS filter on ODR or mode changes
2026-10-14 7:43 [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes Satyam Gupta
` (2 preceding siblings ...)
2026-10-14 7:43 ` [PATCH v5 3/6] platform/chrome: cros_ec_sensorhub: Clamp clock drift slope to MAX_DRIFT_PPM Satyam Gupta
@ 2026-10-14 7:43 ` Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 5/6] platform/chrome: cros_ec_sensorhub: Increase TS_HISTORY_BORED_US to 2s Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 6/6] platform/chrome: cros_ec_sensorhub: Drop sensor samples with past timestamps Satyam Gupta
5 siblings, 0 replies; 7+ messages in thread
From: Satyam Gupta @ 2026-10-14 7:43 UTC (permalink / raw)
To: Benson Leung, Tzung-Bi Shih
Cc: Guenter Roeck, Gwendal Grignou, Scott Collyer, chrome-platform,
linux-kernel, Satyam Gupta
From: Scott Collyer <scollyer@google.com>
Detect Output Data Rate (ODR) or mode transitions (such as switching
between active streaming and low-frequency batching) where the time
delta (dx) between consecutive interrupts changes by more than 10x, and
reset the timestamp filter history. This prevents mixing noisy active
streaming samples with larger batched intervals in the median filter.
Signed-off-by: Scott Collyer <scollyer@google.com>
Signed-off-by: Satyam Gupta <sgsatyam@google.com>
---
drivers/platform/chrome/cros_ec_sensorhub_ring.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index ea70847c8792..4d814e2d7297 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -280,6 +280,21 @@ cros_ec_sensor_ring_ts_filter_update(struct cros_ec_sensors_ts_filter_state
*/
m = clamp(m, -MAX_M, MAX_M);
+ /*
+ * Detect ODR (Output Data Rate) or Mode changes (e.g., transition from
+ * active streaming to low-frequency batching). If the time delta (dx)
+ * changes by more than 10x in either direction, reset the filter history
+ * to prevent mixing noisy active samples with batching samples.
+ */
+ if (state->history_len > 1) {
+ s64 prev_dx = -state->x_history[1];
+
+ if (prev_dx > 0 && (abs(dx) > 10 * prev_dx || prev_dx > 10 * abs(dx))) {
+ state->history_len = 0;
+ m = 0;
+ }
+ }
+
/* Empty filter if we haven't seen any action in a while. */
if (-dx > TS_HISTORY_BORED_US)
state->history_len = 0;
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 5/6] platform/chrome: cros_ec_sensorhub: Increase TS_HISTORY_BORED_US to 2s
2026-10-14 7:43 [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes Satyam Gupta
` (3 preceding siblings ...)
2026-10-14 7:43 ` [PATCH v5 4/6] platform/chrome: cros_ec_sensorhub: Reset TS filter on ODR or mode changes Satyam Gupta
@ 2026-10-14 7:43 ` Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 6/6] platform/chrome: cros_ec_sensorhub: Drop sensor samples with past timestamps Satyam Gupta
5 siblings, 0 replies; 7+ messages in thread
From: Satyam Gupta @ 2026-10-14 7:43 UTC (permalink / raw)
To: Benson Leung, Tzung-Bi Shih
Cc: Guenter Roeck, Gwendal Grignou, Scott Collyer, chrome-platform,
linux-kernel, Satyam Gupta
From: Scott Collyer <scollyer@google.com>
Increase the TS_HISTORY_BORED_US gap threshold from 0.5 seconds
(500,000 us) to 2.0 seconds (2,000,000 us) to accommodate normal sensor
batching flush intervals (which can be 1 to 2 seconds long) without
repeatedly tearing down the timestamp filter, while still resetting the
filter across actual long idle gaps or suspend.
Signed-off-by: Scott Collyer <scollyer@google.com>
Signed-off-by: Satyam Gupta <sgsatyam@google.com>
---
drivers/platform/chrome/cros_ec_sensorhub_ring.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index 4d814e2d7297..7740bb42b1df 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -30,9 +30,13 @@
/*
* If we don't have any history entries for this long, empty the filter to
- * make sure there are no big discontinuities.
+ * make sure there are no big discontinuities (e.g. after suspend or long idle).
+ *
+ * This is set to 2 seconds to accommodate normal batching flush intervals
+ * (which can be up to 1-2 seconds) without constantly resetting the filter,
+ * while still ensuring a reset occurs during actual long gaps or suspend.
*/
-#define TS_HISTORY_BORED_US 500000
+#define TS_HISTORY_BORED_US 2000000
/* To measure by how much the filter is overshooting, if it happens. */
#define FUTURE_TS_ANALYTICS_COUNT_MAX 100
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 6/6] platform/chrome: cros_ec_sensorhub: Drop sensor samples with past timestamps
2026-10-14 7:43 [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes Satyam Gupta
` (4 preceding siblings ...)
2026-10-14 7:43 ` [PATCH v5 5/6] platform/chrome: cros_ec_sensorhub: Increase TS_HISTORY_BORED_US to 2s Satyam Gupta
@ 2026-10-14 7:43 ` Satyam Gupta
5 siblings, 0 replies; 7+ messages in thread
From: Satyam Gupta @ 2026-10-14 7:43 UTC (permalink / raw)
To: Benson Leung, Tzung-Bi Shih
Cc: Guenter Roeck, Gwendal Grignou, Scott Collyer, chrome-platform,
linux-kernel, Satyam Gupta
From: Scott Collyer <scollyer@google.com>
When a sensor event timestamp is strictly earlier than the newest
timestamp previously seen for that sensor, drop the Out Of Order (OOO)
sample instead of clamping its timestamp to last_ts. Clamping past
samples to last_ts previously caused downstream batch spreading logic
(cros_ec_sensor_ring_spread_add()) to treat stale events as a batch of
identical timestamps.
Rename cros_ec_sensor_ring_check_for_past_timestamp() to
cros_ec_sensor_ring_is_past_timestamp() returning true when the sample
timestamp is in the past.
Signed-off-by: Scott Collyer <scollyer@google.com>
Signed-off-by: Satyam Gupta <sgsatyam@google.com>
---
.../platform/chrome/cros_ec_sensorhub_ring.c | 36 +++++++++++--------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index 7740bb42b1df..a5215955470f 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -427,23 +427,29 @@ cros_ec_sensor_ring_fix_overflow(s64 *ts,
state->last = *ts;
}
-static void
-cros_ec_sensor_ring_check_for_past_timestamp(struct cros_ec_sensorhub
- *sensorhub,
- struct cros_ec_sensors_ring_sample
- *sample)
+static bool
+cros_ec_sensor_ring_is_past_timestamp(struct cros_ec_sensorhub *sensorhub,
+ struct cros_ec_sensors_ring_sample *sample)
{
const u8 sensor_id = sample->sensor_id;
- /* If this event is earlier than one we saw before... */
+ /*
+ * If this event is strictly earlier than one we saw before, it is truly
+ * out-of-order and must be dropped to preserve monotonicity.
+ *
+ * We intentionally allow duplicate timestamps (==) to pass through here
+ * because the EC/ISH may report a batch of samples with the same raw
+ * timestamp. These duplicates are required by the downstream spreading
+ * logic (cros_ec_sensor_ring_spread_add) to interpolate unique,
+ * monotonic timestamps for each sample in the batch.
+ */
if (sensorhub->batch_state[sensor_id].newest_sensor_event >
sample->timestamp)
- /* mark it for spreading. */
- sample->timestamp =
- sensorhub->batch_state[sensor_id].last_ts;
- else
- sensorhub->batch_state[sensor_id].newest_sensor_event =
- sample->timestamp;
+ return true;
+
+ sensorhub->batch_state[sensor_id].newest_sensor_event =
+ sample->timestamp;
+ return false;
}
/**
@@ -576,8 +582,10 @@ cros_ec_sensor_ring_process_event(struct cros_ec_sensorhub *sensorhub,
for (axis = 0; axis < 3; axis++)
out->vector[axis] = in->data[axis];
- if (sensorhub->tight_timestamps)
- cros_ec_sensor_ring_check_for_past_timestamp(sensorhub, out);
+ if (sensorhub->tight_timestamps) {
+ if (cros_ec_sensor_ring_is_past_timestamp(sensorhub, out))
+ return false;
+ }
return true;
}
--
2.56.0.385.gd3acb90ef8-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-14 7:43 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-14 7:43 [PATCH v5 0/6] platform/chrome: cros_ec_sensorhub: Timestamp wrap and drift filter fixes Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 1/6] platform/chrome: cros_ec_sensorhub: Fix AP/EC TS wrap Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 2/6] platform/chrome: cros_ec_sensorhub: Fix TS filter history shift index Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 3/6] platform/chrome: cros_ec_sensorhub: Clamp clock drift slope to MAX_DRIFT_PPM Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 4/6] platform/chrome: cros_ec_sensorhub: Reset TS filter on ODR or mode changes Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 5/6] platform/chrome: cros_ec_sensorhub: Increase TS_HISTORY_BORED_US to 2s Satyam Gupta
2026-10-14 7:43 ` [PATCH v5 6/6] platform/chrome: cros_ec_sensorhub: Drop sensor samples with past timestamps Satyam Gupta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®