ARM: qcom: Add CONFIG_ARCH_MSM8953_BOOT_ORDERING

Populate the devicetree at late init, after all platform device drivers
are registered. Devices are probed in the order they are listed in
devicetree, allowing greater flexibility for optimization.

Change-Id: I2b49bba49d8a36d26a6f53d517125af0cdc5656a
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 1ab1fbb..b055b60 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -65,6 +65,17 @@
 	select HAVE_CLK_PREPARE
 	select COMMON_CLK_MSM
 
+config ARCH_MSM8953_BOOT_ORDERING
+	bool "Enable support for MSM8953 device boot ordering"
+	default n
+	help
+	  Populate devices from devicetree at late_init, after
+	  drivers for all platform devices have been registered.
+	  This causes devices to be probed in the order they are
+	  listed in devicetree. Thus it is possible to have
+	  greater control over the probe ordering such that
+	  overall boot time can be reduced.
+
 config ARCH_MSM8937
 	bool "Enable support for MSM8937"
 	select CPU_V7
diff --git a/arch/arm/mach-qcom/board-msm8953.c b/arch/arm/mach-qcom/board-msm8953.c
index 04b0bcc..de4538f 100644
--- a/arch/arm/mach-qcom/board-msm8953.c
+++ b/arch/arm/mach-qcom/board-msm8953.c
@@ -14,6 +14,7 @@
 #include "board-dt.h"
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
+#include <linux/of_platform.h>
 
 static const char *msm8953_dt_match[] __initconst = {
 	"qcom,msm8953",
@@ -23,9 +24,25 @@
 
 static void __init msm8953_init(void)
 {
+	if (IS_ENABLED(CONFIG_ARCH_MSM8953_BOOT_ORDERING))
+		return;
 	board_dt_populate(NULL);
 }
 
+#ifdef CONFIG_ARCH_MSM8953_BOOT_ORDERING
+static int __init msm8953_dt_populate(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+	/* Explicitly parent the /soc devices to the root node to preserve
+	 * the kernel ABI (sysfs structure, etc) until userspace is updated
+	 */
+	of_platform_populate(of_find_node_by_path("/soc"),
+			     of_default_bus_match_table, NULL, NULL);
+}
+late_initcall(msm8953_dt_populate);
+#endif
+
 DT_MACHINE_START(MSM8953_DT,
 	"Qualcomm Technologies, Inc. MSM8953 (Flattened Device Tree)")
 	.init_machine		= msm8953_init,
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 4aba42f..8d8e4c5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -502,7 +502,7 @@
 }
 EXPORT_SYMBOL_GPL(of_platform_default_populate);
 
-#ifndef CONFIG_PPC
+#if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MSM8953_BOOT_ORDERING)
 static int __init of_platform_default_populate_init(void)
 {
 	struct device_node *node;