On Tue. 10 Sep. 2024 at 01:24, Nathan Chancellor <nathan@xxxxxxxxxx> wrote: > When building with clang for a 32-bit target, such as arm, a libcall is > generated when dividing the result of clocksource_cyc2ns(), which > returns a signed 64-bit integer: > > ERROR: modpost: "__aeabi_ldivmod" [drivers/net/can/rockchip/rockchip_canfd.ko] undefined! > > Use div_s64() to avoid generating the libcall. > > Fixes: 4e1a18bab124 ("can: rockchip_canfd: add hardware timestamping support") > Signed-off-by: Nathan Chancellor <nathan@xxxxxxxxxx> > --- > This does not happen with GCC, likely because it implements > optimizations for division by a constant that clang does not implement. > --- > drivers/net/can/rockchip/rockchip_canfd-timestamp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/net/can/rockchip/rockchip_canfd-timestamp.c b/drivers/net/can/rockchip/rockchip_canfd-timestamp.c > index 81cccc5fd8384ee1fec919077db48632f0fe7cc2..4ca01d385ffffdeec964b7fd954d8ba3ba3a1381 100644 > --- a/drivers/net/can/rockchip/rockchip_canfd-timestamp.c > +++ b/drivers/net/can/rockchip/rockchip_canfd-timestamp.c > @@ -71,7 +71,7 @@ void rkcanfd_timestamp_init(struct rkcanfd_priv *priv) > > max_cycles = div_u64(ULLONG_MAX, cc->mult); > max_cycles = min(max_cycles, cc->mask); > - work_delay_ns = clocksource_cyc2ns(max_cycles, cc->mult, cc->shift) / 3; > + work_delay_ns = div_s64(clocksource_cyc2ns(max_cycles, cc->mult, cc->shift), 3); I was surprised at first to see div_s64() instead of div_u64(), but clocksource_cyc2ns() indeed returns a s64. So this looks correct. > priv->work_delay_jiffies = nsecs_to_jiffies(work_delay_ns); > INIT_DELAYED_WORK(&priv->timestamp, rkcanfd_timestamp_work); Reviewed-by: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx>