summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaravana Kannan <saravanak@google.com>2019-08-01 01:17:18 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-08-01 17:04:14 +0300
commit21871a99b34c65c56a24193c277a4981529c306f (patch)
treec8cdd03265fdd8714db60fffd23254bf1de895dc
parent8f8184d6bf676a8680d6f441e40317d166b46f73 (diff)
downloadlinux-21871a99b34c65c56a24193c277a4981529c306f.tar.xz
of/platform: Pause/resume sync state during init and of_platform_populate()
When all the top level devices are populated from DT during kernel init, the supplier devices could be added and probed before the consumer devices are added and linked to the suppliers. To avoid the sync_state() callback from being called prematurely, pause the sync_state() callbacks before populating the devices and resume them at late_initcall_sync(). Similarly, when children devices are populated after kernel init using of_platform_populate(), there could be supplier-consumer dependencies between the children devices that are populated. To avoid the same problem with sync_state() being called prematurely, pause and resume sync_state() callbacks across of_platform_populate(). Signed-off-by: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20190731221721.187713-6-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/of/platform.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index c1c433333124..ae85a88ba53e 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -480,6 +480,7 @@ int of_platform_populate(struct device_node *root,
pr_debug("%s()\n", __func__);
pr_debug(" starting at: %pOF\n", root);
+ device_links_supplier_sync_state_pause();
for_each_child_of_node(root, child) {
rc = of_platform_bus_create(child, matches, lookup, parent, true);
if (rc) {
@@ -487,6 +488,8 @@ int of_platform_populate(struct device_node *root,
break;
}
}
+ device_links_supplier_sync_state_resume();
+
of_node_set_flag(root, OF_POPULATED_BUS);
of_node_put(root);
@@ -683,6 +686,7 @@ static int __init of_platform_default_populate_init(void)
return -ENODEV;
platform_bus_type.add_links = of_link_to_suppliers;
+ device_links_supplier_sync_state_pause();
/*
* Handle certain compatibles explicitly, since we don't want to create
* platform_devices for every node in /reserved-memory with a
@@ -703,6 +707,13 @@ static int __init of_platform_default_populate_init(void)
return 0;
}
arch_initcall_sync(of_platform_default_populate_init);
+
+static int __init of_platform_sync_state_init(void)
+{
+ device_links_supplier_sync_state_resume();
+ return 0;
+}
+late_initcall_sync(of_platform_sync_state_init);
#endif
int of_platform_device_destroy(struct device *dev, void *data)