From patchwork Thu Jun 5 15:43:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Likely X-Patchwork-Id: 31430 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yk0-f200.google.com (mail-yk0-f200.google.com [209.85.160.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 98A89203AC for ; Thu, 5 Jun 2014 15:43:58 +0000 (UTC) Received: by mail-yk0-f200.google.com with SMTP id q9sf3430045ykb.7 for ; Thu, 05 Jun 2014 08:43:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=9AQrjv12qrecYK4DBkd9U9OBfE5l4P1JUlWIbEPrEKc=; b=NET6VbQN0uvDjrV6vQHkcEUNXJ6jO0bGcSZykHQ152EKJkg42Oq9BOm4+Kb5cE47Gx 4M0FFm2bnDoH+NaXvsYp6y5fi7Okl/OwCrk++Gpkua6jW7j9mOGA3Q9lURY4fFGrnOQE YCAk54ZW2VTr4X6xv6ogN2SSAQ9H7dmQkF4/Ql4p1z0SpNp3+qW2Ubr4jXHMtn8TW8WR yi4311cIkCbnmtThrMtJ11HUIMCzq8i+XF9SFgBC0f/fzfXervlXcjNJFPoHgYM/tZx1 dl6ndoXMq+PMmT6T+OmM5Y6wmtvJidLzjQrArU7qLC3PLgt6xhOw198LfkjxpwLcmTif O0Bg== X-Gm-Message-State: ALoCoQkwxuZwhUoNTnzIOQ/VwDCLly6UIuDLFNZRU4u92NQNqsWYYzW0iC3VvFLgOaXw10SwNq5Y X-Received: by 10.58.187.68 with SMTP id fq4mr6515986vec.0.1401983038351; Thu, 05 Jun 2014 08:43:58 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.41.8 with SMTP id y8ls285107qgy.11.gmail; Thu, 05 Jun 2014 08:43:58 -0700 (PDT) X-Received: by 10.221.69.68 with SMTP id yb4mr2545651vcb.49.1401983038199; Thu, 05 Jun 2014 08:43:58 -0700 (PDT) Received: from mail-ve0-f170.google.com (mail-ve0-f170.google.com [209.85.128.170]) by mx.google.com with ESMTPS id fs13si3982544vdb.23.2014.06.05.08.43.58 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 05 Jun 2014 08:43:58 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.170 as permitted sender) client-ip=209.85.128.170; Received: by mail-ve0-f170.google.com with SMTP id db11so1431168veb.29 for ; Thu, 05 Jun 2014 08:43:58 -0700 (PDT) X-Received: by 10.221.26.10 with SMTP id rk10mr51381145vcb.0.1401983038118; Thu, 05 Jun 2014 08:43:58 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.54.6 with SMTP id vs6csp26625vcb; Thu, 5 Jun 2014 08:43:57 -0700 (PDT) X-Received: by 10.68.204.225 with SMTP id lb1mr78632872pbc.63.1401983036762; Thu, 05 Jun 2014 08:43:56 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id oe5si13492400pbc.154.2014.06.05.08.43.56; Thu, 05 Jun 2014 08:43:56 -0700 (PDT) Received-SPF: none (google.com: devicetree-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751569AbaFEPnz (ORCPT + 8 others); Thu, 5 Jun 2014 11:43:55 -0400 Received: from mail-we0-f174.google.com ([74.125.82.174]:53246 "EHLO mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750853AbaFEPnx (ORCPT ); Thu, 5 Jun 2014 11:43:53 -0400 Received: by mail-we0-f174.google.com with SMTP id k48so1342780wev.19 for ; Thu, 05 Jun 2014 08:43:52 -0700 (PDT) X-Received: by 10.194.220.100 with SMTP id pv4mr41884444wjc.3.1401983031572; Thu, 05 Jun 2014 08:43:51 -0700 (PDT) Received: from trevor.secretlab.ca ([213.122.173.130]) by mx.google.com with ESMTPSA id wo9sm8498660wjb.48.2014.06.05.08.43.49 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jun 2014 08:43:50 -0700 (PDT) Received: by trevor.secretlab.ca (Postfix, from userid 1000) id B32B6C41ED6; Thu, 5 Jun 2014 16:43:47 +0100 (BST) From: Grant Likely To: devicetree@vger.kernel.org Cc: rob.herring@linaro.org, Grant Likely Subject: [RFC 3/3] of: Refactor device_node child list to use list_head Date: Thu, 5 Jun 2014 16:43:41 +0100 Message-Id: <1401983021-13829-4-git-send-email-grant.likely@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1401983021-13829-1-git-send-email-grant.likely@linaro.org> References: <1401983021-13829-1-git-send-email-grant.likely@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: devicetree@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: grant.likely@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.170 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The device tree data structure uses a custom linked list implemenation which is baroque and prone to bugs. Replace the child node lists with a list_head and the common list_head accessor functions. Signed-off-by: Grant Likely Cc: Rob Herring --- drivers/of/base.c | 43 +++++++++++++++++++------------------------ drivers/of/fdt.c | 12 +++--------- include/linux/of.h | 8 +++++--- 3 files changed, 27 insertions(+), 36 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 6c0bd86b802f..69f5648babd8 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -47,6 +47,12 @@ static struct kset *of_kset; #define for_each_of_allnodes_continue(dn) \ list_for_each_entry_continue(dn, &of_allnodes, allnext) +#define of_children_prepare(parent, child) \ + list_prepare_entry(child, &parent->children, childnext) +#define for_each_of_children(parent, child) \ + list_for_each_entry(child, &parent->children, childnext) +#define for_each_of_children_continue(parent, child) \ + list_for_each_entry_continue(child, &parent->children, childnext) /* * Used to protect the of_aliases; but also overloaded to hold off addition of * nodes to sysfs @@ -711,11 +717,11 @@ static struct device_node *__of_get_next_child(const struct device_node *node, if (!node) return NULL; - next = prev ? prev->sibling : node->child; - for (; next; next = next->sibling) - if (of_node_get(next)) - break; of_node_put(prev); + next = list_next_entry(of_children_prepare(node, prev), childnext); + if (&next->childnext == &node->children) + next = NULL; + of_node_get(next); return next; } #define __for_each_child_of_node(parent, child) \ @@ -754,21 +760,21 @@ EXPORT_SYMBOL(of_get_next_child); struct device_node *of_get_next_available_child(const struct device_node *node, struct device_node *prev) { - struct device_node *next; + struct device_node *next = NULL; unsigned long flags; if (!node) return NULL; raw_spin_lock_irqsave(&devtree_lock, flags); - next = prev ? prev->sibling : node->child; - for (; next; next = next->sibling) { - if (!__of_device_is_available(next)) - continue; - if (of_node_get(next)) + of_node_put(prev); + prev = of_children_prepare(node, prev); + for_each_of_children_continue(node, prev) { + if (__of_device_is_available(prev)) { + next = of_node_get(prev); break; + } } - of_node_put(prev); raw_spin_unlock_irqrestore(&devtree_lock, flags); return next; } @@ -1976,8 +1982,7 @@ int of_attach_node(struct device_node *np) raw_spin_lock_irqsave(&devtree_lock, flags); list_add_tail(&np->allnext, &of_allnodes); - np->sibling = np->parent->child; - np->parent->child = np; + list_add_tail(&np->childnext, &np->parent->children); of_node_clear_flag(np, OF_DETACHED); raw_spin_unlock_irqrestore(&devtree_lock, flags); @@ -2016,17 +2021,7 @@ int of_detach_node(struct device_node *np) } list_del(&np->allnext); - - if (parent->child == np) - parent->child = np->sibling; - else { - struct device_node *prevsib; - for (prevsib = np->parent->child; - prevsib->sibling != np; - prevsib = prevsib->sibling) - ; - prevsib->sibling = np->sibling; - } + list_del(&np->childnext); of_node_set_flag(np, OF_DETACHED); raw_spin_unlock_irqrestore(&devtree_lock, flags); diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 6876ac3d4b30..2ff96cac1496 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -155,6 +155,7 @@ static void * unflatten_dt_node(void *blob, char *fn; of_node_init(np); np->full_name = fn = ((char *)np) + sizeof(*np); + np->parent = dad; if (new_format) { /* rebuild full path for new format */ if (dad && dad->parent) { @@ -174,15 +175,8 @@ static void * unflatten_dt_node(void *blob, prev_pp = &np->properties; list_add_tail(&np->allnext, allnext); - if (dad != NULL) { - np->parent = dad; - /* we temporarily use the next field as `last_child'*/ - if (dad->next == NULL) - dad->child = np; - else - dad->next->sibling = np; - dad->next = np; - } + if (np->parent) + list_add_tail(&np->childnext, &np->parent->children); } /* process properties */ for (offset = fdt_first_property_offset(blob, *poffset); diff --git a/include/linux/of.h b/include/linux/of.h index e082db3c284f..11bef100bc43 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -52,10 +52,11 @@ struct device_node { struct property *properties; struct property *deadprops; /* removed properties */ + + struct list_head children; /* next device of same type */ struct device_node *parent; - struct device_node *child; - struct device_node *sibling; - struct device_node *next; /* next device of same type */ + + struct list_head childnext; struct list_head allnext; struct kobject kobj; unsigned long _flags; @@ -80,6 +81,7 @@ extern int of_node_add(struct device_node *node); extern struct kobj_type of_node_ktype; static inline void of_node_init(struct device_node *node) { + INIT_LIST_HEAD(&node->children); kobject_init(&node->kobj, &of_node_ktype); }