From patchwork Wed Jul 24 00:10:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 1135965 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="N34QL3Et"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45tbNp541Xz9sLt for ; Wed, 24 Jul 2019 10:11:22 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727562AbfGXALR (ORCPT ); Tue, 23 Jul 2019 20:11:17 -0400 Received: from mail-vk1-f201.google.com ([209.85.221.201]:48665 "EHLO mail-vk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727554AbfGXALP (ORCPT ); Tue, 23 Jul 2019 20:11:15 -0400 Received: by mail-vk1-f201.google.com with SMTP id x71so11024992vkd.15 for ; Tue, 23 Jul 2019 17:11:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=98OUdn+pluVNmpQHs0/5FBBUDYzwIohCNhKsPgXVGmw=; b=N34QL3EtPk26kjAtA0NHSi6z9ap3u0oUAKGPBafJkZBfyiSM67Pog6vi6pSs5F1VjZ vUdHfFxkgYxKi1u7wQ+vLNBC57nGmYUdXJLDI2RZEqtIUQzdSO/7jTzcfHu0WN3p62xe qkRCPIj18BA5/qG/1GaEz/eL7Hlh0BToVryJ9UcTbzO1dynMCnpWf9JtHUutUiWuebXU qpU5gmo9PmDrmVLiU4Kf6kyj4O1sFzcVCpoDcAc9dByDMglAFzVzXJsXNlCRiQDMomdg TWvX1U2yGAoGC+xV7t5kKHCIqeHtr+nJUNl0a1c/nuGNmuC6nejzX5t5mkQKE/MJ3aTZ sz1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=98OUdn+pluVNmpQHs0/5FBBUDYzwIohCNhKsPgXVGmw=; b=CFUQkv+sUo0M9UZQE+6vfzDU84780MaualCkvWMEEg8sOnnLmr6KzslCBAc75TG43k A1Zh26UghLo+qyTQkwz+5VU+ripIWB3yWg/zwHsRN/ZntiIx1rCR7XJlFbHTpwPGqr4Z VUnZ4iAF9f94Mzg62LErr/Ye0+KSngoIToO+1DTzVxoCYGZ0SzmDc36Tak3jC7phdfit k5u4NCgoyEpbKjh88IY+nVYurkLikUGZs6RVBIrixvdATZPZyenVrj9HgHo9AP4sWQpY Z3ddbdOPIa2UGZZIujAbua0E46goSilgfo03SvY4QOYr5BCfqOTSqGKGNnG85/oqavW9 2aQA== X-Gm-Message-State: APjAAAWSi2vAPlO53QMl18yxs+H9/fI2BEn//uMRB4qsJmVd5PGpPo0k //eskDEzFX11+ub+t/AhHzP1W6XLjuihgmc= X-Google-Smtp-Source: APXvYqzqjZnSq0YhGm6eldLeXF03o9zbaCWZcq8S+is3OD6Wx0MhT6EgjHljJFZ/I3hTUcA+Dunr0wyR7eG8kGw= X-Received: by 2002:ab0:20cc:: with SMTP id z12mr16983879ual.32.1563927074834; Tue, 23 Jul 2019 17:11:14 -0700 (PDT) Date: Tue, 23 Jul 2019 17:10:56 -0700 In-Reply-To: <20190724001100.133423-1-saravanak@google.com> Message-Id: <20190724001100.133423-4-saravanak@google.com> Mime-Version: 1.0 References: <20190724001100.133423-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v7 3/7] of/platform: Add functional dependency link from DT bindings From: Saravana Kannan To: Rob Herring , Mark Rutland , Greg Kroah-Hartman , "Rafael J. Wysocki" , Frank Rowand , Jonathan Corbet Cc: Saravana Kannan , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, David Collins , kernel-team@android.com, linux-doc@vger.kernel.org Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org 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. This leads to downstream hacks to handle cases like this that can easily be solved in the upstream kernel. By linking devices before they are probed, we give suppliers a clear count of the number of dependent consumers. Once all of the consumers are active, the suppliers can turn off the unused resources without making assumptions about the number of consumers. By default we just add device-links to track "driver presence" (probe succeeded) of the supplier device. If any other functionality provided by device-links are needed, it is left to the consumer/supplier devices to change the link when they probe. Signed-off-by: Saravana Kannan --- .../admin-guide/kernel-parameters.txt | 5 + drivers/of/platform.c | 165 ++++++++++++++++++ 2 files changed, 170 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 46b826fcb5ad..12937349d79d 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3170,6 +3170,11 @@ This can be set from sysctl after boot. See Documentation/admin-guide/sysctl/vm.rst for details. + of_devlink [KNL] Make device links from common DT bindings. Useful + for optimizing probe order and making sure resources + aren't turned off before the consumer devices have + probed. + ohci1394_dma=early [HW] enable debugging via the ohci1394 driver. See Documentation/debugging-via-ohci1394.txt for more info. diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 7801e25e6895..4344419a26fc 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -508,6 +508,170 @@ int of_platform_default_populate(struct device_node *root, } EXPORT_SYMBOL_GPL(of_platform_default_populate); +bool of_link_is_valid(struct device_node *con, struct device_node *sup) +{ + of_node_get(sup); + /* + * Don't allow linking a device node as a consumer of one of its + * descendant nodes. By definition, a child node can't be a functional + * dependency for the parent node. + */ + while (sup) { + if (sup == con) { + of_node_put(sup); + return false; + } + sup = of_get_next_parent(sup); + } + return true; +} + +static int of_link_to_phandle(struct device *dev, struct device_node *sup_np) +{ + struct platform_device *sup_dev; + u32 dl_flags = DL_FLAG_AUTOPROBE_CONSUMER; + int ret = 0; + + /* + * Since we are trying to create device links, we need to find + * the actual device node that owns this supplier phandle. + * Often times it's the same node, but sometimes it can be one + * of the parents. So walk up the parent till you find a + * device. + */ + while (sup_np && !of_find_property(sup_np, "compatible", NULL)) + sup_np = of_get_next_parent(sup_np); + if (!sup_np) + return 0; + + if (!of_link_is_valid(dev->of_node, sup_np)) { + of_node_put(sup_np); + return 0; + } + sup_dev = of_find_device_by_node(sup_np); + of_node_put(sup_np); + if (!sup_dev) + return -ENODEV; + if (!device_link_add(dev, &sup_dev->dev, dl_flags)) + ret = -ENODEV; + put_device(&sup_dev->dev); + return ret; +} + +static struct device_node *parse_prop_cells(struct device_node *np, + const char *prop, int index, + const char *binding, + const char *cell) +{ + struct of_phandle_args sup_args; + + /* Don't need to check property name for every index. */ + if (!index && strcmp(prop, binding)) + return NULL; + + if (of_parse_phandle_with_args(np, binding, cell, index, &sup_args)) + return NULL; + + return sup_args.np; +} + +static struct device_node *parse_clocks(struct device_node *np, + const char *prop, int index) +{ + return parse_prop_cells(np, prop, index, "clocks", "#clock-cells"); +} + +static struct device_node *parse_interconnects(struct device_node *np, + const char *prop, int index) +{ + return parse_prop_cells(np, prop, index, "interconnects", + "#interconnect-cells"); +} + +static int strcmp_suffix(const char *str, const char *suffix) +{ + unsigned int len, suffix_len; + + len = strlen(str); + suffix_len = strlen(suffix); + if (len <= suffix_len) + return -1; + return strcmp(str + len - suffix_len, suffix); +} + +static struct device_node *parse_regulators(struct device_node *np, + const char *prop, int index) +{ + if (index || strcmp_suffix(prop, "-supply")) + return NULL; + + return of_parse_phandle(np, prop, 0); +} + +/** + * struct supplier_bindings - Information for parsing supplier DT binding + * + * @parse_prop: If the function cannot parse the property, return NULL. + * Otherwise, return the phandle listed in the property + * that corresponds to the index. + */ +struct supplier_bindings { + struct device_node *(*parse_prop)(struct device_node *np, + const char *name, int index); +}; + +static const struct supplier_bindings bindings[] = { + { .parse_prop = parse_clocks, }, + { .parse_prop = parse_interconnects, }, + { .parse_prop = parse_regulators, }, + { }, +}; + +static bool of_link_property(struct device *dev, struct device_node *con_np, + const char *prop) +{ + struct device_node *phandle; + struct supplier_bindings *s = bindings; + unsigned int i = 0; + bool done = true, matched = false; + + while (!matched && s->parse_prop) { + while ((phandle = s->parse_prop(con_np, prop, i))) { + matched = true; + i++; + if (of_link_to_phandle(dev, phandle)) + /* + * Don't stop at the first failure. See + * Documentation for bus_type.add_links for + * more details. + */ + done = false; + } + s++; + } + return done ? 0 : -ENODEV; +} + +static bool of_devlink; +core_param(of_devlink, of_devlink, bool, 0); + +static int of_link_to_suppliers(struct device *dev) +{ + struct property *p; + bool done = true; + + if (!of_devlink) + return 0; + if (unlikely(!dev->of_node)) + return 0; + + for_each_property_of_node(dev->of_node, p) + if (of_link_property(dev, dev->of_node, p->name)) + done = false; + + return done ? 0 : -ENODEV; +} + #ifndef CONFIG_PPC static const struct of_device_id reserved_mem_matches[] = { { .compatible = "qcom,rmtfs-mem" }, @@ -523,6 +687,7 @@ static int __init of_platform_default_populate_init(void) if (!of_have_populated_dt()) return -ENODEV; + platform_bus_type.add_links = of_link_to_suppliers; /* * Handle certain compatibles explicitly, since we don't want to create * platform_devices for every node in /reserved-memory with a From patchwork Wed Jul 24 00:10:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 1135966 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="u946jxc1"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45tbNr2KwTz9sLt for ; Wed, 24 Jul 2019 10:11:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727584AbfGXALX (ORCPT ); Tue, 23 Jul 2019 20:11:23 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:42046 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727574AbfGXALW (ORCPT ); Tue, 23 Jul 2019 20:11:22 -0400 Received: by mail-pf1-f202.google.com with SMTP id 21so27278478pfu.9 for ; Tue, 23 Jul 2019 17:11:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dW/eX2JkclSqL7u9D8ywYYaolgPaeztKnKrJrmo9wG4=; b=u946jxc1RmSvSOtzAKB3GMM86YLHchlYMuLFogO7YsdmMYJyI/7JXiQonjz3bcjopu elHlrksvcvbieQ5JZrC8tfVphdsbpDrryd7Z/sFe+tWszPgvfTmkqDd+g1wm/sTmt499 gtOymTg8kvR2Y7hXivULQm/EfjGEB1KEAhZVwElnZH5RTntDEw55/zGR0eFNE7cjSF2m Fr4IlI72U7F4mZfaFKNfmZVADen5GkW7me5ZUjC141Y4ao4x5wfsMcbswStnYrBe3lLm fgxpOMKVuceTCQhNsmeK1NhqpvhIT5GPsRSahADu5u1Xwkbf5FYCT6XOXBPf+mymKQV0 w+8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=dW/eX2JkclSqL7u9D8ywYYaolgPaeztKnKrJrmo9wG4=; b=NC3pslYqOdvH1X9461iNEDL5jRCQEjMgSinA8dBgmTA3bzCm1RanYfHr7F3CJA2/eJ 5/VLjuJaXxvRqzNjVV0LP3D3CS3fbt+osZmLA+6bm55e9SCV0AxGvPzWDzGvpdSRgCzT ifJj+Z5h0Ig5s+YMbVTg1UbkXelSPkRuKSEBPtUhFVJyYPooHmAuIbqFB1pyk5uRHk4R RbIdJNufUIAp8JiNxjQXQkoVBAbi0R7M4Ya3OZpxEuo8UvzSfbyenfEnAghppy1m1Avu niw7J6xIlPYdI3IvO2i2qaqBEl40hoWJ3vUTdZywq7VP4bdCx2ZmlRHuEMJ3yAl0xFb7 JpLA== X-Gm-Message-State: APjAAAULz1tIaPypO97yA1yB0N0jXhw3kINXiwlyfgzgz+lZUgE/EXt5 qs7UrDikTdrhbtQ5R6/SE58LmU70ZEF/8lo= X-Google-Smtp-Source: APXvYqz9YflAXImGtKl/9HK7UKMqSBdU9Tp6PYpqM84Q1eb8vrgbKFOPzUha0/HYyHn1gr8xv8NM/AwgD1w+mT8= X-Received: by 2002:a65:4103:: with SMTP id w3mr63674222pgp.1.1563927081240; Tue, 23 Jul 2019 17:11:21 -0700 (PDT) Date: Tue, 23 Jul 2019 17:10:58 -0700 In-Reply-To: <20190724001100.133423-1-saravanak@google.com> Message-Id: <20190724001100.133423-6-saravanak@google.com> Mime-Version: 1.0 References: <20190724001100.133423-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v7 5/7] of/platform: Pause/resume sync state during init and of_platform_populate() From: Saravana Kannan To: Rob Herring , Mark Rutland , Greg Kroah-Hartman , "Rafael J. Wysocki" , Frank Rowand Cc: Saravana Kannan , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, David Collins , kernel-team@android.com Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org 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 --- drivers/of/platform.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 4344419a26fc..71d6138698ec 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -485,6 +485,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) { @@ -492,6 +493,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); @@ -688,6 +691,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 @@ -708,6 +712,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) From patchwork Wed Jul 24 00:10:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 1135967 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="TG63xheF"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45tbNv30Rtz9s3l for ; Wed, 24 Jul 2019 10:11:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727622AbfGXAL0 (ORCPT ); Tue, 23 Jul 2019 20:11:26 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:53005 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727604AbfGXALZ (ORCPT ); Tue, 23 Jul 2019 20:11:25 -0400 Received: by mail-pf1-f201.google.com with SMTP id a20so27279655pfn.19 for ; Tue, 23 Jul 2019 17:11:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=L03s0/cCwSibWbjOlLSetg9NEt3OrkecIhAnIwN841s=; b=TG63xheFeu2TtgFwns1F37AaSHu7rAHoMRk+RRVOIKJ8Ya+2Znfh8TIvoJJB4JkqHU gSNCzASvMpUQnrcSjpvOmaDQqPxEsL1iEEwUutzRjWt0rvWBXuY6A+fJ3T31BqTqkXYy 75wO6Isa8nJ99vGoEKt2cs9nfxoY5qA3fjYp80D9Bey/LO93+orki8csi0DDKNMoRACM EtF1g+p+LezFGYIYqBssjGmjAd2JRIVpe1QqD4mhCTTsgwZcVM2fqr72YoyzPXAzht8r rY+tYHS9Z1vGj4bWXcM/1coYsmxI9spyPAWy1i1VJtk9BW3yqfE1KNM4SYeFIUHfPyR3 JelQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=L03s0/cCwSibWbjOlLSetg9NEt3OrkecIhAnIwN841s=; b=pMQ/oYUAY6/xfFBO330SdajpOxY5EEOEIcYY4s8PgMzTKOL1zvU+xH9sIXu0qpxXxR GiM9vhlstz8hKPwkvgt7XOq0BT8YsyN8bVdyy4UmY/Q0R8q1DsXV+EJsG7dpPP4sNfw8 4UUMUxdoOaOPN94n0jN9rvOSTmjc4+mKZqckEUsV7Suy9zZgHJ0EP8Cxk6NN/rI5Mj01 JS4BrrgwoeIlQ/8tZY+STwiq6LmnNf0EJtRmsK2DyuK2DgOqgFJ3dFZM2gQdShgy4xeF OwqfDxcYYuPGL4c1huvFzK/xP5l4qiySPUsQTAbBe+1imGWWxG2pEJQH3bs5UKXOZExL ImOw== X-Gm-Message-State: APjAAAUpK3GzcXNXIQxFQRv2n2qHuDzJaKp0GsnLmjvQsgk0jMjHnKSo RiLtrE3YkC3O2yCs6WUn8IxSVurNWLR5QEM= X-Google-Smtp-Source: APXvYqwXM3zaatfsro6OzkcL1pd5UbOLfzL1dK6ZYUTH1e3CKFd84+WcyriFc2O6S1UEB9t2wnPoV/KmMJuO2tM= X-Received: by 2002:a63:204b:: with SMTP id r11mr38959699pgm.121.1563927084355; Tue, 23 Jul 2019 17:11:24 -0700 (PDT) Date: Tue, 23 Jul 2019 17:10:59 -0700 In-Reply-To: <20190724001100.133423-1-saravanak@google.com> Message-Id: <20190724001100.133423-7-saravanak@google.com> Mime-Version: 1.0 References: <20190724001100.133423-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v7 6/7] of/platform: Create device links for all child-supplier depencencies From: Saravana Kannan To: Rob Herring , Mark Rutland , Greg Kroah-Hartman , "Rafael J. Wysocki" , Frank Rowand Cc: Saravana Kannan , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, David Collins , kernel-team@android.com Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org A parent device can have child devices that it adds when it probes. But this probing of the parent device can happen way after kernel init is done -- for example, when the parent device's driver is loaded as a module. In such cases, if the child devices depend on a supplier in the system, we need to make sure the supplier gets the sync_state() callback only after these child devices are added and probed. To achieve this, when creating device links for a device by looking at its DT node, don't just look at DT references at the top node level. Look at DT references in all the descendant nodes too and create device links from the ancestor device to all these supplier devices. This way, when the parent device probes and adds child devices, the child devices can then create their own device links to the suppliers and further delay the supplier's sync_state() callback to after the child devices are probed. Example: In this illustration, -> denotes DT references and indentation represents child status. Device node A Device node B -> D Device node C -> B, D Device node D Assume all these devices have their drivers loaded as modules. Without this patch, this is the sequence of events: 1. D is added. 2. A is added. 3. Device D probes. 4. Device D gets its sync_state() callback. 5. Device B and C might malfunction because their resources got altered/turned off before they can make active requests for them. With this patch, this is the sequence of events: 1. D is added. 2. A is added and creates device links to D. 3. Device link from A to B is not added because A is a parent of B. 4. Device D probes. 5. Device D does not get it's sync_state() callback because consumer A hasn't probed yet. 5. Device A probes. 5. a. Devices B and C are added. 5. b. Device links from B and C to D are added. 5. c. Device A's probe completes. 6. Device D does not get it's sync_state() callback because consumer A has probed but consumers B and C haven't probed yet. 7. Device B and C probe. 8. Device D gets it's sync_state() callback because all its consumers have probed. 9. None of the devices malfunction. Signed-off-by: Saravana Kannan --- drivers/of/platform.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 71d6138698ec..41499ddc8d95 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -655,24 +655,35 @@ static bool of_link_property(struct device *dev, struct device_node *con_np, return done ? 0 : -ENODEV; } +static int __of_link_to_suppliers(struct device *dev, + struct device_node *con_np) +{ + struct device_node *child; + struct property *p; + bool done = true; + + for_each_property_of_node(con_np, p) + if (of_link_property(dev, con_np, p->name)) + done = false; + + for_each_child_of_node(con_np, child) + if (__of_link_to_suppliers(dev, child)) + done = false; + + return done ? 0 : -ENODEV; +} + static bool of_devlink; core_param(of_devlink, of_devlink, bool, 0); static int of_link_to_suppliers(struct device *dev) { - struct property *p; - bool done = true; - if (!of_devlink) return 0; if (unlikely(!dev->of_node)) return 0; - for_each_property_of_node(dev->of_node, p) - if (of_link_property(dev, dev->of_node, p->name)) - done = false; - - return done ? 0 : -ENODEV; + return __of_link_to_suppliers(dev, dev->of_node); } #ifndef CONFIG_PPC From patchwork Wed Jul 24 00:11:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 1135968 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="WYmp9wsx"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45tbNz1dSpz9sLt for ; Wed, 24 Jul 2019 10:11:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727631AbfGXAL3 (ORCPT ); Tue, 23 Jul 2019 20:11:29 -0400 Received: from mail-pl1-f201.google.com ([209.85.214.201]:39368 "EHLO mail-pl1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727605AbfGXAL2 (ORCPT ); Tue, 23 Jul 2019 20:11:28 -0400 Received: by mail-pl1-f201.google.com with SMTP id r7so22984552plo.6 for ; Tue, 23 Jul 2019 17:11:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=q/JO0jIzFDUcBLNa0OLAVEbtuFfd8ssnFHaHdmtCpxU=; b=WYmp9wsxezkT2R/MikeKx4t2kiHMyW2mvw+vnqop1fKm18UGsdFrOX0WMvp0211oE5 AenkmFgmV5Fd3/Kob7ksNJEBQ5BHl8zs1JzyycKcNyBaseoUHZcFMx6ZWsdHZU92y0E0 Dzyw6ffhd60WvwW1dAxMzf2Bw1rXvf8tft38BNZ/9xEHqn8dkzW3wMW49PAIcMGw6eR5 9+5VreZKwIO5czdaW+ToF0ZASnI1NQZlEzr6pNvgpH06DfFYBDVN2OyI69rdIn6kpJlu CQJMTpeetGIPTol0Z9tGdsf6G3WGCRMgmk5IWKNGrriIaXe6bMmUPkRQnOEodnqoyC/+ hWOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=q/JO0jIzFDUcBLNa0OLAVEbtuFfd8ssnFHaHdmtCpxU=; b=fDZXOvqXyQrD8n8guDfC8UnW8iCtB5cbvpIAW5+1qPP5Ni0B1k15/t8s374ibsemJN ijRBWhPZlBn/ERtaj02dGgjM8i2Tha1zA+kaPTjE5UQJNeDdj0e3Du9npWu8kwUwJKmG eTy+tq3GR/1XquHcRoNQnSa60XqE9UgqEFl7UU96zcOr0ghU9u6mOHGZjcCqaY1U8vXs iTc6Zm6ROnWIT93aU0hANPuyBMY5khPHZb6xoJvEVyoWbN2uvpzYEHL1d3vpiw0os/u9 ueIGCDexhFhmaZBAznxtHIEm1AxuhJQ8Ml3snpLheuditjO4QRlTptxOi/lqIDfsA+25 GG+w== X-Gm-Message-State: APjAAAUMsjoRscVRcBx7/VhAjM6+f3R4/1jATUWFa9hZGVPsOhuU8PPs f2DPT6nJ3y4vwr+3lZY2huCMYnqb8OkevHQ= X-Google-Smtp-Source: APXvYqyfrpfG7foa9SWIkR5PY0wl5lzzhUJJl9ryESw4iWhqCn6wdu4L8I+nTmuFAxhxJl22/uYxTDoF1Fgo0zY= X-Received: by 2002:a65:6259:: with SMTP id q25mr38982937pgv.145.1563927087442; Tue, 23 Jul 2019 17:11:27 -0700 (PDT) Date: Tue, 23 Jul 2019 17:11:00 -0700 In-Reply-To: <20190724001100.133423-1-saravanak@google.com> Message-Id: <20190724001100.133423-8-saravanak@google.com> Mime-Version: 1.0 References: <20190724001100.133423-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v7 7/7] of/platform: Don't create device links for default busses From: Saravana Kannan To: Rob Herring , Mark Rutland , Greg Kroah-Hartman , "Rafael J. Wysocki" , Frank Rowand Cc: Saravana Kannan , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, David Collins , kernel-team@android.com Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Default busses also have devices created for them. But there's no point in creating device links for them. It's especially wasteful as it'll cause the traversal of the entire device tree and also spend a lot of time checking and figuring out that creating those links isn't allowed. So check for default busses and skip trying to create device links for them. Signed-off-by: Saravana Kannan --- drivers/of/platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 41499ddc8d95..676b2f730d1b 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -682,6 +682,8 @@ static int of_link_to_suppliers(struct device *dev) return 0; if (unlikely(!dev->of_node)) return 0; + if (of_match_node(of_default_bus_match_table, dev->of_node)) + return 0; return __of_link_to_suppliers(dev, dev->of_node); }