On Wed, Sep 11, 2019 at 03:29:25AM -0700, Stephen Boyd wrote: > Quoting Saravana Kannan (2019-09-04 14:11:22) > > Add device links after the devices are created (but before they are > > probed) by looking at common DT bindings like clocks and > > interconnects. > > > > Automatically adding device links for functional dependencies at the > > framework level provides the following benefits: > > > > - Optimizes device probe order and avoids the useless work of > > attempting probes of devices that will not probe successfully > > (because their suppliers aren't present or haven't probed yet). > > > > For example, in a commonly available mobile SoC, registering just > > one consumer device's driver at an initcall level earlier than the > > supplier device's driver causes 11 failed probe attempts before the > > consumer device probes successfully. This was with a kernel with all > > the drivers statically compiled in. This problem gets a lot worse if > > all the drivers are loaded as modules without direct symbol > > dependencies. > > > > - Supplier devices like clock providers, interconnect providers, etc > > need to keep the resources they provide active and at a particular > > state(s) during boot up even if their current set of consumers don't > > request the resource to be active. This is because the rest of the > > consumers might not have probed yet and turning off the resource > > before all the consumers have probed could lead to a hang or > > undesired user experience. > > > > Some frameworks (Eg: regulator) handle this today by turning off > > "unused" resources at late_initcall_sync and hoping all the devices > > have probed by then. This is not a valid assumption for systems with > > loadable modules. Other frameworks (Eg: clock) just don't handle > > this due to the lack of a clear signal for when they can turn off > > resources. > > The clk framework disables unused clks at late_initcall_sync. What do > you mean clk framework doesn't turn them off because of a clear signal? There's a number of minor things you pointed out in this review. Saravana, can you send a follow-on patch for the minor code cleanups like formatting and the like that was found here? > > +static int of_link_to_phandle(struct device *dev, struct device_node *sup_np) > > +{ > > + struct device *sup_dev; > > + u32 dl_flags = DL_FLAG_AUTOPROBE_CONSUMER; > > Is it really a u32 instead of an unsigned int or unsigned long? > > > + int ret = 0; > > + struct device_node *tmp_np = sup_np; > > + > > + of_node_get(sup_np); > > + /* > > + * Find the device node that contains the supplier phandle. It may be > > + * @sup_np or it may be an ancestor of @sup_np. > > + */ > > + while (sup_np && !of_find_property(sup_np, "compatible", NULL)) > > + sup_np = of_get_next_parent(sup_np); > > I don't get this. This is assuming that drivers are only probed for > device nodes that have a compatible string? What about drivers that make > sub-devices for clk support that have drivers in drivers/clk/ that then > attach at runtime later? This happens sometimes for MFDs that want to > split the functionality across the driver tree to the respective > subsystems. For that, the link would not be there, correct? > > +static int of_link_property(struct device *dev, struct device_node *con_np, > > + const char *prop_name) > > +{ > > + struct device_node *phandle; > > + const struct supplier_bindings *s = bindings; > > + unsigned int i = 0; > > + bool matched = false; > > + int ret = 0; > > + > > + /* Do not stop at first failed link, link all available suppliers. */ > > + while (!matched && s->parse_prop) { > > + while ((phandle = s->parse_prop(con_np, prop_name, i))) { > > + matched = true; > > + i++; > > + if (of_link_to_phandle(dev, phandle) == -EAGAIN) > > + ret = -EAGAIN; > > And don't break? There was comments before about how this is not needed. Frank asked that the comment be removed. And now you point it out again :) Look at the comment a few lines up, we have to go through all of the suppliers. > > +static int __of_link_to_suppliers(struct device *dev, > > Why the double underscore? > > > + struct device_node *con_np) > > +{ > > + struct device_node *child; > > + struct property *p; > > + int ret = 0; > > + > > + for_each_property_of_node(con_np, p) > > + if (of_link_property(dev, con_np, p->name)) > > + ret = -EAGAIN; > > Same comment. Same response as above :) thanks, greg k-h