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 <tomas.melin@vaisala.com>
---
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..6740c3aed1897d4b50a02c4823a746d9c2ae2655 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
Hi Tomas, kernel test robot noticed the following build errors: [auto build test ERROR on abelloni/rtc-next] [also build test ERROR on xilinx-xlnx/master linus/master v6.19-rc5] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Tomas-Melin/rtc-zynqmp-check-calibration-max-value/20260108-223800 base: https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next patch link: https://lore.kernel.org/r/20260108-zynqmp-rtc-updates-v2-3-864c161fa83d%40vaisala.com patch subject: [PATCH v2 3/5] rtc: zynqmp: rework read_offset config: arm-allyesconfig (https://download.01.org/0day-ci/archive/20260115/202601150836.Yk8DcSZW-lkp@intel.com/config) compiler: arm-linux-gnueabi-gcc (GCC) 15.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260115/202601150836.Yk8DcSZW-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202601150836.Yk8DcSZW-lkp@intel.com/ All errors (new ones prefixed by >>): arm-linux-gnueabi-ld: drivers/spi/spi-amlogic-spifc-a4.o: in function `aml_sfc_set_bus_width': spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0x8c): undefined reference to `__ffsdi2' arm-linux-gnueabi-ld: spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0xac): undefined reference to `__ffsdi2' arm-linux-gnueabi-ld: spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0xcc): undefined reference to `__ffsdi2' arm-linux-gnueabi-ld: drivers/rtc/rtc-zynqmp.o: in function `xlnx_rtc_read_offset': >> rtc-zynqmp.c:(.text.xlnx_rtc_read_offset+0xd0): undefined reference to `__aeabi_ldivmod' >> arm-linux-gnueabi-ld: rtc-zynqmp.c:(.text.xlnx_rtc_read_offset+0x15c): undefined reference to `__aeabi_ldivmod' -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Hi, On 15/01/2026 02:42, kernel test robot wrote: > > arm-linux-gnueabi-ld: drivers/spi/spi-amlogic-spifc-a4.o: in function `aml_sfc_set_bus_width': > spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0x8c): undefined reference to `__ffsdi2' > arm-linux-gnueabi-ld: spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0xac): undefined reference to `__ffsdi2' > arm-linux-gnueabi-ld: spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0xcc): undefined reference to `__ffsdi2' > arm-linux-gnueabi-ld: drivers/rtc/rtc-zynqmp.o: in function `xlnx_rtc_read_offset': >>> rtc-zynqmp.c:(.text.xlnx_rtc_read_offset+0xd0): undefined reference to `__aeabi_ldivmod' >>> arm-linux-gnueabi-ld: rtc-zynqmp.c:(.text.xlnx_rtc_read_offset+0x15c): undefined reference to `__aeabi_ldivmod' AFAIU this is related to compiling for arm 32 bit target. Is this error relevant since this driver is for aarch64 zynqmp specifically? If so, what would be correct way of fixing? Thanks, Tomas >
On 15/01/2026 09:41, Tomas Melin wrote: > Hi, > > On 15/01/2026 02:42, kernel test robot wrote: > >> >> arm-linux-gnueabi-ld: drivers/spi/spi-amlogic-spifc-a4.o: in function `aml_sfc_set_bus_width': >> spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0x8c): undefined reference to `__ffsdi2' >> arm-linux-gnueabi-ld: spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0xac): undefined reference to `__ffsdi2' >> arm-linux-gnueabi-ld: spi-amlogic-spifc-a4.c:(.text.aml_sfc_set_bus_width+0xcc): undefined reference to `__ffsdi2' >> arm-linux-gnueabi-ld: drivers/rtc/rtc-zynqmp.o: in function `xlnx_rtc_read_offset': >>>> rtc-zynqmp.c:(.text.xlnx_rtc_read_offset+0xd0): undefined reference to `__aeabi_ldivmod' >>>> arm-linux-gnueabi-ld: rtc-zynqmp.c:(.text.xlnx_rtc_read_offset+0x15c): undefined reference to `__aeabi_ldivmod' > AFAIU this is related to compiling for arm 32 bit target. Is this error > relevant since this driver is for aarch64 zynqmp specifically? If so, > what would be correct way of fixing? Answering my self, I think correct course of action here is probably to limit building of this driver for the zynqmp architecture. I will add this in next version. Thanks, Tomas > > Thanks, > Tomas > > > >> > >
© 2016 - 2026 Red Hat, Inc.