From: Bryan O'Donoghue Date: Tue, 2 Aug 2016 12:18:30 +0000 (+0100) Subject: greybus: timesync: Implement a retry mechanism X-Git-Tag: v4.9-rc1~119^2~378^2~21^2~88 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=7aa278b771505f8fb85406a891af0b7743710620;p=karo-tx-linux.git greybus: timesync: Implement a retry mechanism 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 Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/timesync.c b/drivers/staging/greybus/timesync.c index ec0a51d6378d..744ae0c9d586 100644 --- a/drivers/staging/greybus/timesync.c +++ b/drivers/staging/greybus/timesync.c @@ -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;