]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
greybus: timesync: Do 64 bit divisions in a 32 friendly way
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>
Fri, 10 Jun 2016 15:10:12 +0000 (16:10 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 10 Jun 2016 23:26:31 +0000 (16:26 -0700)
We need to use 'do_div()' when doing 64 bit division or modulo division
since the kernel will not pull in the gcc builtins __aeabi_ldivmod and
__aeabi_uldivmod on 32 bit builds.

Reported-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/timesync.c

index 87cbe10a5ae7a502cd4ed57b900676ab4b9a26b6..a029fa085af6e54a13052d82d9116859d6f527be 100644 (file)
@@ -502,8 +502,7 @@ static int gb_timesync_to_timespec(struct gb_timesync_svc *timesync_svc,
                                   u64 frame_time, struct timespec *ts)
 {
        unsigned long flags;
-       u64 delta_fs, counts;
-       u32 sec, nsec;
+       u64 delta_fs, counts, sec, nsec;
        bool add;
        int ret = 0;
 
@@ -532,8 +531,15 @@ static int gb_timesync_to_timespec(struct gb_timesync_svc *timesync_svc,
 
        /* Determine the time difference in femtoseconds */
        delta_fs = counts * gb_timesync_fs_per_clock;
-       sec = delta_fs / FSEC_PER_SEC;
-       nsec = (delta_fs % FSEC_PER_SEC) / 1000000UL;
+
+       /* Convert to seconds */
+       sec = delta_fs;
+       do_div(sec, NSEC_PER_SEC);
+       do_div(sec, 1000000UL);
+
+       /* Get the nanosecond remainder */
+       nsec = do_div(delta_fs, sec);
+       do_div(nsec, 1000000UL);
 
        if (add) {
                /* Add the calculated offset - overflow nanoseconds upwards */
@@ -548,7 +554,7 @@ static int gb_timesync_to_timespec(struct gb_timesync_svc *timesync_svc,
                if (nsec > timesync_svc->ktime_data.ts.tv_nsec) {
                        sec++;
                        nsec = nsec + timesync_svc->ktime_data.ts.tv_nsec;
-                       nsec %= NSEC_PER_SEC;
+                       nsec = do_div(nsec, NSEC_PER_SEC);
                } else {
                        nsec = timesync_svc->ktime_data.ts.tv_nsec - nsec;
                }
@@ -1318,8 +1324,10 @@ int __init gb_timesync_init(void)
        gb_timesync_clock_rate = gb_timesync_platform_get_clock_rate();
 
        /* Calculate nanoseconds and femtoseconds per clock */
-       gb_timesync_fs_per_clock = FSEC_PER_SEC / gb_timesync_clock_rate;
-       gb_timesync_ns_per_clock = NSEC_PER_SEC / gb_timesync_clock_rate;
+       gb_timesync_fs_per_clock = FSEC_PER_SEC;
+       do_div(gb_timesync_fs_per_clock, gb_timesync_clock_rate);
+       gb_timesync_ns_per_clock = NSEC_PER_SEC;
+       do_div(gb_timesync_ns_per_clock, gb_timesync_clock_rate);
 
        /* Calculate the maximum number of clocks we will convert to ktime */
        gb_timesync_max_ktime_diff =