From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935193AbcISLyR (ORCPT ); Mon, 19 Sep 2016 07:54:17 -0400 Received: from mail-de.keymile.com ([195.8.104.250]:53605 "EHLO mail-de.keymile.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933781AbcISLyC (ORCPT ); Mon, 19 Sep 2016 07:54:02 -0400 X-Greylist: delayed 350 seconds by postgrey-1.27 at vger.kernel.org; Mon, 19 Sep 2016 07:54:02 EDT X-CTCH-RefID: str=0001.0A0C0204.57DFD076.0188:SCFSTAT4379436,ss=1,re=-4.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0 From: Valentin Longchamp To: lee.jones@linaro.org, linux-kernel@vger.kernel.org Cc: Valentin Longchamp Subject: [PATCH] MFD: do not assign already already assigned compatible of_nodes Date: Mon, 19 Sep 2016 13:47:50 +0200 Message-Id: <1474285670-17078-1-git-send-email-valentin.longchamp@keymile.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If 2 similar cells have the same of_compatible (2 instances of the same functionality), they both are assigned the first found of_node with this compatible. In the below example, the pdev of both cells get the child@0 of_node. parent@0 { /* MFD devices with 2 cells reg = <0>; child@0 { reg = <0>; compatible = "child-driver"; }; child@1 { reg = <1>; compatible = "child-driver"; }; }; To avoid this, the found of_nodes are checked to see if they are already assigned in the children of the parent dev and are only assigned if still "available" (not assigned to a child). This allows the 2nd cell's pdev to get the child@1 of_node. Signed-off-by: Valentin Longchamp --- drivers/mfd/mfd-core.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 3ac486a..11c5ded 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -137,6 +137,19 @@ static inline void mfd_acpi_add_device(const struct mfd_cell *cell, } #endif +static inline int is_my_of_node(struct device *dev, void *data) +{ + struct device_node *np = data; + + return dev->of_node == np; +} + +static inline int of_node_already_in_children(struct device *dev, + struct device_node *node) +{ + return device_for_each_child(dev, node, is_my_of_node); +} + static int mfd_add_device(struct device *parent, int id, const struct mfd_cell *cell, atomic_t *usage_count, struct resource *mem_base, @@ -178,8 +191,10 @@ static int mfd_add_device(struct device *parent, int id, if (parent->of_node && cell->of_compatible) { for_each_child_of_node(parent->of_node, np) { if (of_device_is_compatible(np, cell->of_compatible)) { - pdev->dev.of_node = np; - break; + if (!of_node_already_in_children(parent, np)) { + pdev->dev.of_node = np; + break; + } } } } -- 1.8.3.1