Commit 5e666938 authored by Saravana Kannan's avatar Saravana Kannan Committed by Greg Kroah-Hartman

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 from a module 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: default avatarSaravana Kannan <saravanak@google.com>
Link: https://lore.kernel.org/r/20190904211126.47518-6-saravanak@google.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fc5a251d
...@@ -480,6 +480,7 @@ int of_platform_populate(struct device_node *root, ...@@ -480,6 +480,7 @@ int of_platform_populate(struct device_node *root,
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
pr_debug(" starting at: %pOF\n", root); pr_debug(" starting at: %pOF\n", root);
device_links_supplier_sync_state_pause();
for_each_child_of_node(root, child) { for_each_child_of_node(root, child) {
rc = of_platform_bus_create(child, matches, lookup, parent, true); rc = of_platform_bus_create(child, matches, lookup, parent, true);
if (rc) { if (rc) {
...@@ -487,6 +488,8 @@ int of_platform_populate(struct device_node *root, ...@@ -487,6 +488,8 @@ int of_platform_populate(struct device_node *root,
break; break;
} }
} }
device_links_supplier_sync_state_resume();
of_node_set_flag(root, OF_POPULATED_BUS); of_node_set_flag(root, OF_POPULATED_BUS);
of_node_put(root); of_node_put(root);
...@@ -518,6 +521,7 @@ static int __init of_platform_default_populate_init(void) ...@@ -518,6 +521,7 @@ static int __init of_platform_default_populate_init(void)
if (!of_have_populated_dt()) if (!of_have_populated_dt())
return -ENODEV; return -ENODEV;
device_links_supplier_sync_state_pause();
/* /*
* Handle certain compatibles explicitly, since we don't want to create * Handle certain compatibles explicitly, since we don't want to create
* platform_devices for every node in /reserved-memory with a * platform_devices for every node in /reserved-memory with a
...@@ -538,6 +542,14 @@ static int __init of_platform_default_populate_init(void) ...@@ -538,6 +542,14 @@ static int __init of_platform_default_populate_init(void)
return 0; return 0;
} }
arch_initcall_sync(of_platform_default_populate_init); arch_initcall_sync(of_platform_default_populate_init);
static int __init of_platform_sync_state_init(void)
{
if (of_have_populated_dt())
device_links_supplier_sync_state_resume();
return 0;
}
late_initcall_sync(of_platform_sync_state_init);
#endif #endif
int of_platform_device_destroy(struct device *dev, void *data) int of_platform_device_destroy(struct device *dev, void *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment