From: Graeme Foot <graeme.foot@touchcut.com>
Date: Tue, 24 Sep 2019 14:08:26 +1200

Hot plugged slaves can fail to read DC register straight away.
This patch adds a working_counter value of zero as a retry condition.

diff --git a/master/fsm_slave_scan.c b/master/fsm_slave_scan.c
--- a/master/fsm_slave_scan.c
+++ b/master/fsm_slave_scan.c
@@ -51,6 +51,15 @@
  */
 #define SCAN_RETRY_TIME 100
 
+/** DC System Time retry timeout [ms].
+ *
+ * Used to calculate timeouts bsed on the jiffies counter.
+ *
+ * \attention Must be more than 10 to avoid problems on kernels that run with
+ * a timer interupt frequency of 100 Hz.
+ */
+#define DC_SYSTEM_TIME_TIMEOUT 200
+
 /*****************************************************************************/
 
 void ec_fsm_slave_scan_state_start(ec_fsm_slave_scan_t *, ec_datagram_t *);
@@ -375,6 +384,8 @@
                 slave->base_dc_range == EC_DC_64 ? 8 : 4);
         ec_datagram_zero(datagram);
         fsm->retries = EC_FSM_RETRIES;
+        fsm->scan_jiffies_start = jiffies;
+        fsm->dc_system_time_retry = 0;
         fsm->state = ec_fsm_slave_scan_state_dc_cap;
     } else {
         ec_fsm_slave_scan_enter_datalink(fsm, datagram);
@@ -408,9 +419,31 @@
 
     if (fsm->datagram->working_counter == 1) {
         slave->has_dc_system_time = 1;
-        EC_SLAVE_DBG(slave, 1, "Slave has the System Time register.\n");
+        if (fsm->dc_system_time_retry) {
+            EC_SLAVE_INFO(slave, "Slave has the System Time register.\n");
+        } else {
+            EC_SLAVE_DBG(slave, 1, "Slave has the System Time register.\n");
+        }
     } else if (fsm->datagram->working_counter == 0) {
-        EC_SLAVE_DBG(slave, 1, "Slave has no System Time register; delay "
+        // this may be due to supporting delay measurement only
+        // or the slave has still not fully initialised
+        // retry until we timeout
+        unsigned long diff_ms;
+
+        if (fsm->dc_system_time_retry == 0) {
+            fsm->dc_system_time_retry = 1;
+            EC_SLAVE_WARN(slave, "Slave did not respond to System Time "
+                    "register request, retrying...\n");
+        }
+
+        diff_ms = (fsm->datagram->jiffies_received -
+                fsm->scan_jiffies_start) * 1000 / HZ;
+        if (diff_ms < DC_SYSTEM_TIME_TIMEOUT) {
+            ec_datagram_repeat(datagram, fsm->datagram);
+            return;
+        }
+
+        EC_SLAVE_INFO(slave, "Slave has no System Time register; delay "
                 "measurement only.\n");
     } else {
         fsm->slave->error_flag = 1;
diff --git a/master/fsm_slave_scan.h b/master/fsm_slave_scan.h
--- a/master/fsm_slave_scan.h
+++ b/master/fsm_slave_scan.h
@@ -62,6 +62,7 @@
     unsigned int retries; /**< Retries on datagram timeout. */
     unsigned int scan_retries; /**< Retries on scan read error. */
     unsigned long scan_jiffies_start; /**< scan retry start timestamp. */
+    uint8_t dc_system_time_retry; /**< rechecking system time register */
 
     void (*state)(ec_fsm_slave_scan_t *, ec_datagram_t *); /**< State function. */
     uint16_t sii_offset; /**< SII offset in words. */
