Thread (16 messages) 16 messages, 3 authors, 2026-01-19

RE: [PATCH v2 3/5] rtc: zynqmp: rework read_offset

From: T, Harini <hidden>
Date: 2026-01-14 15:36:20
Also in: linux-rtc, lkml

[Public]

Reviewed-by: Harini T <redacted>

Thanks,
Harini T
quoted hunk ↗ jump to hunk
-----Original Message-----
From: Tomas Melin <redacted>
Sent: Thursday, January 8, 2026 6:21 PM
To: Alexandre Belloni <alexandre.belloni@bootlin.com>; Simek, Michal
[off-list ref]
Cc: linux-rtc@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
kernel@vger.kernel.org; Tomas Melin [off-list ref]
Subject: [PATCH v2 3/5] rtc: zynqmp: rework read_offset

Caution: This message originated from an External Source. Use proper
caution when opening attachments, clicking links, or responding.


read_offset() was using static frequency for determining the tick offset. It was
also using remainder from do_div() operation as tick_mult value which
caused the offset to be incorrect.

At the same time, rework function to improve readability.
It is worth noting, that due to rounding errors, the offset readback will differ
slightly for positive and negative calibration values.

Signed-off-by: Tomas Melin <redacted>
---
 drivers/rtc/rtc-zynqmp.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index
caacce3725e2ef3803ea42d40e77ceaeb7d7b914..6740c3aed1897d4b50a02c4
823a746d9c2ae2655 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -178,21 +178,28 @@ static void xlnx_init_rtc(struct xlnx_rtc_dev
*xrtcdev)  static int xlnx_rtc_read_offset(struct device *dev, long *offset)  {
        struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
-       unsigned long long rtc_ppb = RTC_PPB;
-       unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq);
-       unsigned int calibval;
+       unsigned int calibval, fract_data, fract_part;
+       int freq = xrtcdev->freq;
+       int max_tick, tick_mult;
        long offset_val;

+       /* Tick to offset multiplier */
+       tick_mult = DIV_ROUND_CLOSEST(RTC_PPB, freq);
+
        calibval = readl(xrtcdev->reg_base + RTC_CALIB_RD);
        /* Offset with seconds ticks */
-       offset_val = calibval & RTC_TICK_MASK;
-       offset_val = offset_val - RTC_CALIB_DEF;
-       offset_val = offset_val * tick_mult;
+       max_tick = calibval & RTC_TICK_MASK;
+       offset_val = max_tick - freq;
+       /* Convert to ppb */
+       offset_val *= tick_mult;

        /* Offset with fractional ticks */
-       if (calibval & RTC_FR_EN)
-               offset_val += ((calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT)
-                       * (tick_mult / RTC_FR_MAX_TICKS);
+       if (calibval & RTC_FR_EN) {
+               fract_data = (calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT;
+               fract_part = DIV_ROUND_UP(tick_mult, RTC_FR_MAX_TICKS);
+               offset_val += (fract_part * fract_data);
+       }
+
        *offset = offset_val;

        return 0;

--
2.47.3
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help