From patchwork Tue Oct 17 23:36:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Rowand X-Patchwork-Id: 10014025 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 4197860215 for ; Wed, 18 Oct 2017 08:17:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 30E4628AF1 for ; Wed, 18 Oct 2017 08:17:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 25C1B28AF9; Wed, 18 Oct 2017 08:17:15 +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 7E3A628AF1 for ; Wed, 18 Oct 2017 08:17:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BB7296E7F5; Wed, 18 Oct 2017 08:17:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pg0-x242.google.com (mail-pg0-x242.google.com [IPv6:2607:f8b0:400e:c05::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 82A406E7BF for ; Tue, 17 Oct 2017 23:36:56 +0000 (UTC) Received: by mail-pg0-x242.google.com with SMTP id v78so2698938pgb.5 for ; Tue, 17 Oct 2017 16:36:56 -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=O/8HIrAxG1MsdDXsHcX3/C3YVFuuGeGsTQOuWxGOtmA=; b=UNts246fpJcwqCijXH8Mkd8D21a4Tf1A6GonvgWqJ68dAA4ZlvG7gZ7TTpaaz5nzQq v0FlTX9r42nfU+zG9U5gFfm4vq3EaGUWPT9jEuiCGtQFCxhl7m7TjLuLn/3SQSfMhqBN Yam2oxyt9IfZQL2d5NaUIDEKKIlVTElEvtUvnNdJYkpaz817Tf4UVq3fSCsXbM4FU36/ DsjYdKfhXvxJPTjEUbCD4bS5mdjKMECEChhwEilcfm2jGbQ8qJb9726fj0XoGzr5COro RL9Ya7UISVoimYb+ow8pr6CU3D4MoTns8eLhJ/Psr4HbT6W4wnr1TfUrLhSCok2Rmsuk cFuQ== 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=O/8HIrAxG1MsdDXsHcX3/C3YVFuuGeGsTQOuWxGOtmA=; b=ELE6ulHRN9Qq6v9cPWtwndHaC9UksHGV0u0T/ZDyiaumrwGmDIHpQER/UgJy36nPaD fT5vFYCKnDZesWaRBr+9kglFnUy4udkW0WPceTChJVS4K1cx8SsfVM/bGFsOKmvyC/d1 iP0muG2+pbyMJNnTG/X5P0hSiD815qXVkvg3OE9Zm5dOVgw1i7qRIDV5CU3QaRqq0baK voT31++XhmEeZWwGAvvyfs7dHihkqYgHeREP7t+oqk92jKy4ti6gU/2pgXTad+JuWRgP HiBVZmf8feRYQygdA0CCfBczPNcSIzrM0A5Po+QWN15ljLuYq6kDEPsAlOZ/Yank2WZV Z6mA== X-Gm-Message-State: AMCzsaV1eDcL2bYudu5tAJ2entvRecxUtWdwQawulpZii3RLF3u+jt32 W7vP6rEGdp8xwUU3qKaMLH0= X-Google-Smtp-Source: AOwi7QDe1iuJG/yspxjJqhdGf/FWed1NOau+Xzz+2Jyz+eZo6AzCcN6j3ihO17nTLMLAbjvWbxMtkQ== X-Received: by 10.84.252.149 with SMTP id y21mr13500788pll.276.1508283416092; Tue, 17 Oct 2017 16:36:56 -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 76sm21185562pfq.4.2017.10.17.16.36.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Oct 2017 16:36:55 -0700 (PDT) From: frowand.list@gmail.com To: Rob Herring , Pantelis Antoniou , David Airlie , Jyri Sarha Subject: [PATCH v3 11/12] of: overlay: remove a dependency on device node full_name Date: Tue, 17 Oct 2017 16:36:31 -0700 Message-Id: <1508283392-18252-12-git-send-email-frowand.list@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1508283392-18252-1-git-send-email-frowand.list@gmail.com> References: <1508283392-18252-1-git-send-email-frowand.list@gmail.com> X-Mailman-Approved-At: Wed, 18 Oct 2017 08:17:10 +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 b98f3adffbb0..3de07e6e82a0 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -658,7 +658,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 248730567dbe..92a9a3687446 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -110,6 +110,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 602218e07ec3..0e9aefc1ff15 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; } @@ -519,6 +539,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);