]> git.karo-electronics.de Git - linux-beck.git/commitdiff
greybus: timesync: Implement a retry mechanism
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>
Tue, 2 Aug 2016 12:18:30 +0000 (13:18 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 3 Aug 2016 08:59:13 +0000 (10:59 +0200)
It's possible the AP could miss an incoming SVC timesync pulse i.e. the AP
could have interrupts switched off for long enough that one SVC GPIO strobe
ends up over-lapping another one. TimeSync should be able to deal with this
type of transitory failure by retrying a failed synchronous TimeSync resync
up to 'n' number of times. For this patch 'n' has been set to five, which
is a hand-wavy choice that 'feels' right.

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 ec0a51d6378d2adf0111158724c3c32a439eb6df..744ae0c9d586d6b97fb026323c798600cfacf95e 100644 (file)
@@ -34,6 +34,9 @@
 #define GB_TIMESYNC_KTIME_UPDATE               msecs_to_jiffies(1000)
 #define GB_TIMESYNC_MAX_KTIME_CONVERSION       15
 
+/* Maximum number of times we'll retry a failed synchronous sync */
+#define GB_TIMESYNC_MAX_RETRIES                        5
+
 /* Reported nanoseconds/femtoseconds per clock */
 static u64 gb_timesync_ns_per_clock;
 static u64 gb_timesync_fs_per_clock;
@@ -870,19 +873,26 @@ int gb_timesync_schedule_synchronous(struct gb_interface *interface)
 {
        int ret;
        struct gb_timesync_svc *timesync_svc;
+       int retries;
 
        if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
                return 0;
 
        mutex_lock(&gb_timesync_svc_list_mutex);
-       timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
-       if (!timesync_svc) {
-               ret = -ENODEV;
-               goto done;
-       }
+       for (retries = 0; retries < GB_TIMESYNC_MAX_RETRIES; retries++) {
+               timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
+               if (!timesync_svc) {
+                       ret = -ENODEV;
+                       goto done;
+               }
 
-       ret = __gb_timesync_schedule_synchronous(timesync_svc,
+               ret = __gb_timesync_schedule_synchronous(timesync_svc,
                                                 GB_TIMESYNC_STATE_INIT);
+               if (!ret)
+                       break;
+       }
+       if (ret && retries == GB_TIMESYNC_MAX_RETRIES)
+               ret = -ETIMEDOUT;
 done:
        mutex_unlock(&gb_timesync_svc_list_mutex);
        return ret;