From patchwork Wed Apr 15 15:05:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Saenz Julienne X-Patchwork-Id: 1271242 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=devicetree-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.de Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 492QgM0Fq1z9sT3 for ; Thu, 16 Apr 2020 01:06:55 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S371208AbgDOPGx (ORCPT ); Wed, 15 Apr 2020 11:06:53 -0400 Received: from mx2.suse.de ([195.135.220.15]:60720 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2394095AbgDOPGV (ORCPT ); Wed, 15 Apr 2020 11:06:21 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C82B1AFBB; Wed, 15 Apr 2020 15:06:18 +0000 (UTC) From: Nicolas Saenz Julienne To: saravanak@google.com, Greg Kroah-Hartman , devicetree@vger.kernel.org, Rob Herring , Frank Rowand Cc: Nicolas Saenz Julienne , linux-kernel@vger.kernel.org Subject: [PATCH 3/4] of: property: Move of_link_to_phandle() Date: Wed, 15 Apr 2020 17:05:48 +0200 Message-Id: <20200415150550.28156-4-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200415150550.28156-1-nsaenzjulienne@suse.de> References: <20200415150550.28156-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This is done in order to simplify further changes. Signed-off-by: Nicolas Saenz Julienne --- drivers/of/property.c | 145 +++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/drivers/of/property.c b/drivers/of/property.c index 487685ff8bb19..2c7978ef22be1 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -1014,78 +1014,6 @@ static bool of_is_ancestor_of(struct device_node *test_ancestor, return false; } -/** - * of_link_to_phandle - Add device link to supplier from supplier phandle - * @dev: consumer device - * @sup_np: phandle to supplier device tree node - * - * Given a phandle to a supplier device tree node (@sup_np), this function - * finds the device that owns the supplier device tree node and creates a - * device link from @dev consumer device to the supplier device. This function - * doesn't create device links for invalid scenarios such as trying to create a - * link with a parent device as the consumer of its child device. In such - * cases, it returns an error. - * - * Returns: - * - 0 if link successfully created to supplier - * - -EAGAIN if linking to the supplier should be reattempted - * - -EINVAL if the supplier link is invalid and should not be created - * - -ENODEV if there is no device that corresponds to the supplier phandle - */ -static int of_link_to_phandle(struct device *dev, struct device_node *sup_np, - u32 dl_flags) -{ - struct device *sup_dev; - int ret = 0; - struct device_node *tmp_np = sup_np; - int is_populated; - - 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); - if (!sup_np) { - dev_dbg(dev, "Not linking to %pOFP - No device\n", tmp_np); - return -ENODEV; - } - - /* Don't allow linking a device node as consumer of a disabled node */ - if (!of_device_is_available(sup_np)) { - dev_dbg(dev, "Not linking to %pOFP - Not available\n", sup_np); - of_node_put(sup_np); - return -ENODEV; - } - - /* - * 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. - */ - if (of_is_ancestor_of(dev->of_node, sup_np)) { - dev_dbg(dev, "Not linking to %pOFP - is descendant\n", sup_np); - of_node_put(sup_np); - return -EINVAL; - } - sup_dev = get_dev_from_fwnode(&sup_np->fwnode); - is_populated = of_node_check_flag(sup_np, OF_POPULATED); - of_node_put(sup_np); - if (!sup_dev && is_populated) { - /* Early device without struct device. */ - dev_dbg(dev, "Not linking to %pOFP - No struct device\n", - sup_np); - return -ENODEV; - } else if (!sup_dev) { - return -EAGAIN; - } - if (!device_link_add(dev, sup_dev, dl_flags)) - ret = -EAGAIN; - put_device(sup_dev); - return ret; -} - /** * parse_prop_cells - Property parsing function for suppliers * @@ -1243,6 +1171,79 @@ static const struct supplier_bindings of_supplier_bindings[] = { {} }; +/** + * of_link_to_phandle - Add device link to supplier from supplier phandle + * @dev: consumer device + * @sup_np: phandle to supplier device tree node + * + * Given a phandle to a supplier device tree node (@sup_np), this function + * finds the device that owns the supplier device tree node and creates a + * device link from @dev consumer device to the supplier device. This function + * doesn't create device links for invalid scenarios such as trying to create a + * link with a parent device as the consumer of its child device. In such + * cases, it returns an error. + * + * Returns: + * - 0 if link successfully created to supplier + * - -EAGAIN if linking to the supplier should be reattempted + * - -EINVAL if the supplier link is invalid and should not be created + * - -ENODEV if there is no device that corresponds to the supplier phandle + */ +static int of_link_to_phandle(struct device *dev, struct device_node *sup_np, + u32 dl_flags) +{ + struct device *sup_dev; + int ret = 0; + struct device_node *tmp_np = sup_np; + int is_populated; + + 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); + if (!sup_np) { + dev_dbg(dev, "Not linking to %pOFP - No device\n", tmp_np); + return -ENODEV; + } + + /* Don't allow linking a device node as consumer of a disabled node */ + if (!of_device_is_available(sup_np)) { + dev_dbg(dev, "Not linking to %pOFP - Not available\n", sup_np); + of_node_put(sup_np); + return -ENODEV; + } + + /* + * 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. + */ + if (of_is_ancestor_of(dev->of_node, sup_np)) { + dev_dbg(dev, "Not linking to %pOFP - is descendant\n", sup_np); + of_node_put(sup_np); + return -EINVAL; + } + sup_dev = get_dev_from_fwnode(&sup_np->fwnode); + is_populated = of_node_check_flag(sup_np, OF_POPULATED); + of_node_put(sup_np); + if (!sup_dev && is_populated) { + /* Early device without struct device. */ + dev_dbg(dev, "Not linking to %pOFP - No struct device\n", + sup_np); + return -ENODEV; + } else if (!sup_dev) { + return -EAGAIN; + } + + if (!device_link_add(dev, sup_dev, dl_flags)) + ret = -EAGAIN; + put_device(sup_dev); + return ret; +} + /** * of_link_property - Create device links to suppliers listed in a property * @dev: Consumer device