dd: Invoke one probe retry cycle after every initcall level

Drivers that are registered at an initcall level may have to
wait until late_init before the probe deferral mechanism can
retry their probe functions. It is possible that their
dependencies were resolved much earlier, in some cases even
before the next initcall level. Invoke one probe retry cycle
at every _sync initcall level, allowing these drivers to be
probed earlier.

A real world example of how this change helps follows. On the
MSM8974, there are 3 devices that need to be probed in order
for the display driver to be able to probe and bring up a
display panel. These are the gdsc_mdss (a regulator device), the
mmsscc-dsi device (a display clock controller), and the
dsipllcc device (a PLL controller). Here is a kernel log that
shows these devices probing in the wrong order:

[0.503253] mmsscc-dsi fd8c0000.qcom,mmsscc-dsi: Failed to get
		pixel source. -- [1]
[0.505210] dsipllcc fd8c0000.qcom,dsipllcc: Failed to get MDSS
		GDSC         -- [2]
[0.523264] gdsc_mdss: no parameters
		             -- [3]

Only gdsc_mdss successfully probed at 0.52 seconds. Now without
_this_ change, the current probe deferral mechanism results in
the devices probing at or after late_init:

[9.196006] dsipllcc fd8c0000.qcom,dsipllcc: Registered DSI PLL
		clocks.        -- [2]
[9.357440] mmsscc-dsi fd8c0000.qcom,mmsscc-dsi: Registered MMSSCC DSI
		clocks. -- [1]

Thus the display can only be brought up after 9.35 seconds. However,
by allowing a probe retry after each initcall level, this number
reduces drastically:

[0.608252] dsipllcc fd8c0000.qcom,dsipllcc: Registered DSI PLL
		clocks.       -- [2]
[0.613758] mmsscc-dsi fd8c0000.qcom,mmsscc-dsi: Registered MMSSCC DSI
		clocks.-- [1]

Thus the display can be brought up just after 0.61 seconds.

Change-Id: I83d8ac89e591e89e27934c0402449437b61b2124
Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index d76cd97..f95593a 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -201,22 +201,43 @@
 	driver_deferred_probe_trigger();
 }
 
+static void enable_trigger_defer_cycle(void)
+{
+	driver_deferred_probe_enable = true;
+	driver_deferred_probe_trigger();
+	/*
+	 * Sort as many dependencies as possible before the next initcall
+	 * level
+	 */
+	flush_work(&deferred_probe_work);
+}
+
 /**
  * deferred_probe_initcall() - Enable probing of deferred devices
  *
  * We don't want to get in the way when the bulk of drivers are getting probed.
  * Instead, this initcall makes sure that deferred probing is delayed until
- * late_initcall time.
+ * all the registered initcall functions at a particular level are completed.
+ * This function is invoked at every *_initcall_sync level.
  */
 static int deferred_probe_initcall(void)
 {
-	driver_deferred_probe_enable = true;
-	driver_deferred_probe_trigger();
-	/* Sort as many dependencies as possible before exiting initcalls */
-	flush_work(&deferred_probe_work);
+	enable_trigger_defer_cycle();
+	driver_deferred_probe_enable = false;
 	return 0;
 }
-late_initcall(deferred_probe_initcall);
+arch_initcall_sync(deferred_probe_initcall);
+subsys_initcall_sync(deferred_probe_initcall);
+fs_initcall_sync(deferred_probe_initcall);
+device_initcall_sync(deferred_probe_initcall);
+
+static int deferred_probe_enable_fn(void)
+{
+	/* Enable deferred probing for all time */
+	enable_trigger_defer_cycle();
+	return 0;
+}
+late_initcall(deferred_probe_enable_fn);
 
 /**
  * device_is_bound() - Check if device is bound to a driver