From nobody Sun Jun 14 00:39:52 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBEF848C8AA; Thu, 11 Jun 2026 20:35:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781210150; cv=none; b=Z5GH3iuYpOUaZQ72Zq4+g59+NwB6BVUXpuz0EMujEW70ck3hXLpRgqKdup409wpyZihBHPaNXuI/H+a6up2PhSt4zhrtLXJHVKFM9YEZu8lLQwnpyrffOekAaXUU/7VpJ1TPYuQlC1ZF88ul9NgfZNIRWrenP+09pxb5X5hrTO8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781210150; c=relaxed/simple; bh=3Q2YwluvYGccTj8xHDYb4/SxtTFNcPw+qEZ+0VjwhKY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hYRSH2YcavVBLaVeZd/ylSJPwL7rRndVHgzqAGxkTfUzbR9MomN/1TPDSrhIBv7u20kAka4izKVLcD5EWAYRhnhT5RD9wX4Z0Pix/O0zg4cZ5e3q8W3a2NBmq9ZeUkDAlmVRMhWom7RUtl/1hdhSRvRbX6tTIG3Lg5KxZagDse0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=T5EYcKdy; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="T5EYcKdy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1781210149; x=1812746149; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3Q2YwluvYGccTj8xHDYb4/SxtTFNcPw+qEZ+0VjwhKY=; b=T5EYcKdyoMAnmKRgolDZy6xB1s+gyLtBtewW+58V/yR5PYnjy28un5VF igQuDwOGmElxOP9ovjpjGM9s+JELwTMXT/rMefQn2XiP4l8hr8IuMcbcS Q/lp2sjmpzqp67WtvjpBguJznES/L1XFI9VkFoXRveweutc87hAyKM+y5 Ae4cickn1qwdJFrqzwOc3QSHg8f3JKznrHhXYF4F1uiWqBXUIo1INb599 j204jBVhg34muEW6HFN4qlgGSjA2XW/q1nABRbu10siCBlbALIkfYPWUU N3Al6i4IdOHEe+5k+mAeBl3N2tu+b5U3d/xrCB3K8zBecFrWFCXJobR87 Q==; X-CSE-ConnectionGUID: +FEOgKuGR6CK9KCPmlMymA== X-CSE-MsgGUID: vnyIaqHrTaG6d8mOYAA5Sg== X-IronPort-AV: E=McAfee;i="6800,10657,11813"; a="99456617" X-IronPort-AV: E=Sophos;i="6.24,199,1774335600"; d="scan'208";a="99456617" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jun 2026 13:35:46 -0700 X-CSE-ConnectionGUID: ocijLvAbRAahK0j1PpRIkA== X-CSE-MsgGUID: msQIaXvFSYmGwQ2JDyOchg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.24,199,1774335600"; d="scan'208";a="270631217" Received: from black.igk.intel.com ([10.91.253.5]) by fmviesa001.fm.intel.com with ESMTP; 11 Jun 2026 13:35:43 -0700 Received: by black.igk.intel.com (Postfix, from userid 1003) id C801698; Thu, 11 Jun 2026 22:35:42 +0200 (CEST) From: Andy Shevchenko To: Andy Shevchenko , Xu Yang , linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Cc: Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , stable@vger.kernel.org Subject: [PATCH v4 1/3] device property: fix infinite loop in fwnode_for_each_child_node() Date: Thu, 11 Jun 2026 22:31:06 +0200 Message-ID: <20260611203537.1786399-2-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260611203537.1786399-1-andriy.shevchenko@linux.intel.com> References: <20260611203537.1786399-1-andriy.shevchenko@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Xu Yang When iterate over children of a fwnode that has a secondary fwnode, fwnode_get_next_child_node() can enter an infinite loop if the secondary fwnode has more than one child. Parent Child (Primary fwnode) FWa: {FWa1, FWa2, FWa3} (Secondary fwnode) FWb: {FWb1, FWb2} In this case: =E2=94=8C=E2=94=80> fwnode_get_next_child_node(FWa, FWa1) =E2=94=82 - fwnode_call_ptr_op(FWa, get_next_child_node, FWa1) returns = FWa2 =E2=94=82 =E2=94=82 ... =E2=94=82 =E2=94=82 fwnode_get_next_child_node(FWa, FWa3) =E2=94=82 - fwnode_call_ptr_op(FWa, get_next_child_node, FWa3) returns = NULL =E2=94=82 - fwnode_call_ptr_op(FWb, get_next_child_node, FWa3) returns = FWb1 =E2=94=82 =E2=94=82 fwnode_get_next_child_node(FWa, FWb1) =E2=94=82 - fwnode_call_ptr_op(FWa, get_next_child_node, FWb1) returns = FWa1 =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 This cause fwnode_for_each_child_node() to loop indefinitely, reapeatedly output {FWa1, FWa2, FWa3, FWb1, FWa1, ...}. The root cause is that when the current child (FWb1) belongs to the secondary fwnode, calling get_next_child_node() on the parimary fwnode incorrectly returns the first child (FWa1) again instead of NULL. Fix this by dynamically checking the parent fwnode of the current child before calling get_next_child_node(). This approach follows the pattern established in commit b5b41ab6b0c1 ("device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint()"). Fixes: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get= _next_child_node()") Cc: stable@vger.kernel.org Signed-off-by: Xu Yang Tested-by: Andy Shevchenko Signed-off-by: Andy Shevchenko Tested-by: Xu Yang --- drivers/base/property.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index 8e0148a37fff..f7b30d9c8716 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -807,18 +807,31 @@ struct fwnode_handle * fwnode_get_next_child_node(const struct fwnode_handle *fwnode, struct fwnode_handle *child) { + const struct fwnode_handle *parent; + struct fwnode_handle *child_parent __free(fwnode_handle) =3D NULL; struct fwnode_handle *next; =20 - if (IS_ERR_OR_NULL(fwnode)) + /* + * If this function is in a loop and the previous iteration returned + * an child from fwnode->secondary, then we need to use the secondary + * as parent rather than @fwnode. + */ + if (child) { + child_parent =3D fwnode_get_parent(child); + parent =3D child_parent; + } else { + parent =3D fwnode; + } + if (IS_ERR_OR_NULL(parent)) return NULL; =20 /* Try to find a child in primary fwnode */ - next =3D fwnode_call_ptr_op(fwnode, get_next_child_node, child); + next =3D fwnode_call_ptr_op(parent, get_next_child_node, child); if (next) return next; =20 /* When no more children in primary, continue with secondary */ - return fwnode_call_ptr_op(fwnode->secondary, get_next_child_node, child); + return fwnode_get_next_child_node(parent->secondary, NULL); } EXPORT_SYMBOL_GPL(fwnode_get_next_child_node); =20 --=20 2.50.1 From nobody Sun Jun 14 00:39:52 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB7393A6B76; Thu, 11 Jun 2026 20:35:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781210149; cv=none; b=gpbp0VEJ1+5HXh5hZKjpUsORv3SSBH1qUznvSLNbth2VTL8g+WU82TfwZDCPs2zgZXTsymZmtZ/knB0ynxrip8btZT9nch0cYmeHW98vRGftL6++QGi1gk39rYZd8F1o1xU90YbvMHtA1ZBviETbJi+rYOSlCplcrrMRrWlDkUA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781210149; c=relaxed/simple; bh=C6OIarG6iVN7dquSssvxi6i1DiHTixrw0oqyWp2Vp78=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W7IAx3A8PRwUXACV1r6/z1/jSKy6aOiHhMeAu1k1RAEdwty8hHTnpsvLBy8TfjNdesVTtOf7MQMNAg4oVO8efB58+NtnnS5i59A9TuNf+Mv6Msxz/VZyR7FeCV6QcN0tMZkvOBS5SB+1sUcaR63fWoQnKaZQho2JaQ4QQPbWLwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=RicIyYic; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="RicIyYic" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1781210147; x=1812746147; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=C6OIarG6iVN7dquSssvxi6i1DiHTixrw0oqyWp2Vp78=; b=RicIyYic5c2WI8Z2B1nbbt7gI1V2ovGIJxYR0gyrABUrBhZUMrsomhCI M8eed4DDYBcUXd2Jm+zejjoJ4Z+YlYqpeFHXOkZUrOTfZ6CCgWHLzucPQ tB4TUudZ0j6vXeONHvpwu8IfnEYoGZWMF02vEuO1jLbTaxaCtbzxw073w uQ5uqK7pS475brU3ThWOhirsQHEkG1PdeLyqhhE7bfQh4RXHBsXf+gJI8 kB9AgI7Urj66Xh8AOw7d9E65hcta7adk9e37rCiA/vdzGyEli1Y0qUFle 7RtfuVhTz7qicvt+RtSRs26rqueFdHSUU6XkUoPssHyYoNoygTiDgRMzE Q==; X-CSE-ConnectionGUID: r4sqcEudTgiOVht4I9kv2A== X-CSE-MsgGUID: LRubJQe9TImPM6/NsWKIuA== X-IronPort-AV: E=McAfee;i="6800,10657,11813"; a="82144676" X-IronPort-AV: E=Sophos;i="6.24,199,1774335600"; d="scan'208";a="82144676" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jun 2026 13:35:46 -0700 X-CSE-ConnectionGUID: qe70sS8pS7i83GpM7lqeUg== X-CSE-MsgGUID: L9qEze+IRBmawzmdWggMRQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.24,199,1774335600"; d="scan'208";a="270272997" Received: from black.igk.intel.com ([10.91.253.5]) by fmviesa002.fm.intel.com with ESMTP; 11 Jun 2026 13:35:44 -0700 Received: by black.igk.intel.com (Postfix, from userid 1003) id CCDB699; Thu, 11 Jun 2026 22:35:42 +0200 (CEST) From: Andy Shevchenko To: Andy Shevchenko , Xu Yang , linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Cc: Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Subject: [PATCH v4 2/3] device property: Refactor to use RAII approach Date: Thu, 11 Jun 2026 22:31:07 +0200 Message-ID: <20260611203537.1786399-3-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260611203537.1786399-1-andriy.shevchenko@linux.intel.com> References: <20260611203537.1786399-1-andriy.shevchenko@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In a couple of functions code can be made cleaner with help of __free() macro. Refactor these to use RAII approach. Signed-off-by: Andy Shevchenko --- drivers/base/property.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index f7b30d9c8716..808e8a90c125 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -7,10 +7,10 @@ * Mika Westerberg */ =20 +#include #include #include #include -#include #include #include #include @@ -517,7 +517,6 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string); int fwnode_property_match_string(const struct fwnode_handle *fwnode, const char *propname, const char *string) { - const char **values; int nval, ret; =20 nval =3D fwnode_property_string_array_count(fwnode, propname); @@ -527,20 +526,18 @@ int fwnode_property_match_string(const struct fwnode_= handle *fwnode, if (nval =3D=3D 0) return -ENODATA; =20 - values =3D kcalloc(nval, sizeof(*values), GFP_KERNEL); + const char **values __free(kfree) =3D kcalloc(nval, sizeof(*values), GFP_= KERNEL); if (!values) return -ENOMEM; =20 ret =3D fwnode_property_read_string_array(fwnode, propname, values, nval); if (ret < 0) - goto out_free; + return ret; =20 ret =3D match_string(values, nval, string); if (ret < 0) - ret =3D -ENODATA; + return -ENODATA; =20 -out_free: - kfree(values); return ret; } EXPORT_SYMBOL_GPL(fwnode_property_match_string); @@ -1128,8 +1125,9 @@ struct fwnode_handle * fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, struct fwnode_handle *prev) { - struct fwnode_handle *ep, *port_parent =3D NULL; const struct fwnode_handle *parent; + struct fwnode_handle *port_parent __free(fwnode_handle) =3D NULL; + struct fwnode_handle *ep; =20 /* * If this function is in a loop and the previous iteration returned @@ -1147,13 +1145,9 @@ fwnode_graph_get_next_endpoint(const struct fwnode_h= andle *fwnode, =20 ep =3D fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev); if (ep) - goto out_put_port_parent; + return ep; =20 - ep =3D fwnode_graph_get_next_endpoint(parent->secondary, NULL); - -out_put_port_parent: - fwnode_handle_put(port_parent); - return ep; + return fwnode_graph_get_next_endpoint(parent->secondary, NULL); } EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint); =20 --=20 2.50.1 From nobody Sun Jun 14 00:39:52 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8272847CC9B; Thu, 11 Jun 2026 20:35:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781210150; cv=none; b=SoWPHgpkRlcHktBkZ2LfpLjHtup/cgAe2Q5pGAiPzu/cT30mAaxJwD7y3+/1WBxAhCMTWAyhuxBSgpHo/JGlIOcB0GM4dG5spDYgwQV7uvyIlESBanFxm4KcvHNKWZzKc+H/1r2TpSSRs/B9j1I0F3+NlJ1SS4OS3RjNySb5NWs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781210150; c=relaxed/simple; bh=f4dfwOVe/IPX9UmzalevLBZHEmKjqRmHsZGnkjby5TY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HHoB50XYEDpoqOViqmZ6+pW/7Q58KeLK2GquyehvfT1GNR9Hgtpdw+786krlDkoVkY4sPmyvH+P0L1B95ERnVDYQ6jSLus8jafLHnUGiEOFbgTGkLDgZI8CIKm/vLHmxmjE+iwMHRakFd7So9BtTx1xZdqfSOeMNjc3mX6pUjC0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=EybznAiN; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="EybznAiN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1781210148; x=1812746148; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=f4dfwOVe/IPX9UmzalevLBZHEmKjqRmHsZGnkjby5TY=; b=EybznAiNs9LWFUoSLM73b01vhowoWtjiizVyXv34mA8jpgMy8Jsun8ZI /QmP6+HTvrpvDuXMMxHkx9utqOcl4iKVpWKqkgoQqaGD49Y2BwObok7Vb karQNVGWNiJKNM5KOrsYFxpGQu5E5yv4HfAK2LgLxixRpAXThivNeLfps ekgi6lkTrqWClksydBtOIwSBfnz60neVNhGDV5q3ECJhJnZL2Ik/3xuse kOp4QyrJ8sm7OqS0gW3kobicFr9N5NzIr8itzmJRJG7CG+bnJH0Jhe61f eLFDG10YHmQosBAXn98FscydWfvTMjdAd45D40CkR/9aL5DsSVzOfd3L+ Q==; X-CSE-ConnectionGUID: eipcjib2TjmRGpMowv9VPA== X-CSE-MsgGUID: F6g9aZdPSV2UNRiY8IJScQ== X-IronPort-AV: E=McAfee;i="6800,10657,11813"; a="99456611" X-IronPort-AV: E=Sophos;i="6.24,199,1774335600"; d="scan'208";a="99456611" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jun 2026 13:35:46 -0700 X-CSE-ConnectionGUID: oa5sI2tAQuGXyuvgqF8s+g== X-CSE-MsgGUID: yXEpydJaSwmJcJbWrfBvyQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.24,199,1774335600"; d="scan'208";a="270631218" Received: from black.igk.intel.com ([10.91.253.5]) by fmviesa001.fm.intel.com with ESMTP; 11 Jun 2026 13:35:43 -0700 Received: by black.igk.intel.com (Postfix, from userid 1003) id D19749B; Thu, 11 Jun 2026 22:35:42 +0200 (CEST) From: Andy Shevchenko To: Andy Shevchenko , Xu Yang , linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Cc: Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Subject: [PATCH v4 3/3] device property: add test cases for fwnode_for_each_child_node() Date: Thu, 11 Jun 2026 22:31:08 +0200 Message-ID: <20260611203537.1786399-4-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260611203537.1786399-1-andriy.shevchenko@linux.intel.com> References: <20260611203537.1786399-1-andriy.shevchenko@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xu Yang Add test cases for fwnode_for_each_child_node() API. Test command: $ ./tools/testing/kunit/kunit.py run property-entry Signed-off-by: Xu Yang Signed-off-by: Andy Shevchenko --- drivers/base/test/Kconfig | 1 + drivers/base/test/property-entry-test.c | 136 ++++++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/drivers/base/test/Kconfig b/drivers/base/test/Kconfig index 2756870615cc..95fc42e91564 100644 --- a/drivers/base/test/Kconfig +++ b/drivers/base/test/Kconfig @@ -17,4 +17,5 @@ config DM_KUNIT_TEST config DRIVER_PE_KUNIT_TEST tristate "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS depends on KUNIT + select OF default KUNIT_ALL_TESTS diff --git a/drivers/base/test/property-entry-test.c b/drivers/base/test/pr= operty-entry-test.c index a8657eb06f94..a3d1caf28cc7 100644 --- a/drivers/base/test/property-entry-test.c +++ b/drivers/base/test/property-entry-test.c @@ -4,6 +4,8 @@ // Copyright 2019 Google LLC. =20 #include + +#include #include #include =20 @@ -489,6 +491,139 @@ static void pe_test_reference(struct kunit *test) software_node_unregister_node_group(group); } =20 +static struct fwnode_handle *create_device_node(struct kunit *test, + const char *name, + const char *full_name, + struct device_node *parent) +{ + struct device_node *node; + + node =3D kunit_kzalloc(test, sizeof(*node), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); + + node->name =3D kunit_kstrdup(test, name, GFP_KERNEL); + node->full_name =3D kunit_kstrdup(test, full_name, GFP_KERNEL); + + if (parent) { + node->sibling =3D parent->child; + /* set the node as the first child of the parent */ + parent->child =3D node; + node->parent =3D parent; + } + + of_node_init(node); + return of_fwnode_handle(node); +} + +/* Verifies that fwnode_for_each_child_node() can output correct children = */ +static void pe_test_child_iteration(struct kunit *test) +{ + struct fwnode_handle *of_node, *of_node1; + struct fwnode_handle *sw_node, *sw_node1; + struct fwnode_handle *child; + int error, i, num; + + static const struct software_node node =3D { .name =3D "sw" }; + static const struct software_node node1 =3D { .name =3D "sw-1", .parent = =3D &node}; + static const struct software_node node2 =3D { .name =3D "sw-2", .parent = =3D &node}; + static const struct software_node node3 =3D { .name =3D "sw-3", .parent = =3D &node}; + static const struct software_node *group[] =3D { &node, &node1, &node2, &= node3, NULL }; + + static const char * const of_child_array[] =3D { "of-1", "of-2", "of-3" }; + static const char * const sw_child_array[] =3D { "sw-1", "sw-2", "sw-3" }; + static const char * const of_sw_child_array[] =3D { "of-1", "of-2", "of-3= ", + "sw-1", "sw-2", "sw-3" }; + static const char * const sw_of_child_array[] =3D { "sw-1", "sw-2", "sw-3= ", + "of-1", "of-2", "of-3" }; + + /* 1. Test OF node child iteration */ + + of_node =3D create_device_node(test, "of", "of", NULL); + create_device_node(test, "of", "of-3", to_of_node(of_node)); + create_device_node(test, "of", "of-2", to_of_node(of_node)); + of_node1 =3D create_device_node(test, "of", "of-1", to_of_node(of_node)); + + i =3D 0; + num =3D ARRAY_SIZE(of_child_array); + fwnode_for_each_child_node(of_node, child) { + KUNIT_ASSERT_LT(test, i, num); + KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child)); + } + KUNIT_EXPECT_PTR_EQ(test, child, NULL); + + /* 2. Test SW node child iteration */ + + error =3D software_node_register_node_group(group); + KUNIT_ASSERT_EQ(test, error, 0); + + sw_node =3D software_node_fwnode(&node); + + i =3D 0; + num =3D ARRAY_SIZE(sw_child_array); + fwnode_for_each_child_node(sw_node, child) { + KUNIT_ASSERT_LT(test, i, num); + KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child)); + } + KUNIT_EXPECT_PTR_EQ(test, child, NULL); + + /* 3. Test OF (primary) + SW (secondary) node child iteration */ + + of_node->secondary =3D sw_node; + sw_node->secondary =3D ERR_PTR(-ENODEV); + + i =3D 0; + num =3D ARRAY_SIZE(of_sw_child_array); + fwnode_for_each_child_node(of_node, child) { + KUNIT_ASSERT_LT(test, i, num); + KUNIT_EXPECT_STREQ(test, of_sw_child_array[i++], fwnode_get_name(child)); + } + KUNIT_EXPECT_PTR_EQ(test, child, NULL); + + /* 4. Test SW (primary) + OF (secondary) node child iteration */ + + sw_node->secondary =3D of_node; + of_node->secondary =3D ERR_PTR(-ENODEV); + + i =3D 0; + num =3D ARRAY_SIZE(sw_of_child_array); + fwnode_for_each_child_node(sw_node, child) { + KUNIT_ASSERT_LT(test, i, num); + KUNIT_EXPECT_STREQ(test, sw_of_child_array[i++], fwnode_get_name(child)); + } + KUNIT_EXPECT_PTR_EQ(test, child, NULL); + + /* 5. Test OF (primary) + SW (secondary, but no children) node child iter= ation */ + + sw_node1 =3D software_node_fwnode(&node1); + of_node->secondary =3D sw_node1; + sw_node->secondary =3D ERR_PTR(-ENODEV); + + i =3D 0; + num =3D ARRAY_SIZE(of_child_array); + fwnode_for_each_child_node(of_node, child) { + KUNIT_ASSERT_LT(test, i, num); + KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child)); + } + KUNIT_EXPECT_PTR_EQ(test, child, NULL); + + /* 6. Test SW (primary) + OF (secondary, but no children) node child iter= ation */ + + sw_node->secondary =3D of_node1; + of_node->secondary =3D ERR_PTR(-ENODEV); + + i =3D 0; + num =3D ARRAY_SIZE(sw_child_array); + fwnode_for_each_child_node(sw_node, child) { + KUNIT_ASSERT_LT(test, i, num); + KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child)); + } + KUNIT_EXPECT_PTR_EQ(test, child, NULL); + + of_node->secondary =3D NULL; + sw_node->secondary =3D NULL; + software_node_unregister_node_group(group); +} + static struct kunit_case property_entry_test_cases[] =3D { KUNIT_CASE(pe_test_uints), KUNIT_CASE(pe_test_uint_arrays), @@ -497,6 +632,7 @@ static struct kunit_case property_entry_test_cases[] = =3D { KUNIT_CASE(pe_test_move_inline_u8), KUNIT_CASE(pe_test_move_inline_str), KUNIT_CASE(pe_test_reference), + KUNIT_CASE(pe_test_child_iteration), { } }; =20 --=20 2.50.1