From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752427AbbJSMiM (ORCPT ); Mon, 19 Oct 2015 08:38:12 -0400 Received: from mezzanine.sirena.org.uk ([106.187.55.193]:37202 "EHLO mezzanine.sirena.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751457AbbJSMiK (ORCPT ); Mon, 19 Oct 2015 08:38:10 -0400 Date: Mon, 19 Oct 2015 13:37:58 +0100 From: Mark Brown To: Alexander Holler Cc: linux-kernel@vger.kernel.org, Linus Torvalds , Andrew Morton , Greg Kroah-Hartman , Russell King , Grant Likely , Frank Rowand , Rob Herring , David Gibson Message-ID: <20151019123758.GF14956@sirena.org.uk> References: <1445102067-11519-1-git-send-email-holler@ahsoftware.de> <1445102067-11519-4-git-send-email-holler@ahsoftware.de> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="7JDdbSaSV851Oucw" Content-Disposition: inline In-Reply-To: <1445102067-11519-4-git-send-email-holler@ahsoftware.de> X-Cookie: Do you like "TENDER VITTLES"? User-Agent: Mutt/1.5.24 (2015-08-30) X-SA-Exim-Connect-IP: 94.175.94.161 X-SA-Exim-Mail-From: broonie@sirena.org.uk Subject: Re: [PATCH 03/14] init: deps: dt: use (HW-specific) dependencies provided by the DT too X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on mezzanine.sirena.org.uk) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --7JDdbSaSV851Oucw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Oct 17, 2015 at 07:14:16PM +0200, Alexander Holler wrote: > This patch adds dependencies provided by the hardware description in > the used DT. This avoids the use of the deferred probe mechanism > on most (if not all) DT based kernels. >=20 > Drawback is that the binary DT blob has to be enhanced with type > information for phandles (which are used as dependencies) which > needs a modified dtc. You probably want to loop the DT and DTC maintainers in on this - adding Frank, Rob and David and leaving context for their reference. It would probably help if you could explicitly say why the DTB needs to be annotated and why this annotiation is best done via a DTC modification (rather than doing something like add new properties, or just guessing that any phandle reference is a dependency). >=20 > Signed-off-by: Alexander Holler > --- > drivers/of/base.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++= ++++++ > include/linux/of.h | 3 ++ > init/dependencies.c | 4 ++ > 3 files changed, 121 insertions(+) >=20 > diff --git a/drivers/of/base.c b/drivers/of/base.c > index 8b5a187..423ddff 100644 > --- a/drivers/of/base.c > +++ b/drivers/of/base.c > @@ -12,6 +12,8 @@ > * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and > * Grant Likely. > * > + * The dependency related stuff was done by Alexander Holler. > + * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License > * as published by the Free Software Foundation; either version > @@ -2308,3 +2310,115 @@ struct device_node *of_graph_get_remote_port(cons= t struct device_node *node) > return of_get_next_parent(np); > } > EXPORT_SYMBOL(of_graph_get_remote_port); > + > +#ifdef CONFIG_DEPENDENCIES > + > +static const struct _annotated_initcall * __init find_matching_driver( > + const struct _annotated_initcall *from, const struct device_node *node) > +{ > + while (++from !=3D __annotated_initcall_end) > + if (from->driver && > + __of_match_node(from->driver->of_match_table, > + node)) > + return from; > + return NULL; > +} > + > +static int __init add_dep_list(const struct device_node *node, unsigned = drvid) > +{ > + const __be32 *list, *list_end; > + uint32_t ph; > + int size =3D 0; > + int rc =3D 0; > + const struct device_node *dep; > + const struct _annotated_initcall *ac; > + > + list =3D __of_get_property(node, "dependencies", &size); > + if (!list || !size || size % sizeof(*list)) > + return 0; > + list_end =3D list + size / sizeof(*list); > + while (list < list_end) { > + ph =3D be32_to_cpup(list++); > + if (unlikely(!ph)) { > + /* Should never happen */ > + if (node->name) > + pr_warn("phandle =3D=3D 0 for %s\n", node->name); > + continue; > + } > + dep =3D of_find_node_by_phandle(ph); > + if (unlikely(!dep)) { > + pr_err("No DT node for dependency with phandle 0x%x found\n", > + ph); > + continue; > + } > + ac =3D __annotated_initcall_start - 1; > + while ((ac =3D find_matching_driver(ac, dep))) { > + if (!ac->id) > + continue; > + rc =3D add_initcall_dependency(drvid, ac->id); > + if (rc) > + return rc; > + } > + } > + > + return rc; > +} > + > +static int __init add_deps(unsigned parent, const struct device_node *no= de) > +{ > + struct device_node *child; > + const struct _annotated_initcall *ac; > + int rc =3D 0; > + bool found_one_driver =3D false; > + > + if (!__of_device_is_available(node)) > + return 0; > + if (__of_get_property(node, "compatible", NULL)) { > + ac =3D __annotated_initcall_start - 1; > + while ((ac =3D find_matching_driver(ac, node))) { > + if (!ac->id) > + continue; > + found_one_driver =3D true; > + rc =3D add_initcall_dependency(ac->id, parent); > + if (unlikely(rc)) > + return rc; > + rc =3D add_dep_list(node, ac->id); > + if (unlikely(rc)) > + return rc; > + for_each_child_of_node(node, child) { > + rc =3D add_deps(ac->id, child); > + if (unlikely(rc)) > + return rc; > + } > + } > + if (found_one_driver) > + return rc; > + } > + for_each_child_of_node(node, child) { > + rc =3D add_deps(parent, child); > + if (unlikely(rc)) > + break; > + } > + > + return rc; > +} > + > +int __init of_add_dependencies(void) > +{ > + int rc =3D 0; > + struct device_node *child; > + struct device_node *root =3D of_find_node_by_path("/"); > + > + if (unlikely(!root)) > + return -EINVAL; > + > + for_each_child_of_node(root, child) { > + rc =3D add_deps(0, child); > + if (unlikely(rc)) > + break; > + } > + of_node_put(root); > + > + return rc; > +} > +#endif /* CONFIG_DEPENDENCIES */ > diff --git a/include/linux/of.h b/include/linux/of.h > index edc068d..e3b65c8 100644 > --- a/include/linux/of.h > +++ b/include/linux/of.h > @@ -1101,4 +1101,7 @@ static inline int of_overlay_destroy_all(void) > =20 > #endif > =20 > +/* Inserts dependencies for drivers referenced in the loaded DT. */ > +int __init of_add_dependencies(void); > + > #endif /* _LINUX_OF_H */ > diff --git a/init/dependencies.c b/init/dependencies.c > index c47817c..b484f67 100644 > --- a/init/dependencies.c > +++ b/init/dependencies.c > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > =20 > #if defined(CONFIG_DEPENDENCIES_PRINT_INIT_ORDER) \ > || defined(CONFIG_DEPENDENCIES_PRINT_CALLS) > @@ -335,6 +336,9 @@ static int __init build_order(void) > =20 > build_inventory(); > add_dependencies(); > +#ifdef CONFIG_OF > + of_add_dependencies(); > +#endif > if (topological_sort()) > return -EINVAL; /* cycle found */ > pr_debug("init: vertices: %u edges %u count %u\n", > --=20 > 2.1.0 >=20 > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ >=20 --7JDdbSaSV851Oucw Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAEBCAAGBQJWJOQmAAoJECTWi3JdVIfQ81kIAITEYlRWcp/BhrAfaLiH8Vbd xLOa5CY24oq9MCMkwmt230ULoZltTKfBS3R38JFqNycMEFjtz+sIYBeU2uq2nbs9 oh/dEd2+nkrwl5JLe7+yTT3o2c8c3NieJo436jZ+5sOTibhgqOPZnvTYaJ5JM+Kp 36MFREi+6rpay0PlLwn6BJydtMZhN0OYOUFwgRCNQd2SYBdgSKt/zG9tCZiyLcze MJIpIoU000SHjj+36GlpQQZT8i3LGMnryLAPd1eFbLPHscBkQ12dT7dg4pq0yynB qDa7XWCautNy7n/25G5c0+7BjgJXdYYOcULikRoSP4P9Wf8UUzfAIQ2D8xJchU0= =9byz -----END PGP SIGNATURE----- --7JDdbSaSV851Oucw--