From patchwork Wed Nov 15 09:43:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Hovold X-Patchwork-Id: 838128 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@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=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qA5pUKd/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3ycKFb0QrPz9s7M for ; Wed, 15 Nov 2017 20:43:47 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756054AbdKOJno (ORCPT ); Wed, 15 Nov 2017 04:43:44 -0500 Received: from mail-lf0-f65.google.com ([209.85.215.65]:57266 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756667AbdKOJnb (ORCPT ); Wed, 15 Nov 2017 04:43:31 -0500 Received: by mail-lf0-f65.google.com with SMTP id g35so11197590lfi.13; Wed, 15 Nov 2017 01:43:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=gEkmXwuMdVThWAYv85Z9BvXyv6V7Fom4ns6gyQzkgTM=; b=qA5pUKd/3TDrh+RrYKhy8qR8RmLjZHVAPMgQwd+mNMVL/W6io2VYsej92UdW4YJ1L5 mMPZ67z3qkFwo+BnyHyidlHUxKPV+O9ESqZVzIpuN0svZ/IcJ+pa2RoqLRoebJTM39A2 QR40x/nQ0ewtO7YXbdsD2Vjfs/fnKlTRKOkHX31kjr2b0TF1xx9OWk46vqGtNqn9fSez ++cQOPQkOySY1G11o6pWHbemqs9SVpV9MYjXYPh/QOl8VZHA1LNTd1T60CjZRcY4U5Yj RLfF+4yBVaKwpysQ91ZzomFJdqS9sfxdywA8sZl6QgHMYscGH7WwbPWP1LwwnLfTsY2f ukYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=gEkmXwuMdVThWAYv85Z9BvXyv6V7Fom4ns6gyQzkgTM=; b=hQCKcuCxOJz3N3Sd0qG7yfY7VoXpPDLvPpMhg9MGqKusLhUEaBI0tiucZbC02N12bB rR9THI11uK7W+B2SnSCpABiGqM/7FwiETwL/Fr4gFvZrdugXn7NpFo2ko5wRSeVQBdgt dCRTzPLLWCb/VKHPRTIvEzRbRRmSdv/WzBTMkFct455qbkJS3Q6ILZ20zTo3mTmQAQ3e 2UCSZhhwNRlexZqWuC8ciWPWrCFDtPWuBogVysdls0gv/VS6QGah3rgxzrvcRuUdDarZ 5vi/HRKErJ140TNqPmRuwM+NCcYr2Fs1KxVrDVNKKeOyRXqdAf5nTSWY6/tb0ee3Xwy7 6PUA== X-Gm-Message-State: AJaThX5Lh3KSDoo7WKhhoqfXnHGF7+cq9P6ZaG9dkmrrdytfCxuDZa/Y Z/NL35dfg2NK0mTambhZg+Q= X-Google-Smtp-Source: AGs4zMa0rJclc2EuKQ8KJyo+WY9ONw8GzIJuMQRHy9wSAls/pyvga0gZnjTcPmJS9CzH0tfFgqNLHQ== X-Received: by 10.25.227.77 with SMTP id c13mr4938624lfk.82.1510739009455; Wed, 15 Nov 2017 01:43:29 -0800 (PST) Received: from xi.terra (c-c0bae655.07-184-6d6c6d4.cust.bredbandsbolaget.se. [85.230.186.192]) by smtp.gmail.com with ESMTPSA id i66sm4194983lji.51.2017.11.15.01.43.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Nov 2017 01:43:28 -0800 (PST) Received: from johan by xi.terra with local (Exim 4.89) (envelope-from ) id 1eEuEI-0008E0-LV; Wed, 15 Nov 2017 10:43:34 +0100 From: Johan Hovold To: Kishon Vijay Abraham I Cc: Thierry Reding , Jonathan Hunter , linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold , stable , Thierry Reding Subject: [PATCH] phy: tegra: fix device-tree node lookups Date: Wed, 15 Nov 2017 10:43:16 +0100 Message-Id: <20171115094316.31576-1-johan@kernel.org> X-Mailer: git-send-email 2.15.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Fix child-node lookups during probe, which ended up searching the whole device tree depth-first starting at the parents rather than just matching on their children. To make things worse, some parent nodes could end up being being prematurely freed (by tegra_xusb_pad_register()) as of_find_node_by_name() drops a reference to its first argument. Fixes: 53d2a715c240 ("phy: Add Tegra XUSB pad controller support") Cc: stable # 4.7 Cc: Thierry Reding Signed-off-by: Johan Hovold --- drivers/phy/tegra/xusb.c | 58 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 4307bf0013e1..63e916d4d069 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -75,14 +75,14 @@ MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match); static struct device_node * tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) { - /* - * of_find_node_by_name() drops a reference, so make sure to grab one. - */ - struct device_node *np = of_node_get(padctl->dev->of_node); + struct device_node *pads, *np; + + pads = of_get_child_by_name(padctl->dev->of_node, "pads"); + if (!pads) + return NULL; - np = of_find_node_by_name(np, "pads"); - if (np) - np = of_find_node_by_name(np, name); + np = of_get_child_by_name(pads, name); + of_node_put(pads); return np; } @@ -90,16 +90,16 @@ tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) static struct device_node * tegra_xusb_pad_find_phy_node(struct tegra_xusb_pad *pad, unsigned int index) { - /* - * of_find_node_by_name() drops a reference, so make sure to grab one. - */ - struct device_node *np = of_node_get(pad->dev.of_node); + struct device_node *np, *lanes; - np = of_find_node_by_name(np, "lanes"); - if (!np) + lanes = of_get_child_by_name(pad->dev.of_node, "lanes"); + if (!lanes) return NULL; - return of_find_node_by_name(np, pad->soc->lanes[index].name); + np = of_get_child_by_name(lanes, pad->soc->lanes[index].name); + of_node_put(lanes); + + return np; } static int @@ -195,7 +195,7 @@ int tegra_xusb_pad_register(struct tegra_xusb_pad *pad, unsigned int i; int err; - children = of_find_node_by_name(pad->dev.of_node, "lanes"); + children = of_get_child_by_name(pad->dev.of_node, "lanes"); if (!children) return -ENODEV; @@ -444,21 +444,21 @@ static struct device_node * tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type, unsigned int index) { - /* - * of_find_node_by_name() drops a reference, so make sure to grab one. - */ - struct device_node *np = of_node_get(padctl->dev->of_node); + struct device_node *ports, *np; + char *name; - np = of_find_node_by_name(np, "ports"); - if (np) { - char *name; + ports = of_get_child_by_name(padctl->dev->of_node, "ports"); + if (!ports) + return NULL; - name = kasprintf(GFP_KERNEL, "%s-%u", type, index); - if (!name) - return ERR_PTR(-ENOMEM); - np = of_find_node_by_name(np, name); - kfree(name); + name = kasprintf(GFP_KERNEL, "%s-%u", type, index); + if (!name) { + of_node_put(ports); + return ERR_PTR(-ENOMEM); } + np = of_get_child_by_name(ports, name); + kfree(name); + of_node_put(ports); return np; } @@ -847,7 +847,7 @@ static void tegra_xusb_remove_ports(struct tegra_xusb_padctl *padctl) static int tegra_xusb_padctl_probe(struct platform_device *pdev) { - struct device_node *np = of_node_get(pdev->dev.of_node); + struct device_node *np = pdev->dev.of_node; const struct tegra_xusb_padctl_soc *soc; struct tegra_xusb_padctl *padctl; const struct of_device_id *match; @@ -855,7 +855,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) int err; /* for backwards compatibility with old device trees */ - np = of_find_node_by_name(np, "pads"); + np = of_get_child_by_name(np, "pads"); if (!np) { dev_warn(&pdev->dev, "deprecated DT, using legacy driver\n"); return tegra_xusb_padctl_legacy_probe(pdev);