From patchwork Tue Oct 17 01:17:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Rowand X-Patchwork-Id: 10010999 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D0F3C60211 for ; Tue, 17 Oct 2017 07:37:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C1E402871D for ; Tue, 17 Oct 2017 07:37:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B689A2876A; Tue, 17 Oct 2017 07:37:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 218C72871D for ; Tue, 17 Oct 2017 07:37:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6CB036E5DA; Tue, 17 Oct 2017 07:35:31 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf0-x241.google.com (mail-pf0-x241.google.com [IPv6:2607:f8b0:400e:c00::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7F0366E573 for ; Tue, 17 Oct 2017 01:18:20 +0000 (UTC) Received: by mail-pf0-x241.google.com with SMTP id b79so123268pfk.5 for ; Mon, 16 Oct 2017 18:18:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zFR/3rgA6r142YtYxqy0fvIW0XaYs+kiJX9Ovq51zew=; b=cDu/7DfMLu+g0fBr8T/Zrj2nVk9ys71bomJdRXj+eOsA5KAjkctAkN6P+DL2a7yWD+ Ka9Tu8PWEByMobDm7ZgbB7tadW+7cpzrLycGtOjV/13yrwjNsxNsTVW5ryxTj00U1PtQ NYtLcdMqmPut3LE8n6svbSSvlKAqUOZiKLF19iTAoxnjz55tayiPXtPDN7k031nNenAI 5+W7Eql9w/g/dhYYM+JBhGb01Pwt62pEKDIyNVRjux9hXSYY6vaEgRXtyK1UMv8kI4Dl RhrkDlP4ky/BeLb7s1pLcfVeAMwQ3hBDDVtfGKk0zbignd8ID0I07WNTpE5q2b2b4IuN XDVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zFR/3rgA6r142YtYxqy0fvIW0XaYs+kiJX9Ovq51zew=; b=pGAjAcX1it8bS/+26qeHC/uakUeAIIbOc8uoI/Vnlq3hjihz9ZHlT8sWHivir5gOId jeKQQKT4TBghInyQaPsW+VYPaa9ND4356rxwvCUU1ieQXMv7GTMgDwGlYt6itqbla6Ak 0wrDRgk9NCW1rVdzZ9IIE7FOMYBpwL8DJ5TGE9c9sF1Ep+hHf4OLlw1i1IXwqU0eySL3 m0CeK7j1nqaj5h/aS8OQx+sJZ88YoF1wDjC6l20pIYnevLavYhgmsNQBILpg9qKppRJc qlf/2/kP2diW2vF+Y9Gzpft30whIZtypNqywnPSOI93iW61qh7L7T3kq9AKqI3D+Hn54 8igw== X-Gm-Message-State: AMCzsaUYHRcNEyF+WBNhAmB5p8+rfzG/jIZsGDQTMx7+wGbX65yaq3Ep 76cIGAp0lDQQRJWnNSr3IvQ= X-Google-Smtp-Source: ABhQp+SnDBNk7RunczSM+NiHL2KcX+rlyIn1RcAUfuV5hQ6IndD2upzapZUzGJmizoaB2599XI9X0A== X-Received: by 10.84.129.36 with SMTP id 33mr2329957plb.303.1508203100138; Mon, 16 Oct 2017 18:18:20 -0700 (PDT) Received: from localhost.localdomain (c-73-93-215-6.hsd1.ca.comcast.net. [73.93.215.6]) by smtp.gmail.com with ESMTPSA id f1sm16874283pfe.150.2017.10.16.18.18.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 16 Oct 2017 18:18:19 -0700 (PDT) From: frowand.list@gmail.com To: Rob Herring , Pantelis Antoniou , David Airlie , Jyri Sarha Subject: [PATCH v2 11/12] of: overlay: remove a dependency on device node full_name Date: Mon, 16 Oct 2017 18:17:53 -0700 Message-Id: <1508203074-26917-12-git-send-email-frowand.list@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1508203074-26917-1-git-send-email-frowand.list@gmail.com> References: <1508203074-26917-1-git-send-email-frowand.list@gmail.com> X-Mailman-Approved-At: Tue, 17 Oct 2017 07:35:19 +0000 Cc: Mark Rutland , devicetree@vger.kernel.org, Tomi Valkeinen , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Frank Rowand The "%pOF" printf format was recently added to print the full name of a device tree node, with the intent of changing the node full_name field to contain only the node name instead of the full path of the node. dup_and_fixup_symbol_prop() duplicates a property from the "/__symbols__" node of an overlay device tree. The value of each duplicated property must be fixed up to include the full path of a node in the live device tree. The current code uses the node's full_name for that purpose. Update the code to use the "%pOF" printf format to determine the node's full path. Signed-off-by: Frank Rowand --- drivers/of/base.c | 2 +- drivers/of/of_private.h | 2 ++ drivers/of/overlay.c | 90 ++++++++++++++++++++++++++++++------------------- 3 files changed, 59 insertions(+), 35 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 260d33c0f26c..6f91fa67e5bb 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -760,7 +760,7 @@ struct device_node *of_get_child_by_name(const struct device_node *node, } EXPORT_SYMBOL(of_get_child_by_name); -static struct device_node *__of_find_node_by_path(struct device_node *parent, +struct device_node *__of_find_node_by_path(struct device_node *parent, const char *path) { struct device_node *child; diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 03772bdbd94b..267edb1b50df 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -93,6 +93,8 @@ extern void *__unflatten_device_tree(const void *blob, struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); __printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...); +struct device_node *__of_find_node_by_path(struct device_node *parent, + const char *path); struct device_node *__of_find_node_by_full_path(struct device_node *node, const char *path); diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 912c222ff011..a257474c9223 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -37,6 +37,7 @@ struct fragment { /** * struct overlay_changeset * @ovcs_list: list on which we are located + * @overlay_tree: expanded device tree that contains the fragment nodes * @count: count of fragment structures * @fragments: fragment nodes in the overlay expanded device tree * @symbols_fragment: last element of @fragments[] is the __symbols__ node @@ -45,6 +46,7 @@ struct fragment { struct overlay_changeset { int id; struct list_head ovcs_list; + struct device_node *overlay_tree; int count; struct fragment *fragments; bool symbols_fragment; @@ -145,12 +147,13 @@ static int overlay_notify(struct overlay_changeset *ovcs, } /* - * The properties in the "/__symbols__" node are "symbols". + * The values of properties in the "/__symbols__" node are paths in + * the ovcs->overlay_tree. When duplicating the properties, the paths + * need to be adjusted to be the correct path for the live device tree. * - * The value of properties in the "/__symbols__" node is the path of a - * node in the subtree of a fragment node's "__overlay__" node, for - * example "/fragment@0/__overlay__/symbol_path_tail". Symbol_path_tail - * can be a single node or it may be a multi-node path. + * The paths refer to a node in the subtree of a fragment node's "__overlay__" + * node, for example "/fragment@0/__overlay__/symbol_path_tail", + * where symbol_path_tail can be a single node or it may be a multi-node path. * * The duplicated property value will be modified by replacing the * "/fragment_name/__overlay/" portion of the value with the target @@ -160,59 +163,76 @@ static struct property *dup_and_fixup_symbol_prop( struct overlay_changeset *ovcs, const struct property *prop) { struct fragment *fragment; - struct property *new; - const char *overlay_name; - char *symbol_path_tail; - char *symbol_path; + struct property *new_prop; + struct device_node *fragment_node; + struct device_node *overlay_node; + const char *path; + const char *path_tail; const char *target_path; int k; - int symbol_path_tail_len; int overlay_name_len; + int path_len; + int path_tail_len; int target_path_len; if (!prop->value) return NULL; - symbol_path = prop->value; + if (strnlen(prop->value, prop->length) >= prop->length) + return NULL; + path = prop->value; + path_len = strlen(path); - new = kzalloc(sizeof(*new), GFP_KERNEL); - if (!new) + if (path_len < 1) return NULL; + fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path + 1); + overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/"); + of_node_put(fragment_node); + of_node_put(overlay_node); for (k = 0; k < ovcs->count; k++) { fragment = &ovcs->fragments[k]; - overlay_name = fragment->overlay->full_name; - overlay_name_len = strlen(overlay_name); - if (!strncasecmp(symbol_path, overlay_name, overlay_name_len)) + if (fragment->overlay == overlay_node) break; } - if (k >= ovcs->count) - goto err_free; + return NULL; + + overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay); - target_path = fragment->target->full_name; + if (overlay_name_len > path_len) + return NULL; + path_tail = path + overlay_name_len; + path_tail_len = strlen(path_tail); + + target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target); + if (!target_path) + return NULL; target_path_len = strlen(target_path); - symbol_path_tail = symbol_path + overlay_name_len; - symbol_path_tail_len = strlen(symbol_path_tail); + new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); + if (!new_prop) + goto err_free_target_path; - new->name = kstrdup(prop->name, GFP_KERNEL); - new->length = target_path_len + symbol_path_tail_len + 1; - new->value = kzalloc(new->length, GFP_KERNEL); + new_prop->name = kstrdup(prop->name, GFP_KERNEL); + new_prop->length = target_path_len + path_tail_len + 1; + new_prop->value = kzalloc(new_prop->length, GFP_KERNEL); + if (!new_prop->name || !new_prop->value) + goto err_free_new_prop; - if (!new->name || !new->value) - goto err_free; + strcpy(new_prop->value, target_path); + strcpy(new_prop->value + target_path_len, path_tail); - strcpy(new->value, target_path); - strcpy(new->value + target_path_len, symbol_path_tail); + of_property_set_flag(new_prop, OF_DYNAMIC); - of_property_set_flag(new, OF_DYNAMIC); + return new_prop; - return new; +err_free_new_prop: + kfree(new_prop->name); + kfree(new_prop->value); + kfree(new_prop); +err_free_target_path: + kfree(target_path); - err_free: - kfree(new->name); - kfree(new->value); - kfree(new); return NULL; } @@ -510,6 +530,8 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, if (!of_node_is_root(tree)) pr_debug("%s() tree is not root\n", __func__); + ovcs->overlay_tree = tree; + INIT_LIST_HEAD(&ovcs->ovcs_list); of_changeset_init(&ovcs->cset);