From nobody Sat Jul 25 21:20:42 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 D558E387569 for ; Mon, 13 Jul 2026 11:15:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941309; cv=none; b=Lqi4sXr7MSjhlONfWNw1L6tgVjaXxCpEi9aap1q7t42ROfiwQVTKM8vyPHI3D53g2xMf8tvAj6XMlOmoI9776LR8+RlfTw1FQYYpIkURNiDrDLaff0tWpzx5REXj5JWUChwS07MUFbKC4jP9QtGMPcTbwQCyT/axTDXDfCZYnPc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941309; c=relaxed/simple; bh=uFLoL2fvDTFtaPGJjiYzbRQ0YLyv32CJCl3JGUiomJ0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CHchk/nvmGQACsyR/qduvmHzc9nTwPxGdUz1YGHz8wkmgF3WQ2eL0yKuB26mqAhCpi82IbR2yBhTV7WTW8pM83h8YPJ9PibvJIYNTJdZ8M9E7ORe376wIf1M7ic3MoaGKVphoxb74q+pvGTp8vHuvhhwUdzkBfrSI8hqkOU5PSo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=kEA28Ldy; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=IMVbijq/; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="kEA28Ldy"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="IMVbijq/" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66D9ucCS1089702 for ; Mon, 13 Jul 2026 11:15:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= YlTE9tG9MyDB8d3Vffq87ifEYJb3TdmU4EqBwnnxKpc=; b=kEA28LdyBQ3Ug6yo 21hsuGc9OORE7PCXmMcOrZFD2aSRkngX/W9h4pOoQvUlB3a7NjCaxTdtf5vIPS1M gJKbEay9zu+k2gCx8cdEDVvHYz5rGmsbb49n+b4Ar2NU1HQUehZF2uk+e1hwYPm6 7DJBxtYc7eFJbZZooKH2ZShrvGDx8GSaC6w5AenPzRYPS9ivCIgGsRkWgfJh4dZH 4fkpbQKVPVwKHS88sZzHFA17x6Ekw027wHyAjgvim3Jj0Jf30Ae529nk+/d/IFWZ iQ/dcOSIBnuBjDob2zXQwSagUF4TX6m6vs6ToEnfmxlFP6JTfVL6rQ6Gn5C+tPn2 xTTDGg== Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fcwu4r8tv-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 13 Jul 2026 11:15:06 +0000 (GMT) Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-51bf321d786so36177041cf.1 for ; Mon, 13 Jul 2026 04:15:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783941306; x=1784546106; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YlTE9tG9MyDB8d3Vffq87ifEYJb3TdmU4EqBwnnxKpc=; b=IMVbijq/jZZ08IxkW7vSemhGAH9bB8cLDgGuuWiIXXQ52VbQO+YPjde2ZGI8Z1Kof5 CwzMcIfcP8HFECyItvgSAnGTxLJkcF8ae9gO1CijkMvfxxYJqSTebTIH/IXomoczL8yW qsFH8wJ5TXlHKqMyKDYCSVfE5t+oCJ6pUOLPrkbE736swhzPBD33+QSL0Mz94IkgE+4y fLSYANRHk7KESZ0GGpXLqY3A795AIoPoY0moDM61Xz3N1AU6OvrXFEzyaTy6SvBheZ0t X6QRZ8nCY7wTXzCj8mLBgHyZl1gW56VTa5iu5WzVB1VmXZqhNEvkDMULFKdkgD3EFnZc y/uA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783941306; x=1784546106; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=YlTE9tG9MyDB8d3Vffq87ifEYJb3TdmU4EqBwnnxKpc=; b=C1z1rADjXRiebLwR6U53HWOGkVxeLRIGYun9eFEv928k7YlWHB15CJVn1TZWORAw5/ 5wkHNDs/Gfvh7wUTwuLdCc1Hgt9/W/DcSE+18xg2349zogNfzrZHH0lDpBtQRTzqgr3z SqQxJoYXvx6bIg6yK0PQt8k6CWEIN974tYW3QtlDNaOZk6Xb1QpmXYmZrohgCivwHFQC iHk19ysRbMepZETj0KCR9Zc+TXxAHXgE7rnq8c1+Z7nAE75E7k2wLKanJZvzKRrSxtXE XMnzaY1IUVIiuheRMjmJ7dqaGTnkbfUIkqHT30xaPmBFiVbtuz6Tlo7wCSogU12UcD/J YCBg== X-Gm-Message-State: AOJu0YyLexyNyjQqq4IsFHqekMWcEoCHap58H9bGgihRrzNkET1avFon 9FZzGIfqdQPK8r0h6foOHwguBGlR5MJCZSg1Bg0h+cJlJ4mx9QMPqPCCwTaQpMNgUJSKXcKoaoY 4QS9Zt2T1ecJ+CciSBmOlCT5Efyulf6DGOXBFxoYU985ugAxKJ2jBKeNJJ12u0Sb2PUMOrgtKcH U= X-Gm-Gg: AfdE7clcDDUxmHCgOu4Y5vsBUOxbw2T3IMsxa9x+A1V/hWGNIvt2jmyQxuYfCx+ASuN +M1F84vbeUuhfQBQgcmtobzmL4stJI0atMIuW2Mpy7543r+momXWIuZlPftu4LZ8Re1MwINwnWJ CXP+FCLsib4hmywgdgPlLqPzccE+fDO7sOPb5TRD3VQVZnYWaTtX2z3CqkptRxd8aVtbWKQkcyb otQuMqSVC8yllu2C0WV8xnwONnz6L5SxGHQ+ler7IDHMTP1CeuPS/rmTe0h8VXTPKmEf5dwFnoO QEEUCM/9ESQQI8I+8e5nOodJ7r+sB3LhcEu6yGjyqqYg/PJuoPlKaRrw9d8/DWXUbrlDhys+5KZ 07xBDxF9s7Fbsto0UoWWFf0Y2AJptVzKdLItVW0sW X-Received: by 2002:ac8:7d0d:0:b0:51c:140c:6893 with SMTP id d75a77b69052e-51cbf058eb2mr82898551cf.11.1783941305987; Mon, 13 Jul 2026 04:15:05 -0700 (PDT) X-Received: by 2002:ac8:7d0d:0:b0:51c:140c:6893 with SMTP id d75a77b69052e-51cbf058eb2mr82897921cf.11.1783941305455; Mon, 13 Jul 2026 04:15:05 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:8881:83b8:89fa:1a2a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa0f214d2sm82323160f8f.33.2026.07.13.04.15.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2026 04:15:03 -0700 (PDT) From: Bartosz Golaszewski Date: Mon, 13 Jul 2026 13:14:44 +0200 Subject: [PATCH v4 1/5] kunit: provide a set of fwnode-oriented helpers 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 Message-Id: <20260713-swnode-fw-devlink-v4-1-d4f2dee27ad9@oss.qualcomm.com> References: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> In-Reply-To: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> To: Brendan Higgins , David Gow , Rae Moar , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Bartosz Golaszewski , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Linus Walleij , Dmitry Torokhov Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-gpio@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6696; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=uFLoL2fvDTFtaPGJjiYzbRQ0YLyv32CJCl3JGUiomJ0=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBqVMiu+nsriE3lOF9zrRtytxUH2n+H0QN6LfRCx cLBlDZOkMOJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCalTIrgAKCRAFnS7L/zaE w+OxD/973xGLRGLOocJWBtz3tDcEyidl5QcoNu1o/BmJ8bmpshzd9DbKi6mUMvJ7cUXUL3hIl+0 JhTpNCwomo8J6p9mzXG5XpRj7vt4n5gtoYG+xHLxqhJv/rwYZouzzfjgpiWQEBrkXpIpo9p4TCt szPq6BBhhsXssuZ+pCQTlJiCrPtqUAOGIKLglxwEX+PfI7e7ebDYsIYBxQQsdulW7WW0SuElc6N duy5VViezwsA73FchoFNzNe2MqXmylcMcO4ZJ5X+Lex/FLguDimknnlXQUjxbQqHpPE8gFh5nht Yye/mAChuLnWqw2ImH65Z36MaXsQUdeVfr4gE7nCFXmDvUMPVIfnu7m+S1+REbHzeb1rPIPucK9 8mOfBd5Kv5yqdbnP4x5Mqqd4ceF+Q3ifP8oLJdLBaqMZR1kHhZVf5Q8qeV3QkeNrFDR5km2UfIU n8iOlfXAV/e3HoQoTVwkmnsm+0xfaHjQCzKjHtHLQ/gPmNUeChjcIT3evwRV8MnszkjNsswBLzx xZcmulKIuzxW02naVlpUZW7cjlmhZtr25cv9vSpYo0qjFNfmn+4GGc3C+Z4ONrHRIrDxQgaGSpO 1+M2YuLUXh6DRGcplbcrF+q3cYXO2VQQ6Nx7Ip4+EvIoUHu8FlDj0w8fzi85jHvKHm9gahD0nFv uCDgq7HGFUdwAKw== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Authority-Analysis: v=2.4 cv=FMErAeos c=1 sm=1 tr=0 ts=6a54c8ba cx=c_pps a=EVbN6Ke/fEF3bsl7X48z0g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=nzuXsxulAAAA:8 a=EUspDBNiAAAA:8 a=5HYbyjZdm2YZoA3apZYA:9 a=QEXdDO2ut3YA:10 a=a_PwQJl-kcHnX1M80qC6:22 a=Jn5cl5okm61iLnyvC_SE:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX+KqCIBf+B9or oSSXY7kW6oCvIrqS8/76Vr8xuKBKj5R2tyRTU7DYRIEhv+wjBDNvvgXVxbd8J+647Axk6s49H2B YcxSnSS04sn4emVGtKI3juyVL+MooKY= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX3IvYeMu8HP1L AS2BFcI8iCxmU/8Bv9Nnc687aQCyjQ43CffbYLeOD7r13ujlKbSZbQk5qwIigCP0BeaJ+VWdDWY gPTfDn0mgk4nfv+ioR/TQ3a7+cNQTBhp4KCRaVC4tTjjsaFwWqaWAYqcRGovdESdugGDew/tx58 Qz5j5+m0G8szRrTwknlKIvAq8Nsq/P+opQ8UL7nBkLO6nz5Fo1e3pE004bQAXkbgsbr+i8n+0D8 GjmPkoTsClsgex8z09CowASuBmEYsBJi/f8b8F+9RWB7CfdFSQghG8mm+vVLfii78x+iW1gNuKL 5somyzrOgpsXF90IMIvok8pqaoy4rZijnJWR4RDrp5nQV7a3ks8De2xB9xPgzjByBmZwKm5XeQ/ zMTPnN6fZnrAxH+pQj+XEAx1GN3wuvMnHs7hSMaE8ywMizKAnphAPCZalxraam/Oa5kTDLQ5QYb LWYDGAhhp9wz7PaRT/w== X-Proofpoint-ORIG-GUID: mWnTKcfuoo3n-9ASbifSaqJOjNaBcUEv X-Proofpoint-GUID: mWnTKcfuoo3n-9ASbifSaqJOjNaBcUEv X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-13_02,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 bulkscore=0 malwarescore=0 impostorscore=0 suspectscore=0 priorityscore=1501 phishscore=0 spamscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607130117 Provide three new kunit-managed helpers for test cases that need to register/create dynamic software nodes. Reviewed-by: David Gow Signed-off-by: Bartosz Golaszewski --- include/kunit/fwnode.h | 29 ++++++++++ lib/kunit/Makefile | 1 + lib/kunit/fwnode.c | 146 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 176 insertions(+) diff --git a/include/kunit/fwnode.h b/include/kunit/fwnode.h new file mode 100644 index 0000000000000000000000000000000000000000..e250bb87e144c42b1a7e439947a= 224f50a253179 --- /dev/null +++ b/include/kunit/fwnode.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * KUnit resource management helpers for firmware nodes. + * + * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries + */ + +#ifndef _KUNIT_FWNODE_H +#define _KUNIT_FWNODE_H + +struct device; +struct fwnode_handle; +struct kunit; +struct property_entry; +struct software_node; + +struct fwnode_handle * +kunit_fwnode_create_software_node(struct kunit *test, + const struct property_entry *properties, + const struct fwnode_handle *parent); +struct fwnode_handle * +kunit_software_node_register(struct kunit *test, + const struct software_node *node); +int kunit_software_node_register_node_group(struct kunit *test, + const struct software_node *const *nodes); +int kunit_device_add_software_node(struct kunit *test, struct device *dev, + const struct software_node *node); + +#endif /* _KUNIT_FWNODE_H */ diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile index 2e8a6b71a2ab07a738964a7ef0f442fd53e085b1..204e02b10eba1030c6d511991fe= 2f6271de64603 100644 --- a/lib/kunit/Makefile +++ b/lib/kunit/Makefile @@ -11,6 +11,7 @@ kunit-objs +=3D test.o \ attributes.o \ device.o \ platform.o \ + fwnode.o \ bug.o =20 ifeq ($(CONFIG_KUNIT_DEBUGFS),y) diff --git a/lib/kunit/fwnode.c b/lib/kunit/fwnode.c new file mode 100644 index 0000000000000000000000000000000000000000..a58ce0984d76bae1072d77abc26= f4cd516e487ea --- /dev/null +++ b/lib/kunit/fwnode.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries + */ + +#include +#include + +#include +#include + +KUNIT_DEFINE_ACTION_WRAPPER(fwnode_remove_software_node_wrapper, + fwnode_remove_software_node, + struct fwnode_handle *); + +/** + * kunit_fwnode_create_software_node() - Create a kunit-managed software n= ode + * @test: Test context + * @properties: Properties to use to create the new software node + * @parent: Parent of this software node + * + * Create a test-managed software node and return its firmware node handle. + * The software node is removed after the test case completes. + * + * Returns: + * Firmware node handle of the newly created software node or IS_ERR() on + * failure. + */ +struct fwnode_handle * +kunit_fwnode_create_software_node(struct kunit *test, + const struct property_entry *properties, + const struct fwnode_handle *parent) +{ + struct fwnode_handle *fwnode; + int ret; + + fwnode =3D fwnode_create_software_node(properties, parent); + if (IS_ERR(fwnode)) + return fwnode; + + ret =3D kunit_add_action_or_reset(test, fwnode_remove_software_node_wrapp= er, + fwnode); + if (ret) + return ERR_PTR(ret); + + return fwnode; +} +EXPORT_SYMBOL_GPL(kunit_fwnode_create_software_node); + +KUNIT_DEFINE_ACTION_WRAPPER(software_node_unregister_wrapper, + software_node_unregister, + const struct software_node *); + +/** + * kunit_software_node_register() - Register a kunit-managed software node + * @test: Test context + * @swnode: Software node to register + * + * Register a test-managed software node and return its firmware node hand= le. + * The software node is unregistered after the test case completes. + * + * Returns: + * Firmware node handle of the registered software node or IS_ERR() on fai= lure. + */ +struct fwnode_handle * +kunit_software_node_register(struct kunit *test, + const struct software_node *swnode) +{ + struct fwnode_handle *fwnode; + int ret; + + ret =3D software_node_register(swnode); + if (ret) + return ERR_PTR(ret); + + fwnode =3D software_node_fwnode(swnode); + if (WARN_ON(!fwnode)) + return ERR_PTR(-ENOENT); + + ret =3D kunit_add_action_or_reset(test, software_node_unregister_wrapper, + (void *)swnode); + if (ret) + return ERR_PTR(ret); + + return fwnode; +} +EXPORT_SYMBOL_GPL(kunit_software_node_register); + +KUNIT_DEFINE_ACTION_WRAPPER(software_node_unregister_node_group_wrapper, + software_node_unregister_node_group, + const struct software_node *const *); + +/** + * kunit_software_node_register_node_group() - Register a kunit-managed so= ftware node group + * @test: Test context + * @nodes: Software node group to register + * + * Register a test-managed software node group. The nodes are unregistered + * after the test case completes. + * + * Returns: + * 0 on success, negative error number on failure. + */ +int kunit_software_node_register_node_group(struct kunit *test, + const struct software_node *const *nodes) +{ + int ret; + + ret =3D software_node_register_node_group(nodes); + if (ret) + return ret; + + return kunit_add_action_or_reset(test, software_node_unregister_node_grou= p_wrapper, + (void *)nodes); +} +EXPORT_SYMBOL_GPL(kunit_software_node_register_node_group); + +KUNIT_DEFINE_ACTION_WRAPPER(device_remove_software_node_wrapper, + device_remove_software_node, + struct device *); + +/** + * kunit_device_add_software_node() - Assign a kunit-managed software node= to a device + * @test: Test context + * @dev: Device to assign the software node for + * @node: The software node to assign + * + * Make @node the secondary firmware node of @dev. If @dev has no primary + * firmware node, @node will become the primary node. The software node wi= ll + * be automatically removed from @dev when the test case completes. + * + * Returns: + * 0 on success, negative error number on failure. + */ +int kunit_device_add_software_node(struct kunit *test, struct device *dev, + const struct software_node *node) +{ + int ret; + + ret =3D device_add_software_node(dev, node); + if (ret) + return ret; + + return kunit_add_action_or_reset(test, device_remove_software_node_wrappe= r, dev); +} +EXPORT_SYMBOL_GPL(kunit_device_add_software_node); --=20 2.47.3 From nobody Sat Jul 25 21:20:42 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 81D77388382 for ; Mon, 13 Jul 2026 11:15:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941312; cv=none; b=HL70LaQg35pY6H6vQ8iaOtWBA+XLM0JwmxZdvYI0bWNbzcZZ1ZU9bAn3XRAlqI2g0RgoJJymerRZlFYrJEO4vI7ynOoXhTcBpVKubZvOusjvn6pNJcEXdXJjtWZrteEFyoBu+8Ya9xkOWAAIFZtt2EcQoXP9RhUZWllAdh5l8jQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941312; c=relaxed/simple; bh=O9NkHL6JYILIp7mfm0RnOgr/0S6YPfzPn6jbv5EJbjU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IFDj40h0CR/7a2ENhk4pSI1XM38qKkmMP8/Via/c3GHGvFO3P+oeSS1af0nAMbF8LfCkhrehBCKAu0OJruGO5V/zlsr2ZzR+qyLFoBPkPYNapVgn5tGw1qVyGXEV0CCjtwS1dpXTsku/yGb1hBISAiEJmnpsSlkmqg0ToXCjSfo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=RYh6cDyp; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=SvfnpIz3; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="RYh6cDyp"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="SvfnpIz3" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66D9ucYE1089701 for ; Mon, 13 Jul 2026 11:15:09 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= okGnys6Dq42n97G+YBE9VPTayEfByn7CtWc7od0TY/Y=; b=RYh6cDypsF1bP+QG Z4qVwPP2cR80gKUg1fPaK8tCo5IUPTfgtNOdxx+2W7pEdbGDur+HOudFcd4TDtbh br1ltp21Qa7t10NW2C13DhyQTGwIK71YNSCB1xv2dFKwz626Uxpvm49ksJixSCZR JV1mvp2ZRzKutzAqRYbuxK6FXhJQiyLM9NewJ++A4ctoJrtyQ1e5XAzf0S+XsrS4 AcXrWrf7Y6eDycSdp0Bt1Nce1QdWrW+WvoltYjX09lzXXwT3A39XFJTifJsuHB8d piaGTAp/oXfq9Ji6N9qRkptvEKBb1dP3j4qVhDQXFnZxSo6hPRpF3dW+rIC6WNbx pnKJkA== Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fcwu4r8ub-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 13 Jul 2026 11:15:09 +0000 (GMT) Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-51c083f1818so42212451cf.0 for ; Mon, 13 Jul 2026 04:15:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783941309; x=1784546109; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=okGnys6Dq42n97G+YBE9VPTayEfByn7CtWc7od0TY/Y=; b=SvfnpIz3gUQR6aUwNSQPUPAvk/7HjD1IWvbxWHTJzWI9KSYtl0YB5Jb9wcNcXpQsyK Xp/VY6G6BsSlteDhOlZkQA2wo3WIEm08z+mthjVsg9XWM/cWq7ul77Yzfo1g0daXlkqg vvvkpH37o5P/n6PlV/FSXVgcwCkKq2Ctn1G/cuEOPmIotKNCLAq5S3WRujfg7wW48Osy Hkg12R0jP0Yf75TZcZzcwFdV+eI5FYctZYXzKBngF9z72Hs7pZ5XlDs5txKJfwCNDspF E2QDtqqkuj9fB9m4vLvY9llfuv/B9R/eNvbOaVpNu7sQ5Uuvfa0nFV1IeisJQ4UHx8AQ dqHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783941309; x=1784546109; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=okGnys6Dq42n97G+YBE9VPTayEfByn7CtWc7od0TY/Y=; b=iYlDveHrHWZISCLgjSVNvcHbTMeJ1wmO2k/IrgJC0sA6Zsf1x9EfmMv5NATzzjDtyD DjWaD1BdSRCROVEJkI4HK8+vKAOMd5mjJ6W0QmSc623lLcpXn5yoDhE6gem5cb4znDEC hsG7rbiFmtO1w18GScwVR2ySrifrYFpurlxdfUDuAGyBjzko9RH89u3/tBhDsuR+jy3A uWwxQ2/VnyaCGWNtteDgAqa1UgpaQbhFDEJ80ZH7/slZONhkIWlkukfHJXGdkmvh7+Kb JRp2IWE2w6p6p6xZyMrHsz3BQ+F+b7esiTsR9KyR68vfTInBkk/Mw6IYZ0innwQRrgDJ nMHA== X-Gm-Message-State: AOJu0YwGaeHxk6onID0UppXqf/8l2yAe1azk7hxsCIT+32l34pOS/dDt lw82OJZ0sr1G3fU3X/4xbAdO9D20zUx6pSoxO1OBlc4GoAEpzpeQUocUdRmSXN1Q+IGLrH/61qf WH9QIN7q+bmWuqy2b3xZ1R+WsGQng2iPSCCbSa2+VSVvvywSD20+Ac6tfXhELHqR7mbbTUER1lJ I= X-Gm-Gg: AfdE7ckOgAlRNQL1I1A9aGZYhLfcqd04V8pZxXzh2h6KY6RDpYa2j+qjmVFWWJ4VSqb qv1zFJswrC6LFLkXx8sS2BZugjtYyh11TXqSF58thJyRBs/r1sMowAn7uUB4FhqpxysdZlOsTXd 87Nkz2PlkA2Xah773bgNaoHm79ecOESe+hiATgrcHDlnxKVjdfAVmGHa+C7Fzwklu271vzSZ6M6 6I/2wUv7S0Cs09bTA1ZrfzSsffNCJZtJgIPVYmnSXK98JR0jkdxEegczZI1p80Pd0F0BaBMekWo cF36wtcirj2PLVvKRic3u71Dj4t6h5Lcexwm5hQ4fFaaF22OBx8DwTtPMg8iFDCkovTAaYqLDur +KY+YRDZ1pUqFKF5ApKEJswRbbUqPNMiyqXjDt8Kk X-Received: by 2002:a05:622a:1828:b0:51a:8c9b:649f with SMTP id d75a77b69052e-51cbf38ef7emr84447391cf.67.1783941308473; Mon, 13 Jul 2026 04:15:08 -0700 (PDT) X-Received: by 2002:a05:622a:1828:b0:51a:8c9b:649f with SMTP id d75a77b69052e-51cbf38ef7emr84446991cf.67.1783941308020; Mon, 13 Jul 2026 04:15:08 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:8881:83b8:89fa:1a2a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa0f214d2sm82323160f8f.33.2026.07.13.04.15.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2026 04:15:06 -0700 (PDT) From: Bartosz Golaszewski Date: Mon, 13 Jul 2026 13:14:45 +0200 Subject: [PATCH v4 2/5] software node: add fw_devlink support 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 Message-Id: <20260713-swnode-fw-devlink-v4-2-d4f2dee27ad9@oss.qualcomm.com> References: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> In-Reply-To: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> To: Brendan Higgins , David Gow , Rae Moar , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Bartosz Golaszewski , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Linus Walleij , Dmitry Torokhov Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-gpio@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5990; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=O9NkHL6JYILIp7mfm0RnOgr/0S6YPfzPn6jbv5EJbjU=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBqVMiv3n7DWmU3bTgDtMHhn+McKk6aAxv9PFD8+ L/kGkkHH4mJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCalTIrwAKCRAFnS7L/zaE w1WRD/0fycoaLESQF+jB+f8IxtpFfiLvdJ4cwDu4+Kgo2CXBydcgbhsuo1LEVLLC4eTXh4qJuSW vApZWytxW6u84Gd7RM2JZAhrrfFH7sgRGvgkn9jSRG/kwqWkq4QrSm16TPglgLGyavF2tcwV3JP fojBN2IHhuKKAjC4IVvuV/GuJvRgQHaObu9v0SJcNT8WNjUkQU5uC6Bs3p/shCnyZcuwg17Q1Lh fdi+CpEr5nFWo2/g7j50IVzqAzswifIj9kPn0pMTuU7oVo1zNjrw89jGpoYYMGYP6WoYvHzNZkE ylnU9iiVIo4cBd/8oRK9V8We2blZBWx8AhhLXGiicXDt+mbJxmxhkx9kk58vMSjXhejoqa+B/5r /bolt61WnOR0t5DQWGt1raUCyJoNV8Lg5/g1NjvAtjUqZVBetnpHwFYUV3lW2VQ7v1fF/uOMKJK 8uZU0ZqVUXOKd0gRaaz+e5j7QfOqwkXVjtnkxo59mY1TJmfGR+7udlroTFzyY8dL0sNw99k8a35 0J6Auidrd1W+GLC9m6PGDGorsJBQin0gFlKR5mK+hZujM1D8+biy4yUcaFNGDDbdnXrbF4Zo+JH CEYzBnKn00I9as4is4jyBwNZIQckRnXjKh46IIROikmeDpe1hiD6ae0LUp1if2DVhMB0BaUGKAW vyjg97iHRtLLOFA== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Authority-Analysis: v=2.4 cv=FMErAeos c=1 sm=1 tr=0 ts=6a54c8bd cx=c_pps a=WeENfcodrlLV9YRTxbY/uA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=QyXUC8HyAAAA:8 a=EUspDBNiAAAA:8 a=fLzRGSmVK1lo7flavS8A:9 a=QEXdDO2ut3YA:10 a=kacYvNCVWA4VmyqE58fU:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX7T7a9d9OL8nt V6mjuNlUy5GzC85AGwq8RUNuKZk7aq4Jn/h3HwxrF+r3NbGpmnBaeABDifOH2S+3syTLlNDCAzS afNtgwSMPJIJJw83bn8BLW52q7jxjx4= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX2N+dQAGnf5do gV07HYPZm/Aurr4+Yusp/oQK5KAX9Eq0kFEt/KYbBXkyyjjU8iQmopLp5jiOATOK5P13wqUy3Ah rItxcXPECoALAnPKL6NsdAJE7kb+l1+lSyTpnlUnKP4JQ5plMV90pG35lZiRmYONE/Gwkugfobq sqWnpzEOpXg5ptMd3EC0SCE5xYkbBv28Mt+hIv4PBZqP/ME/GOocuWc+OkR4n91rEpYOm7spw2Q yZtwMLq8JjEKjORhZbcr7La30n0O7pvvJ84t1NOOK+IShFfPJThaVrfvOFa/Tb92xmLxV/0lnOP 3xNwR7LqMIqTWoNpXLGtPi1EudSyG8faTuOUyG5ddmTlo8jK8xw/rnk6xZHjMfTXVfySrwpYFzE 065h/FrKwVCKe1i/18+Taoeb6NvJRhqwi4SoEPUB9BpgxCvq/2VPImDHd5AKi9HKpM5k6vA+RY0 q2JBabgv5FC5JCvpYfA== X-Proofpoint-ORIG-GUID: jww7wUDriQUU3kJOyru-n1aSMPZ8K6gt X-Proofpoint-GUID: jww7wUDriQUU3kJOyru-n1aSMPZ8K6gt X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-13_02,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 bulkscore=0 malwarescore=0 impostorscore=0 suspectscore=0 priorityscore=1501 phishscore=0 spamscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607130117 Software nodes can be used to describe supplier-consumer relationships between devices they represent using reference property entries. Unlike for OF-nodes, driver core cannot yet use these references to create a probe order that avoids needless probe deferrals on missing providers. Implement software_node_add_links() modelled on of_fwnode_add_links(). For every DEV_PROP_REF property we resolve each referenced supplier and create an fwnode link from the node to it. The driver core later promotes these to device links and defers the consumer until the suppliers are ready. There's no allowlist like the one DT needs - devicetree phandles appear in plenty of non-supplier contexts, but a software node only carries a reference property when its author explicitly points at another node, so we treat every reference as an intentional supplier dependency and link all of them. Graph "remote-endpoint" references are skipped for now: they go 2-ways between endpoint nodes and would create graph cycles without the port-parent lifting DT does via get_con_dev(). References to suppliers that aren't registered yet and self-references are ignored. fw_devlink resolves the supplier device through fwnode->dev but the core only records the owning device on the primary fwnode. When the software node is a device's secondary fwnode, mirror the device pointer onto it in software_node_notify() so the consumer can actually find the supplier instead of deferring forever. While at it: purge the fwnode links in software_node_release() now that software nodes can own them. Acked-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/base/swnode.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 79 insertions(+) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 869228a65cb365567ddac7db6ad7b8743e0dbca9..1f2315858cc3e04c7ff197324f1= 862c32a2ffa31 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -699,6 +699,62 @@ software_node_graph_parse_endpoint(const struct fwnode= _handle *fwnode, return 0; } =20 +static int software_node_add_links(struct fwnode_handle *fwnode) +{ + const struct software_node_ref_args *ref, *ref_array; + struct swnode *swnode =3D to_swnode(fwnode); + const struct property_entry *prop; + struct fwnode_handle *refnode; + unsigned int count; + + if (!swnode || !swnode->node->properties) + return 0; + + /* + * Unlike Device Tree, where phandles appear in many non-supplier + * contexts and a curated allowlist is required, a software node only + * carries a DEV_PROP_REF property when the author explicitly describes + * a reference to another node. Every such reference is therefore an + * intentional supplier dependency, so we create fwnode links for all + * of them. + */ + for (prop =3D swnode->node->properties; prop->name; prop++) { + if (prop->type !=3D DEV_PROP_REF || prop->is_inline) + continue; + + /* + * TODO: Graph "remote-endpoint" references go both ways + * between endpoint child nodes and would create endpoint + * cycles. Let's leave it out for now until we have potential + * users. + */ + if (!strcmp(prop->name, "remote-endpoint")) + continue; + + ref_array =3D prop->pointer; + count =3D prop->length / sizeof(*ref_array); + + for (unsigned int i =3D 0; i < count; i++) { + ref =3D &ref_array[i]; + + if (ref->swnode) + refnode =3D software_node_fwnode(ref->swnode); + else if (ref->fwnode) + refnode =3D ref->fwnode; + else + continue; + + /* Supplier not registered yet, or self-reference. */ + if (!refnode || refnode =3D=3D &swnode->fwnode) + continue; + + fwnode_link_add(&swnode->fwnode, refnode, 0); + } + } + + return 0; +} + static const struct fwnode_operations software_node_ops =3D { .get =3D software_node_get, .put =3D software_node_put, @@ -716,6 +772,7 @@ static const struct fwnode_operations software_node_ops= =3D { .graph_get_remote_endpoint =3D software_node_graph_get_remote_endpoint, .graph_get_port_parent =3D software_node_graph_get_port_parent, .graph_parse_endpoint =3D software_node_graph_parse_endpoint, + .add_links =3D software_node_add_links, }; =20 /* -----------------------------------------------------------------------= --- */ @@ -787,6 +844,8 @@ static void software_node_release(struct kobject *kobj) { struct swnode *swnode =3D kobj_to_swnode(kobj); =20 + fwnode_links_purge(&swnode->fwnode); + if (swnode->parent) { ida_free(&swnode->parent->child_ids, swnode->id); list_del(&swnode->entry); @@ -1105,6 +1164,17 @@ void software_node_notify(struct device *dev) if (!swnode) return; =20 + /* + * When the software node is the device's secondary firmware node, + * the core only records the owning device on the primary fwnode + * (see device_add()). fw_devlink resolves a supplier device through + * fwnode->dev, so without this a consumer referencing the software + * node could never find the supplier device and would defer forever. + * Make fwnode.dev point to its owner in that case. + */ + if (!device_match_fwnode(dev, &swnode->fwnode) && !swnode->fwnode.dev) + swnode->fwnode.dev =3D dev; + swnode_get(swnode); ret =3D sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node"); if (ret) @@ -1127,6 +1197,15 @@ void software_node_notify_remove(struct device *dev) =20 sysfs_remove_link(&swnode->kobj, dev_name(dev)); sysfs_remove_link(&dev->kobj, "software_node"); + + /* + * Drop the device pointer mirrored onto a secondary software node in + * software_node_notify(). For a primary software node the core owns + * fwnode->dev and clears it in device_del(). + */ + if (!device_match_fwnode(dev, &swnode->fwnode) && swnode->fwnode.dev =3D= =3D dev) + swnode->fwnode.dev =3D NULL; + swnode_put(swnode); =20 if (swnode->managed) { --=20 2.47.3 From nobody Sat Jul 25 21:20:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 015F63876DF for ; Mon, 13 Jul 2026 11:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941320; cv=none; b=rKpTa+e9i8iTKVxljxCSJF8AL97nKSKk+eGVIVVsdwjAEJaJ7SPjqUt620AdadPJxn/d7KBzo8Kgjy/O+c+LDVzp7ZA3rePRDupxXT8KpdVQmy3t80aVQeOG/iEZ64aUvMNSdPQRnv8TFxVgv2KP+8NVpHSv4wVFARgIHDhe4nM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941320; c=relaxed/simple; bh=VYz0TYRwzOI7K0hlO+3u24CfmURLK/h7puPMYIu7DoE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I4Tfic8omn7LKiN6Rp2vFzLixXTAay4qAeZDGhS3mWNTEPh74Xl9HEQMeXjHtWEztSx9A+1wh6XYb4Z7EPfeSVSFxWv3lzgGfkoCu9OOseP+8WI9FDNy6igd9+PNouDRendmzyijFa9C6n9nAAShwF58ufbM6zGKARjf9m3rPwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=jK5OFX8y; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=icAfG81f; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="jK5OFX8y"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="icAfG81f" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66DB7gZE507296 for ; Mon, 13 Jul 2026 11:15:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= G1ndrEIR7n7BpzBb/bC1xzKI/CnXvp4qobfU8FGyanY=; b=jK5OFX8yDhdtk95h qV90IMpyKSbjgVEUlCVkTMXZtgXsLjkDcCFIOihzkzl09kMXg5b90oDpSI6EAfY1 A8XEpZMjaOL9Fr2OO/Y4fBkIqJ0T5tbjrcraAsD+w0LA36mYz7oLEzyF9JB6GDlb EHIIUgZu6xhLW26JzwGch0vUSVkPAYgn75/gHdza0yKA84yiLrK5ZdokP9jl3r7C l7uj1/jL9ksIE8sN59WJiyrU23dwt50mlKK6YnND8mZBrU7rN0Teuy3eIEpwmWeM uRlO3uvTWT/fF0Go3Q35OrBAR024uwLNkTt+K8BuHJXlKho3L6+zTlnc+TThAJHz hFIk8A== Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fctc8h6tx-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 13 Jul 2026 11:15:15 +0000 (GMT) Received: by mail-qv1-f72.google.com with SMTP id 6a1803df08f44-8efe7db1c42so49334946d6.3 for ; Mon, 13 Jul 2026 04:15:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783941315; x=1784546115; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=G1ndrEIR7n7BpzBb/bC1xzKI/CnXvp4qobfU8FGyanY=; b=icAfG81fwvAlVgOSTW4kaznuUePa9fe1Ruz9i/Es1XFZFToDuPhO1ekO0W3oVYdP1h uCQ/TA37c/Ryc2izX0JsKuU/k8iFFQNwmpuO5mZclevLbomqsri71Hs72oWUT91plv9L Dfv74/StEt1vd/HdE+i0RSxggiijcdhHkr9KSa0J5qWgqIbrHvVJfgwk9I49rQa2Pp7K nl3O8dXU1ayuFbFdq6kqG4tR91BgrqZKglwPEDczwj34yAMzL1H7pV1MfRVRZJ+ivd2f SHAiB4EGyo8Bx3JATwTQZesxI+C27pwTzNlOcu9Yk5HauvSQ/DSH7G50z9mGT1hBPB78 NaGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783941315; x=1784546115; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=G1ndrEIR7n7BpzBb/bC1xzKI/CnXvp4qobfU8FGyanY=; b=Zrupeh9uzYuzPM+0qeGBpSINEQqeu5GkeEAL7O8Z48sEJ1cquAVlpndtvlYgY1B6v+ HsqgM8PQxgokH3BUTKP3ctQRsaLM5ePgiBHxiFJx//nHQG521SXyBUfD73EgiAdYG+8y KWg+/JWt9kvR+lVVRjujP25kS0ruTqEgh2GWQvCHxPFPjIbx5/BOsZn2UWfXJGe6/NvW ZamWJbLy0mo5qzb4BbTN+A7GzNaVrtH/54d3mG95QNhJ84GlgmHqyMuW5K51fykaclFo aserb51pLmlMzNuI4RpMpeewTv8AIRhWwDZPAeBbAysL8umJZqqlp+CzKWDP5ojjZqtt XE0A== X-Gm-Message-State: AOJu0YyNkbpY4L1k7v34nd1h8Sx4IiHOXK89NDok9DHyP1AQxsZZKPRA 71vNgLtFGFJkk46f6XqKr5EHnFxO0q2e6oKVFqQvXnGEWygaC0K8SllJRoxGyhv7TjPlQgjxQTP 6Q5Xm9/eqbIyVea3ra3CK6i6cdeBYDkuBVyIX6NOY2r8LFs+h5gFIi5teeQgKXORL8pBIID5sT3 E= X-Gm-Gg: AfdE7cloCQGzY9koYyLcPdRE+OD8NjXJYSBWUo7ikZDYDuOHfOlUsYfof8DcYISqCTd 6DSPDpThCtql9IsRHq3vNCxo/y6/R3BI4DaPP7zbSIkTmOpCwfGjHSMjzb7zx5pUXDUU4xfs7xt RyEUOvofs/EmD/3XyYFAW+qA+CAmaFVXoTQ9PUGlelEOYTRXw9LZbdWDLsugwvGMfQ9y/gpd2/f WkIeb5YYChuogmdkTU8YIadmrJp/ApiLuV9iWNzby3fsqqteXWbyM6rTjqg1oSdM864BVF4aagn 6yhvYzum9PLTwysbFhFuVDrim+r1VfxxcEqSRhVwC6K3ST+HYFzjxwS6TxgbFtWcEmNhoEwsSF6 DIXTr1yJZ1WAG85m1H6OwT6K0DI4c5sckUzsxJRyl X-Received: by 2002:a05:622a:1918:b0:51c:8fb:fa45 with SMTP id d75a77b69052e-51cbf2fab81mr88878561cf.58.1783941313273; Mon, 13 Jul 2026 04:15:13 -0700 (PDT) X-Received: by 2002:a05:622a:1918:b0:51c:8fb:fa45 with SMTP id d75a77b69052e-51cbf2fab81mr88877321cf.58.1783941312140; Mon, 13 Jul 2026 04:15:12 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:8881:83b8:89fa:1a2a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa0f214d2sm82323160f8f.33.2026.07.13.04.15.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2026 04:15:09 -0700 (PDT) From: Bartosz Golaszewski Date: Mon, 13 Jul 2026 13:14:46 +0200 Subject: [PATCH v4 3/5] software node: add kunit tests for fw_devlink support 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 Message-Id: <20260713-swnode-fw-devlink-v4-3-d4f2dee27ad9@oss.qualcomm.com> References: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> In-Reply-To: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> To: Brendan Higgins , David Gow , Rae Moar , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Bartosz Golaszewski , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Linus Walleij , Dmitry Torokhov Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-gpio@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=13715; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=VYz0TYRwzOI7K0hlO+3u24CfmURLK/h7puPMYIu7DoE=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBqVMiwKqOvnQ53efJ+Gdvxj32YrXGjDJCupbdAS hOlNL2qYGeJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCalTIsAAKCRAFnS7L/zaE w+WZD/wLXZP4GYrLA8mBNJtgA29WG2H+RCY4Za27dUOwLErpZ5h10IUhuObHX1hNl0gTIieh7d4 ckbBw6udTFyxfAdz5DmNYO7UxIqYI1sZcITsZYQe5Ux+1/MM2CckJesxyTXcDcojFpPfDxsA7wE guftCRAdYVUGALM8tchVFSVK2EFjcbGphenY/yGkzOf4ryBbQEgdkbGXzzNnk3D3WR7PJadoKZZ 1V659cFXZ9bG0xZUFPbuFWrtoQ9t2P1Wt9hYmWIFN1Zj0l7aM0e/RREEMjYdj7TAbWeUWSaI3rh K0x5BaV6HHHhTC9YC0z2K4JCEs92dpCAvuwb+ruJ4gdGCfljhIFUwhQTqHAPgo48apjJVnuPRp+ 0loYSMbGwkSuMfaZ8AbHXwYm2jqtzSuMy7EJo34SHgJdTLwJzLDjtKd19vrcwHOYQOi6mF6f6r/ /hbSICWu+JjTtAr/SU9s8a9kPSFCWUTsyNudU2DTPu04ILH9VN/F9oVVx3cEREBHebHuJB2QoO6 +/nvifSEMRR+cF+w70b0j/lLxYC7+dGN4cJbmYdFO48boD4RYbXRIM1ZSSqJ/HehIwVkRp08bhR wR0vBSS0i+H8LD7G47I6qoSWO8R+zEFExDhGnWJqF+4MTp1JBqKoWX1F2PVCUSL4SxH1Bam+T+z 0tu7cLHxVMWEFOw== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Proofpoint-GUID: zHNJGdb3hzi5WQje8Cxprre2f8r2pYkg X-Proofpoint-ORIG-GUID: zHNJGdb3hzi5WQje8Cxprre2f8r2pYkg X-Authority-Analysis: v=2.4 cv=UtRT8ewB c=1 sm=1 tr=0 ts=6a54c8c3 cx=c_pps a=7E5Bxpl4vBhpaufnMqZlrw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=QyXUC8HyAAAA:8 a=nzuXsxulAAAA:8 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=9zVEpjMGfH8rPmTIezIA:9 a=QEXdDO2ut3YA:10 a=pJ04lnu7RYOZP9TFuWaZ:22 a=Jn5cl5okm61iLnyvC_SE:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX7FS95t4kaIK9 NWYP0Aj2AckNVPUlXUYPAiU7X1V5eh6cZhe1eOiRQfQHNOZWVMvpc/U+2gBJSAjpk/GOM6UBWvk cc+rlT/8Xs2JfNsjaJG4+54+APAiEhE= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX+ynnTsm7/i4W 6CnUXni8o8/lAcbMXbCmpuY1qJ0obzsj4nczAznfgQZZ2U3eYFSqKE557KhaX1LicGrwcIbBag3 bTJgPgl3qjyZlLxM4SJmea9bLsrgW7eot6Vy8HG++gLAZrQeDD52jac2NVnADZDIv4NWZSQYFJE ikpYVeN5LcEQE3GzpcbritlI4ImHy3SSlDxtQTRlJyUhNsGohrNjPALdEYU0b83R+zrUBZ6Li9R OKJMW2hoaBuQb3rkf2c37wkxOkTmOawsZExP5lJ6KBzQz1J5Ei8R4v7zQVUJtSFu9XIccRwIaWu 9if61gE7fUNJ2ZnQKBiNy1+RGOnx4MTUTIMlc72zw/Fmy6scdRmZrw4V8lZJh6Sy7VPjtxsJx2n ueszv/3uZc94nIaV9fuGENJ+ejhd1/dGJg+9BLTPz7cVLLSOsRf7sSt3YuDt23dGxw1HDZzOEB6 NQhcRHpQti7c9er2ZZw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-13_02,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 suspectscore=0 bulkscore=0 clxscore=1015 impostorscore=0 lowpriorityscore=0 adultscore=0 malwarescore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607130117 Add a kunit test suite for fw_devlink support for software nodes. Most cases call add_links() directly and inspect the resulting fwnode supplier/consumer lists: a single reference, multiple references, a reference to an unregistered node, a "remote-endpoint" reference and a reference array. The last case is end-to-end - it registers real consumer and supplier platform devices together with their drivers, adds the consumer first and checks that fw_devlink defers its probe until the supplier has been bound. Acked-by: Andy Shevchenko Tested-by: David Gow Signed-off-by: Bartosz Golaszewski --- MAINTAINERS | 1 + drivers/base/test/Kconfig | 5 + drivers/base/test/Makefile | 2 + drivers/base/test/swnode-devlink-test.c | 337 ++++++++++++++++++++++++++++= ++++ 4 files changed, 345 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 806bd2d80d153537393761df322165f683954d50..f9dfb14b9d477fc0331441f96c1= 58b0474f63026 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25106,6 +25106,7 @@ L: linux-acpi@vger.kernel.org S: Maintained F: drivers/base/property.c F: drivers/base/swnode.c +F: drivers/base/test/swnode-devlink-test.c F: include/linux/fwnode.h F: include/linux/property.h =20 diff --git a/drivers/base/test/Kconfig b/drivers/base/test/Kconfig index 2756870615ccab67ec26d8671c1e4dba69342134..1ecf0791241a1b2eee7e1e78777= 2217724abacb9 100644 --- a/drivers/base/test/Kconfig +++ b/drivers/base/test/Kconfig @@ -18,3 +18,8 @@ config DRIVER_PE_KUNIT_TEST tristate "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS depends on KUNIT default KUNIT_ALL_TESTS + +config DRIVER_SWNODE_KUNIT_TEST + tristate "KUnit Tests for software node fw_devlink links" if !KUNIT_ALL_T= ESTS + depends on KUNIT + default KUNIT_ALL_TESTS diff --git a/drivers/base/test/Makefile b/drivers/base/test/Makefile index e321dfc7e92266d2073d442f652cadb6e911dba5..9ced7bbd569fc49ba2719aa0cab= 57c7d8245dde1 100644 --- a/drivers/base/test/Makefile +++ b/drivers/base/test/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_DM_KUNIT_TEST) +=3D platform-device-test.o =20 obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) +=3D property-entry-test.o CFLAGS_property-entry-test.o +=3D $(DISABLE_STRUCTLEAK_PLUGIN) + +obj-$(CONFIG_DRIVER_SWNODE_KUNIT_TEST) +=3D swnode-devlink-test.o diff --git a/drivers/base/test/swnode-devlink-test.c b/drivers/base/test/sw= node-devlink-test.c new file mode 100644 index 0000000000000000000000000000000000000000..f53549e926118fd4a1e109ece67= d58d45d52193d --- /dev/null +++ b/drivers/base/test/swnode-devlink-test.c @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int swnode_count_suppliers(struct fwnode_handle *fwnode) +{ + struct fwnode_link *link; + unsigned int count =3D 0; + + /* + * The suppliers and consumers lists should typically only be accessed + * with the fwnode_link_lock taken but it's private to the driver core. + * + * These are tests and at this point nobody should be modifying them so + * let's just access the list. + */ + list_for_each_entry(link, &fwnode->suppliers, c_hook) + count++; + + return count; +} + +/* True if a supplier link con->sup exists, checked from both list ends. */ +static bool swnode_has_link(struct fwnode_handle *consumer, + struct fwnode_handle *supplier) +{ + bool from_con =3D false, from_sup =3D false; + struct fwnode_link *link; + + list_for_each_entry(link, &consumer->suppliers, c_hook) { + if (link->supplier =3D=3D supplier && link->consumer =3D=3D consumer) + from_con =3D true; + } + + list_for_each_entry(link, &supplier->consumers, s_hook) { + if (link->supplier =3D=3D supplier && link->consumer =3D=3D consumer) + from_sup =3D true; + } + + return from_con && from_sup; +} + +/* A single reference creates exactly one supplier link, on both list ends= . */ +static void swnode_devlink_test_single_ref(struct kunit *test) +{ + static const struct software_node supp_swnode =3D { + .name =3D "swnode-devlink-test-supplier", + }; + + struct fwnode_handle *cons_fwnode, *supp_fwnode; + int ret; + + const struct property_entry props[] =3D { + PROPERTY_ENTRY_REF("supplier", &supp_swnode), + { } + }; + + supp_fwnode =3D kunit_software_node_register(test, &supp_swnode); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supp_fwnode); + + cons_fwnode =3D kunit_fwnode_create_software_node(test, props, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons_fwnode); + + ret =3D fwnode_call_int_op(cons_fwnode, add_links); + KUNIT_EXPECT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, swnode_count_suppliers(cons_fwnode), 1); + KUNIT_EXPECT_TRUE(test, swnode_has_link(cons_fwnode, supp_fwnode)); +} + +/* Multiple distinct references create multiple supplier links. */ +static void swnode_devlink_test_multiple_refs(struct kunit *test) +{ + static const struct software_node supp1_swnode =3D { + .name =3D "swnode-devlink-test-supplier-1", + }; + static const struct software_node supp2_swnode =3D { + .name =3D "swnode-devlink-test-supplier-2", + }; + static const struct software_node *supp_nodes[] =3D { + &supp1_swnode, &supp2_swnode, NULL + }; + + const struct property_entry props[] =3D { + PROPERTY_ENTRY_REF("foo", &supp1_swnode), + PROPERTY_ENTRY_REF("bar", &supp2_swnode), + { } + }; + + struct fwnode_handle *fwnode; + int ret; + + ret =3D kunit_software_node_register_node_group(test, supp_nodes); + KUNIT_ASSERT_EQ(test, ret, 0); + + fwnode =3D kunit_fwnode_create_software_node(test, props, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); + + ret =3D fwnode_call_int_op(fwnode, add_links); + KUNIT_EXPECT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, swnode_count_suppliers(fwnode), 2); + KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&sup= p1_swnode))); + KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&sup= p2_swnode))); +} + +/* A reference to an unregistered node creates no link (graceful skip). */ +static void swnode_devlink_test_unregistered_ref(struct kunit *test) +{ + static const struct software_node supp_swnode =3D { + .name =3D "swnode-devlink-test-supplier", + }; + + const struct property_entry props[] =3D { + PROPERTY_ENTRY_REF("supplier", &supp_swnode), + { } + }; + + struct fwnode_handle *fwnode; + int ret; + + fwnode =3D kunit_fwnode_create_software_node(test, props, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); + + ret =3D fwnode_call_int_op(fwnode, add_links); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, swnode_count_suppliers(fwnode), 0); +} + +/* Graph "remote-endpoint" references are excluded. */ +static void swnode_devlink_test_remote_endpoint_excluded(struct kunit *tes= t) +{ + static const struct software_node ep_swnode =3D { + .name =3D "swnode-devlink-test-end-point" + }; + + const struct property_entry props[] =3D { + PROPERTY_ENTRY_REF("remote-endpoint", &ep_swnode), + { } + }; + + struct fwnode_handle *cons_fwnode, *supp_fwnode; + int ret; + + supp_fwnode =3D kunit_software_node_register(test, &ep_swnode); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supp_fwnode); + + cons_fwnode =3D kunit_fwnode_create_software_node(test, props, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons_fwnode); + + ret =3D fwnode_call_int_op(cons_fwnode, add_links); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, swnode_count_suppliers(cons_fwnode), 0); +} + +/* A reference array creates one link per registered element. */ +static void swnode_devlink_test_ref_array(struct kunit *test) +{ + static const struct software_node supp1_swnode =3D { + .name =3D "swnode-devlink-test-supplier-1", + }; + static const struct software_node supp2_swnode =3D { + .name =3D "swnode-devlink-test-supplier-2", + }; + static const struct software_node *supp_nodes[] =3D { + &supp1_swnode, &supp2_swnode, NULL + }; + static const struct software_node_ref_args refs[] =3D { + SOFTWARE_NODE_REFERENCE(&supp1_swnode), + SOFTWARE_NODE_REFERENCE(&supp2_swnode, 4, 2), + }; + + const struct property_entry props[] =3D { + PROPERTY_ENTRY_REF_ARRAY("suppliers", refs), + { } + }; + + struct fwnode_handle *fwnode; + int ret; + + ret =3D kunit_software_node_register_node_group(test, supp_nodes); + KUNIT_ASSERT_EQ(test, ret, 0); + + fwnode =3D kunit_fwnode_create_software_node(test, props, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); + + ret =3D fwnode_call_int_op(fwnode, add_links); + KUNIT_EXPECT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, swnode_count_suppliers(fwnode), 2); + KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&sup= p1_swnode))); + KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, software_node_fwnode(&sup= p2_swnode))); +} + +/* + * End-to-end test: fw_devlink must defer a consumer's probe until its + * supplier has probed. + * + * The reference created by software_node_add_links() is only useful if the + * driver core promotes it to a real device_link and uses it to order prob= ing. + * This test drives actual probing through the platform bus and asserts the + * supplier binds before the consumer. + */ + +#define SWNODE_DEVLINK_TEST_SUPPLIER "swnode-link-supplier" +#define SWNODE_DEVLINK_TEST_CONSUMER "swnode-link-consumer" +#define SWNODE_DEVLINK_TEST_TIMEOUT_MS (2 * MSEC_PER_SEC) + +struct swnode_test_probe_order { + /* Names in the order their drivers' .probe ran. */ + const char *probed[2]; + unsigned int count; + wait_queue_head_t wq; +}; + +static int swnode_test_record_probe(struct platform_device *pdev) +{ + struct swnode_test_probe_order *order =3D platform_get_drvdata(pdev); + + if (order && order->count < ARRAY_SIZE(order->probed)) { + order->probed[order->count++] =3D dev_name(&pdev->dev); + wake_up_interruptible(&order->wq); + } + + return 0; +} + +static struct platform_driver swnode_test_supplier_driver =3D { + .probe =3D swnode_test_record_probe, + .driver =3D { + .name =3D SWNODE_DEVLINK_TEST_SUPPLIER, + }, +}; + +static struct platform_driver swnode_test_consumer_driver =3D { + .probe =3D swnode_test_record_probe, + .driver =3D { + .name =3D SWNODE_DEVLINK_TEST_CONSUMER, + }, +}; + +static void swnode_devlink_test_probe_order(struct kunit *test) +{ + static const struct software_node supplier_swnode =3D { + .name =3D "swnode-devlink-test-supplier", + }; + + const struct property_entry consumer_props[] =3D { + PROPERTY_ENTRY_REF("supplier-ref", &supplier_swnode), + { } + }; + + struct platform_device *supplier, *consumer; + struct swnode_test_probe_order *order; + struct fwnode_handle *fwnode; + int ret; + + order =3D kunit_kzalloc(test, sizeof(*order), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, order); + init_waitqueue_head(&order->wq); + + fwnode =3D kunit_software_node_register(test, &supplier_swnode); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); + + ret =3D kunit_platform_driver_register(test, &swnode_test_supplier_driver= ); + KUNIT_ASSERT_EQ(test, ret, 0); + ret =3D kunit_platform_driver_register(test, &swnode_test_consumer_driver= ); + KUNIT_ASSERT_EQ(test, ret, 0); + + supplier =3D kunit_platform_device_alloc(test, SWNODE_DEVLINK_TEST_SUPPLI= ER, + PLATFORM_DEVID_NONE); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supplier); + consumer =3D kunit_platform_device_alloc(test, SWNODE_DEVLINK_TEST_CONSUM= ER, + PLATFORM_DEVID_NONE); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, consumer); + + platform_set_drvdata(supplier, order); + platform_set_drvdata(consumer, order); + + ret =3D kunit_device_add_software_node(test, &supplier->dev, &supplier_sw= node); + KUNIT_ASSERT_EQ(test, ret, 0); + ret =3D device_create_managed_software_node(&consumer->dev, + consumer_props, NULL); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret =3D kunit_platform_device_add(test, consumer); + KUNIT_ASSERT_EQ(test, ret, 0); + ret =3D kunit_platform_device_add(test, supplier); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret =3D wait_event_interruptible_timeout(order->wq, + order->count =3D=3D 2, + msecs_to_jiffies(SWNODE_DEVLINK_TEST_TIMEOUT_MS)); + KUNIT_ASSERT_GT(test, ret, 0); + + KUNIT_EXPECT_STREQ(test, order->probed[0], SWNODE_DEVLINK_TEST_SUPPLIER); + KUNIT_EXPECT_STREQ(test, order->probed[1], SWNODE_DEVLINK_TEST_CONSUMER); + + /* Tear down the consumer (and its device link) before the supplier. */ + kunit_platform_device_unregister(test, consumer); +} + +static struct kunit_case swnode_test_cases[] =3D { + KUNIT_CASE(swnode_devlink_test_single_ref), + KUNIT_CASE(swnode_devlink_test_multiple_refs), + KUNIT_CASE(swnode_devlink_test_unregistered_ref), + KUNIT_CASE(swnode_devlink_test_remote_endpoint_excluded), + KUNIT_CASE(swnode_devlink_test_ref_array), + KUNIT_CASE(swnode_devlink_test_probe_order), + { } +}; + +static struct kunit_suite swnode_test_suite =3D { + .name =3D "software-node-links", + .test_cases =3D swnode_test_cases, +}; + +kunit_test_suite(swnode_test_suite); + +MODULE_DESCRIPTION("Test module for software node fw_devlink support"); +MODULE_AUTHOR("Bartosz Golaszewski "= ); +MODULE_LICENSE("GPL"); --=20 2.47.3 From nobody Sat Jul 25 21:20:42 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 ACA33389107 for ; Mon, 13 Jul 2026 11:15:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941320; cv=none; b=uzGoOYOEBKiIkbwUWJGoNSeg42oNJXq1LzNK3wsiS71miSGxxGvNzHV0j3KA9Nbl05X1nv1IwfKsh0qSoDWM7Qncrx8obdEuCZzhuaQvfwkTdQCi2J2w1csFmsAGwtyf3/nNNYw443DLxv4lbyVurP3hlmRSTVEtS3mKaqYUOrQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941320; c=relaxed/simple; bh=W+4x54SXHSvmG8iNR7zCrefhHtiBz/ghaUo8GDg9VJY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n7bjMFKUPw3pG3RIjNHDHBpcG7xNCBRe3AGxqw+t6aRcT7ltiiPuAJhpMHc6Tug3aS3DMiAgHYOPTza/8M/xFYHQX6MscGJmQFE+OYpV8glhCKEbXrFdWGZDPX+l1209ceEscKJprSVFw9+q7dq1+ZSBE4ECLsZaV5mYS24mHD8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=JD/KNSWn; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=MOtgQPRn; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="JD/KNSWn"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="MOtgQPRn" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66D7Kupu775882 for ; Mon, 13 Jul 2026 11:15:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= gZpBMxILdTui1a4fiArtZqZbQ/ndjLRgPSPN0AMlFLU=; b=JD/KNSWnQspOuGRL zJfe73pU7DMXV8BzPKic7F7jAwWshVjoFiwKxOnShbid/YqaUDQV8owzwHr5Dj/2 i096Ql2A4atVxGvut3zn/Y099c/DIogel07lgYwRFbKhhPFls4R7STFF/hwiROeS a4XVHMLPjqdHuzRwSLLrZMT7LkJm+aj8v/P6xSnaV8KJA4wOjww2aGXqCYIVvb2z Rgfls693TApsqMuQ0vgZWYpYyfKuimfKLdYP8XNkJ43ssyH8lMpcv8t7rm/ZpECS MKcYAhFjrRXPuMOr+DyUQpVINzWbRdFf278OD8P/dQCxBkc6rVqYDTe7IoWtO7hA SDKl3w== Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fcuj00vce-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 13 Jul 2026 11:15:16 +0000 (GMT) Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-51c0408254aso49686241cf.0 for ; Mon, 13 Jul 2026 04:15:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783941316; x=1784546116; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=gZpBMxILdTui1a4fiArtZqZbQ/ndjLRgPSPN0AMlFLU=; b=MOtgQPRnWr6E8rQBxlQ67Jy14xiPpZhmRN94ZT7zR2UeFrfOTxBrjNKhedWPYAsE2i wGC+mCGOqB3zCWMH4ov2pRam2wVUD2zRtLzylXptRZGMMg50DpRsRXsXSPErEKiE40AA HUhDIQj1V/OUSUAm15y0mDeau0D+MRi8s4ZxLRcoySC+Wir4kg6bI3UETN17qGDm1mxG oijADkpe1biXSOI3LO4DgWoc5BCzB42BRWV/drmnUeET/3jyd/E/dgil6kWrWJGowIUv gqAI6mEco5AdFBIS04e7XYidhpffAERMr43e6t+spz37cLbKfbTWao+jnj2GEH89ur8+ Z3pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783941316; x=1784546116; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=gZpBMxILdTui1a4fiArtZqZbQ/ndjLRgPSPN0AMlFLU=; b=Sbn7ACEsxmbqMWmu8SMEh2opZDPuirBb9WoyObJy0FtdpguHaYjMSk/XeWun7b6WSo 9+qpv6UYz/WHMz+rmd1NqkB57+GG2iA1Es1vVsEU/fNrk/Bx77Wy0TvajoFDjsx+Z3vZ nIVw0/NJ0SBbOuDAnoXiMEDvjQBAmEdilU81EnbfbfMZ7ur58RHooRfkfj+cPMjzTFhb 9pxZqO8FIXfYX9nWyhhIr7g2/ahG7yNP+7L5ux6iqU1mKUjHut+a8Cl9W2BGcAXgOXtN JienBGVOseTp6MsT0X2MkWDvbf8NPtErskmNNyfmjyorepH1dxGvYfBhWsVd/4qP7puO 9jjA== X-Gm-Message-State: AOJu0YwltIsDxVgEputM3yrqlou8KLopcDYcWPQwoPFjMKkeoWm3q7lv 5rPg+9SIoyofuP+fGUs9I8kofQ7hyhXslJU+6ZLh1DXGG7aJ/imZXkRZ5fF2f0xhBsEPVhCa48d G4zsBnu/XG9/wK1kAmzIlQ/rwEOSdqxjePMA77DurpucCZEux8QLwcwNdEMm/5P3zA3Yx7cqW1h I= X-Gm-Gg: AfdE7clRNE7ASx/4WpIa7oMfO0DBq4xItXOUWjTTlFLXReaONLbM6+NyEkgva89GLkj dB7qX9bJBtMltBgxcHz98BkP7VpNMbhegRjPToKUBRPiERpCPDsZyKWd8KX07pRcM/E9CVZ+deo zucJA+ktEDPykcax++cZZt2JkvDi8jDt3P+tPsVs+iRGogOC1T1b5FzSoHjUzsP/xufsSiXu8Bb X9DL3hRT/Jo4+m5qrQpMuR7+x9191wLK9mc97wm5O180nfROzFv4ncz9QiRp/r2jS+FuSeMaHEt 2W7z92tHf9N+AQUqPkV0O2zba5LRMXvK90kooFvmUnFxQgQDHGB1xywtB9fa1tS2kTUZxV5ZZ/k BDxc1vV7Mqu/n5hzJdORPsW6fnpuy3ygU74ycfU4L X-Received: by 2002:a05:622a:5513:b0:516:ca56:a44d with SMTP id d75a77b69052e-51caa02e1c2mr128572191cf.6.1783941315937; Mon, 13 Jul 2026 04:15:15 -0700 (PDT) X-Received: by 2002:a05:622a:5513:b0:516:ca56:a44d with SMTP id d75a77b69052e-51caa02e1c2mr128571201cf.6.1783941314689; Mon, 13 Jul 2026 04:15:14 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:8881:83b8:89fa:1a2a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa0f214d2sm82323160f8f.33.2026.07.13.04.15.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2026 04:15:13 -0700 (PDT) From: Bartosz Golaszewski Date: Mon, 13 Jul 2026 13:14:47 +0200 Subject: [PATCH v4 4/5] MAINTAINERS: add myself as reviewer of software node support 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 Message-Id: <20260713-swnode-fw-devlink-v4-4-d4f2dee27ad9@oss.qualcomm.com> References: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> In-Reply-To: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> To: Brendan Higgins , David Gow , Rae Moar , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Bartosz Golaszewski , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Linus Walleij , Dmitry Torokhov Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-gpio@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=897; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=W+4x54SXHSvmG8iNR7zCrefhHtiBz/ghaUo8GDg9VJY=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBqVMiy441BqBZXkzBL7+gB9+mfFhdM4Y+nxwH32 viBbBXLEfyJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCalTIsgAKCRAFnS7L/zaE wxGbD/0XjM5SUCmLLr0/CpZ2O4eglSDLMnTe+PCk4WFrytuv0nkkklMcmuO/rXJ73ryMSYNRsOz gw6KArw5En7YnHt/oTL52z7uiyj4Crm7aN1M78N78Dw3ltpUv5keC5V/vexaXO0+YAZnqqr/B/K IDoZVdqTtG9O55r2/ChQmU63N6TsDL6nsC225TJgpjHwJ95QOONzET5WM8Io+t5JQREjriZOyUl HJ8Sd6x9jliHz6ohBhFOtQrmjvgpMYRJL/8RVK/zqd4tRS3NStZ/FzM6+bV/RgcYodKnt/Zvhtj 6qwc8OE5RxpkWiB1RqTwS5p/aeH1Q3ys70ZO1xKT9Omny7wncY9zqr0//PV1YhhSRw5FZRSt6mi d5mQx1dmFMvgiZJtpINX8a87qPQeulvgfNoX6RMwyA1WeZ4TvSU+fcSYzJRSsFgpKGg9r4nDKSG 40k9iaOplZDo3y2kL4xIH1zMUfkNNAekxbIbsgPm5G4jeQa1RZjHoE7pm69aEiH1w+CwlJqEftC GLybrwHegXBXYQmIRMmlLFF/xH3rEYB4W76O2HK/S3V+nhowH12umt6gqY+vqwCvE9LA14DWPt5 GDGcYc5rzIx1N/nDxqwrRO5UqH0mOgIqo6yVh9FLjFhnqKE52Gqd/4DlkO8KVfoXnfNP3z8o85P iAOUf/P3EMQZU9g== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX096fr1TBhqNw 5jdKQ67Ysjiy3WZckNSSdQI2M9m6smza0rCiUB98Qf1PZ6l7YnAVNZz/Pus9xGLAe9dtgfsYuHY 5krJG+wETEnRp51rs3RzKFI0O9IT1xc= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX6hsyT/C7yHcM apx6ZH9Z7/W2WCuQIHbMjZUJ4wxXJv+Qpee4Qcitvx1fCoLCCyoEwH7WtrSEUscoLPcB/i5Vb3C vm1lIa1sBXj/+vFceqHQk1WdIx/gjJM6UWZMvbC6JJvd5YDp0axGJp08lblyuUfc3ZIFZdXXwfJ OTUayhoIQs0BLHKmuxenMWlvj44D+JWaZCzh7f8Ue9pCZHKEW2tzWdimts2VrbDmY0bHvprIwGF uujr0sN5L/CnGcfTwLTGcEhBbuHWzbJUBcbEwIqeTmIKBhAWfkbcPr7gykUt4LjZIZP79kWnpyz z/OJRjt55jYGHQF7+U/R7TBLQhikqKomXo2GINJoWouawJGVn0mk9mEKL4zOcPxIhkrcvLGEvl6 G/kN/yWR50uYTq4RqRyboEpoZTHlqF5xMuRXNPO9MZgT99CIaYFLWct2LyB15KTdnvG0z0kTBRv lHQc41g+7/TNUg6BQdQ== X-Proofpoint-ORIG-GUID: Tw2Rku8FKQ5Iyc4r5TRMlXspDtdhvYs7 X-Authority-Analysis: v=2.4 cv=DbcnbPtW c=1 sm=1 tr=0 ts=6a54c8c4 cx=c_pps a=EVbN6Ke/fEF3bsl7X48z0g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=QyXUC8HyAAAA:8 a=EUspDBNiAAAA:8 a=pGLkceISAAAA:8 a=VwQbUJbxAAAA:8 a=0-iA9D7a5yEsystHw7UA:9 a=QEXdDO2ut3YA:10 a=a_PwQJl-kcHnX1M80qC6:22 X-Proofpoint-GUID: Tw2Rku8FKQ5Iyc4r5TRMlXspDtdhvYs7 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-13_02,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 impostorscore=0 malwarescore=0 priorityscore=1501 phishscore=0 suspectscore=0 bulkscore=0 adultscore=0 spamscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607130117 I've been working extensively on software nodes lately and introduced some changes. Add myself as reviewer so that I can help review any new proposed changes. Acked-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index f9dfb14b9d477fc0331441f96c158b0474f63026..a7a5d81d30658700b3744e0b299= 4211d75074883 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25102,6 +25102,7 @@ R: Andy Shevchenko R: Daniel Scally R: Heikki Krogerus R: Sakari Ailus +R: Bartosz Golaszewski L: linux-acpi@vger.kernel.org S: Maintained F: drivers/base/property.c --=20 2.47.3 From nobody Sat Jul 25 21:20:42 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 F3B9338B7C3 for ; Mon, 13 Jul 2026 11:15:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941322; cv=none; b=iGUvfncP5O8UOBY0D/Vixm/RfZrjDBu+pjNDuD/nB+XY94ldAhBB8EV2ekUYDZUobyYwobQKSft/oGQMOvw2yaWWFgeMToVqiV4FJg/yfj9kJkaA4JBSSvYLP4xjJBlywVJQtXFxzUhxApKz11Z7K3oR2qyFxRMeEnaGcFPGHRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783941322; c=relaxed/simple; bh=M4tIaAN+u/4O+r4/eLYo0ugmmbDRHjP7x2qa8S0+pY0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hn/vzWUUIIVDFsmZ2q+oAZYKqQUoo1i5qsigV0JiFMRjA+PFzWo28RcQK4+t4nAAFUd8cniGpz4Irf/IvvH5iQz/B0wjS9McuheUM+6D0/2lkrANFmdPl5FIK/qqQ93qJK/hu1Lss/jzkWcMpIMB6WY/OG1o9UJm8GP+SWeqG9M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=XS8hoZ2l; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=WaRkp5i9; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="XS8hoZ2l"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="WaRkp5i9" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66D77QE2810532 for ; Mon, 13 Jul 2026 11:15:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= BoEIQgMiFtY635hJNKnlXqv5v2AUYjs+FHaGmN/hMqg=; b=XS8hoZ2lJU8A5xrs uHB5QvMlp9ZMRBYX58NLkcJnco73oOaxKQTXKhAuuLWuAMkbcvzBbqAQ/409AhNz cc8DZJHlM+HGMAUGjikGUTkFKHBGPvXcVmeKeG4bIz2Ytuq4VReTsL0sYEPAA3c4 rEwU5VYxFGv05xJ8LhTEmBwiqrnJoGclfFDtpept7SEXiBXwaoJ6FMWaLsKMBdon 1FgolsYCmNh0gd0s/1drCGbJWLWN7Ek7lMFCurJbQvsb3zGDC1U+wB1krMJbszeR g+YZ/vyLZatA5wQAWWpNjQz+VVNT6zlts90raMc+ZbfktY7F2ULEfBnQkDKnWIMc 3dp2CA== Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fcubsrvyr-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 13 Jul 2026 11:15:18 +0000 (GMT) Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-51c0d6a2f4cso42209191cf.3 for ; Mon, 13 Jul 2026 04:15:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783941318; x=1784546118; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=BoEIQgMiFtY635hJNKnlXqv5v2AUYjs+FHaGmN/hMqg=; b=WaRkp5i9BvtLbUKIioQ85tMbPdU8lg7jWLQJorfexve3wbxJg/HJXKq11LXfAJ1zRK bOidOEoB6VKJJqnLKmMpeoWQxd/2+8o94ZWZNyhJfsXeyW25PZsB0wAL5dKIMWDbcO/Q 7N2XWSEqFlLz1myG9VpIrXGh0jsHPEDwA/aP7nTtZvuncQrwekcNxWTjt1EETTdtirk2 d5zChOfNW3qXSquErHquIfRYKiIxj2uPnS2SEvuFYv11ToSRt8KmqKMUeviDgn9unRwN cl6FfHdoAtC0fNOvJLzD5IUE5EUekv0PEaMS52WAvFNGMgiR4ACiTCkpRBHRmy4dLIf3 DGBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783941318; x=1784546118; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=BoEIQgMiFtY635hJNKnlXqv5v2AUYjs+FHaGmN/hMqg=; b=SKCN78wd0hn4FLA9Khn8HsPcP0Vj3+qpWJhc0y2M0jUoB2n7EINf+cAT8N/JFHoRjX v1VXmDTXO1kyT+u3xSNOmOQxbkr1iS2Z/O7Uc1wndA7uLKse53UrtaYI6WIkvey6k2O5 INAWRaPnnXBcB82Qcik9F/TD7YKLEqikcCQB0+4um7BIQxTTpWlKidWVkWPyy5xMW3w2 nI4m1FVHnyQcxogzhLQSIchpknvJwh0+fNIQQYRL6tiDPWJEKDNLUDP/j2xjAZA91CIv lImGynkj/0Igs44d2anliun8/yMql306BAh6DymT3rD/ZhTV8qGAKGI6MGbrRMltgExx caaA== X-Gm-Message-State: AOJu0Yy/z9dcJbSEajHgBoTWNffrx067tmuts1xT871A10KvyKlv8G4n gcrJTyqijewX5eKe/Oz3NCOgXcpOV4YSeHN/m2tWjRR9uQ31lhholDp5HFAHGgoJZux/990n7cA zOirWHpyCQt9bRwYWT+YoaIeRBaNeKdz+WNSBeXR3mkKlWzb5uLIbytVXkHZJR477ZGlqDQHovm I= X-Gm-Gg: AfdE7ckdyTh0FUxHZCY/6HrVPs+Na2oO+YCQ3H3/vraOwUxmtbjgaVH3hyWY1MIakD0 x38e5FTFXAak/+SgiQ53fOKZ5BXHZ4+pKwteu/BvL8NwGvIl2l4mVwmtBXnliM8qgasBMr1JNJ7 Y60FVcSi4QPO5rlxTYGlCisx1jqIBMHpVsRUCV77d3B7TYjS8UVQO/4dSnpzq2Vl8+kR3uBb98Q PrWyXIqs3FXL7qF7O1R5A0SFAZ1ZNtwUgrU6E6g9nV7e1Vk/1aVJfj/ZK9zxjXCYTZgQLICy7fQ ehY+ZOt0fkxcv8aeUtuTg2E0OpW2JDLNhvAsBV8ezAhf00M8loVesOgB4jn3w3LI6IisDSfQk4S b19bAs+6mU5VPB6anWaom/aCE+Twj5Ld53EZI9MIT X-Received: by 2002:a05:622a:11d1:b0:517:8f98:aaff with SMTP id d75a77b69052e-51cbf21391bmr76953451cf.49.1783941317581; Mon, 13 Jul 2026 04:15:17 -0700 (PDT) X-Received: by 2002:a05:622a:11d1:b0:517:8f98:aaff with SMTP id d75a77b69052e-51cbf21391bmr76952731cf.49.1783941316924; Mon, 13 Jul 2026 04:15:16 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:8881:83b8:89fa:1a2a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa0f214d2sm82323160f8f.33.2026.07.13.04.15.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2026 04:15:15 -0700 (PDT) From: Bartosz Golaszewski Date: Mon, 13 Jul 2026 13:14:48 +0200 Subject: [PATCH v4 5/5] gpio: kunit: add test cases verifying swnode devlink support 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 Message-Id: <20260713-swnode-fw-devlink-v4-5-d4f2dee27ad9@oss.qualcomm.com> References: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> In-Reply-To: <20260713-swnode-fw-devlink-v4-0-d4f2dee27ad9@oss.qualcomm.com> To: Brendan Higgins , David Gow , Rae Moar , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Bartosz Golaszewski , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Linus Walleij , Dmitry Torokhov Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-acpi@vger.kernel.org, driver-core@lists.linux.dev, linux-gpio@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=12330; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=M4tIaAN+u/4O+r4/eLYo0ugmmbDRHjP7x2qa8S0+pY0=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBqVMizwoYQj1TLjHYs9DxF1o2IwFlNrdpA+wnsc /Le20hbtriJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCalTIswAKCRAFnS7L/zaE wwpYEACL+whKRyMrZNhi5YI0oLa64iEUkutzrCBFiUU6tQlS9CiXlIBmtBzNxTrtl6/rAUJz/aj EdvJk28jw4pztb04rIfwyfY1e35thyVnsYAD64eOTtqHrnBsYm7nQD399bRTYnQbp8tzG56MeRw PfdBUf9nq3ULJcPJLUEu8MU+p50vhxhgDC94Pf3YrMwyJimOYAqbO7qXBSzcllz1H3ZIJ/l1cxN yEpnmLlzuJzly8ZkBSiPfHmCao9xlGHm2AM8eCyx8mSsB6+F0D+xoCqdpTgaW4unxw1rZW6yzg1 /BKxlnpgFQnyeguBRfvhByBq9Kb1Y9+FGwsnaTIcR+i3ZaZaQNwBsf3Xu7tT2ysWb74jBx8/9ZD tM5Yxq/SFh3+cnEKd+tsX2eDWQhYk7AXgM4FUHPcd/gZ+cOiWVLWGVBMlnXqniuRjVu2/7CQpbr IMarKeVoJA1vxZvIw0PjDcf1NtB/OpzZnMJSSLBrOSdS3Hkx/Surwd5TpQPotpzxe+/HN76jlir jkOLKNQZXxtBJUoeUEMlI47zqiFHLpO3C90HuGSi0ht2g0sUgfgo/XIkTaYb4rjz0rwfRVGHoDk SSkWjwtCP7L3O33X61PG3xTkMcXcB/wn7bpyVoZc8gcJ18bL3xNFhplVGFP7CZDBYUaN/7jrUBZ 4+5VoCTIpAeSjJQ== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Authority-Analysis: v=2.4 cv=Oq9/DS/t c=1 sm=1 tr=0 ts=6a54c8c6 cx=c_pps a=mPf7EqFMSY9/WdsSgAYMbA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=QyXUC8HyAAAA:8 a=nzuXsxulAAAA:8 a=EUspDBNiAAAA:8 a=r134EpD-t8S8Nhkp70wA:9 a=QEXdDO2ut3YA:10 a=dawVfQjAaf238kedN5IG:22 a=Jn5cl5okm61iLnyvC_SE:22 X-Proofpoint-ORIG-GUID: rHOrWO4pMymY_1cPByO9JUbY0vfKsaWT X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfX+uw+I8QXIJBH 34b7pv8kE3octBhc8/VP/EcYu5Pn8PjzSlTUnwH11MMKmQbghdE7HY1AvLxNj5zJeGNuQ1NRKvf BDw4JE+Ra4y5KTS5sJMlIAJYySlNg2I= X-Proofpoint-GUID: rHOrWO4pMymY_1cPByO9JUbY0vfKsaWT X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEzMDExNyBTYWx0ZWRfXx6p5Z8bcy7Hf 7tTKkZP7ZrtPIRRD14raQcC0MM8ik5zIOttnDM5jCNKUecFHVDXcHaALkZfcyW/884EDFHSqTj/ 5r1zf8o8E6IPNIqwTuVwKZFEA2M5iKFhbNy/zUaFMTK6iGRtB7W+R90fgKujS39PsIW6aaZ5uyG TGCtgz3vlH1ekAyk8ud4vWWgWHsRVIjoQBVRJnbUfG8SGkz1ftXi/yEBu2I8WQXhARBvi8rOZMI o9FA2eS63oEzOHMvpKmXxXujY8TQz2tj/vXvkvDxx+J3QfVtQH4WoQU5EFZDUU63MDI6BMOzrYX cd6EFfjgtweIK/2KBbs1I8Ph36wtKuxoz2TZVFBum+bHEr91LhvqdKfDRGAjBXBv+5w+kGmKxuS AFCCcv37p9LbC01ML1zWyZeMTLdVDM/ixs8SKDFzIpdm+gC7uy9jEnMRYrxmGh2FSUIgiQ65mgb ZG3pabyxpQchQ7NcQiQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-13_02,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 impostorscore=0 spamscore=0 malwarescore=0 bulkscore=0 adultscore=0 clxscore=1015 phishscore=0 suspectscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607130117 The software node fw_devlink support already has its own kunit suite, but that verifies the fwnode links in isolation. Add GPIO tests that prove the ordering works in a real-life use-case: a GPIO consumer that references its provider via a software node. The first suite registers the provider's software node, adds the consumer device first and checks that fw_devlink defers its probe until the provider has been added and bound. The second covers the fallback: with the provider's software node not yet registered no supplier link is created, so the consumer probes, devm_gpiod_get() returns -EPROBE_DEFER and the consumer only binds once the provider shows up. While at it: the existing gpio_unbind_with_consumers() test keeps the consumer bound while the provider goes away and then operates the orphaned descriptor. With software nodes now being covered by fw_devlink that would instead force-unbind the consumer along with the provider, so opt it out by setting FWNODE_FLAG_LINKS_ADDED. Acked-by: Andy Shevchenko Tested-by: David Gow Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-kunit.c | 291 +++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 284 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpiolib-kunit.c b/drivers/gpio/gpiolib-kunit.c index 380b68f879e55433668353bb88067d561142a5bc..6c25561c1e9b104b4049965b70f= b5c044051570b 100644 --- a/drivers/gpio/gpiolib-kunit.c +++ b/drivers/gpio/gpiolib-kunit.c @@ -3,6 +3,8 @@ * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries */ =20 +#include +#include #include #include #include @@ -11,12 +13,16 @@ #include #include #include +#include =20 +#include #include #include =20 #define GPIO_TEST_PROVIDER "gpio-test-provider" #define GPIO_SWNODE_TEST_CONSUMER "gpio-swnode-test-consumer" +#define GPIO_PROBE_ORDER_TEST_CONSUMER "gpio-probe-order-test-consumer" +#define GPIO_PROBE_DEFER_TEST_CONSUMER "gpio-probe-defer-test-consumer" #define GPIO_UNBIND_TEST_CONSUMER "gpio-unbind-test-consumer" =20 static int gpio_test_provider_get_direction(struct gpio_chip *gc, unsigned= int offset) @@ -213,6 +219,265 @@ static struct kunit_suite gpio_swnode_lookup_test_sui= te =3D { .test_cases =3D gpio_swnode_lookup_tests, }; =20 +static void gpio_swnode_unregister_swnode(void *data) +{ + software_node_unregister(data); +} + +struct gpio_probe_order_pdata { + unsigned int probe_count; + bool gpio_ok; +}; + +static const struct gpio_probe_order_pdata gpio_probe_order_pdata_template= =3D { + .probe_count =3D 0, + .gpio_ok =3D false, +}; + +static int gpio_probe_order_consumer_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct gpio_probe_order_pdata *pdata =3D dev_get_platdata(dev); + struct gpio_desc *desc; + + pdata->probe_count++; + + desc =3D devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + pdata->gpio_ok =3D true; + + return 0; +} + +static struct platform_driver gpio_probe_order_consumer_driver =3D { + .probe =3D gpio_probe_order_consumer_probe, + .driver =3D { + .name =3D GPIO_PROBE_ORDER_TEST_CONSUMER, + }, +}; + +/* + * Verify that fw_devlink orders the probe of a GPIO consumer after its + * provider. The consumer references the provider through a software node = and + * is registered first. fw_devlink must defer it before its driver's probe= () + * is ever entered, so the consumer probes exactly once - only after the + * provider is added and bound. + */ +static void gpio_swnode_probe_order(struct kunit *test) +{ + struct property_entry properties[2] =3D { }; + struct gpio_probe_order_pdata *pdata; + struct platform_device_info pdevinfo; + struct platform_device *prvd, *cons; + bool bound =3D false; + int ret; + + ret =3D kunit_platform_driver_register(test, &gpio_test_provider_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret =3D kunit_platform_driver_register(test, &gpio_probe_order_consumer_d= river); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret =3D software_node_register(&gpio_test_provider_swnode); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret =3D kunit_add_action_or_reset(test, gpio_swnode_unregister_swnode, + (void *)&gpio_test_provider_swnode); + KUNIT_ASSERT_EQ(test, ret, 0); + + properties[0] =3D PROPERTY_ENTRY_GPIO("foo-gpios", + &gpio_test_provider_swnode, + 0, GPIO_ACTIVE_HIGH); + + pdevinfo =3D (struct platform_device_info){ + .name =3D GPIO_PROBE_ORDER_TEST_CONSUMER, + .id =3D PLATFORM_DEVID_NONE, + .data =3D &gpio_probe_order_pdata_template, + .size_data =3D sizeof(gpio_probe_order_pdata_template), + .properties =3D properties, + }; + + cons =3D kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons); + + wait_for_device_probe(); + scoped_guard(device, &cons->dev) + bound =3D device_is_bound(&cons->dev); + + KUNIT_ASSERT_FALSE(test, bound); + + pdata =3D dev_get_platdata(&cons->dev); + KUNIT_ASSERT_EQ(test, pdata->probe_count, 0); + KUNIT_ASSERT_FALSE(test, pdata->gpio_ok); + + pdevinfo =3D (struct platform_device_info){ + .name =3D GPIO_TEST_PROVIDER, + .id =3D PLATFORM_DEVID_NONE, + .swnode =3D &gpio_test_provider_swnode, + }; + + prvd =3D kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd); + + wait_for_device_probe(); + + scoped_guard(device, &prvd->dev) + bound =3D device_is_bound(&prvd->dev); + KUNIT_ASSERT_TRUE(test, bound); + + scoped_guard(device, &cons->dev) + bound =3D device_is_bound(&cons->dev); + KUNIT_ASSERT_TRUE(test, bound); + + pdata =3D dev_get_platdata(&cons->dev); + KUNIT_ASSERT_EQ(test, pdata->probe_count, 1); + KUNIT_ASSERT_TRUE(test, pdata->gpio_ok); +} + +struct gpio_probe_defer_pdata { + unsigned int probe_count; + int gpio_err; +}; + +static const struct gpio_probe_defer_pdata gpio_probe_defer_pdata_template= =3D { + .probe_count =3D 0, + .gpio_err =3D 0, +}; + +static int gpio_probe_defer_consumer_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct gpio_probe_defer_pdata *pdata =3D dev_get_platdata(dev); + struct gpio_desc *desc; + + pdata->probe_count++; + + desc =3D devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH); + if (IS_ERR(desc)) { + pdata->gpio_err =3D PTR_ERR(desc); + return pdata->gpio_err; + } + + pdata->gpio_err =3D 0; + + return 0; +} + +static struct platform_driver gpio_probe_defer_consumer_driver =3D { + .probe =3D gpio_probe_defer_consumer_probe, + .driver =3D { + .name =3D GPIO_PROBE_DEFER_TEST_CONSUMER, + }, +}; + +/* + * Verify that a GPIO consumer referencing a provider whose software node = is + * not registered yet, defers its probe instead of failing. + * + * The provider software node is deliberately left unregistered when the + * consumer is added. fw_devlink cannot resolve the reference, so it creat= es no + * supplier link and does not order the consumer - the consumer's probe() = runs + * and reaches devm_gpiod_get(). The swnode GPIO lookup returns -ENOTCONN = for a + * reference to an unregistered node, which gpiolib maps to -EPROBE_DEFER.= Once + * the provider software node and device appear, the deferred consumer pro= bes + * again and binds. + */ +static void gpio_swnode_probe_defer_on_unregistered(struct kunit *test) +{ + struct property_entry properties[2] =3D { }; + struct gpio_probe_defer_pdata *pdata; + struct platform_device_info pdevinfo; + struct platform_device *prvd, *cons; + struct fwnode_handle *fwnode; + bool bound =3D false; + int ret; + + ret =3D kunit_platform_driver_register(test, &gpio_test_provider_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret =3D kunit_platform_driver_register(test, &gpio_probe_defer_consumer_d= river); + KUNIT_ASSERT_EQ(test, ret, 0); + + properties[0] =3D PROPERTY_ENTRY_GPIO("foo-gpios", + &gpio_test_provider_swnode, + 0, GPIO_ACTIVE_HIGH); + + pdevinfo =3D (struct platform_device_info){ + .name =3D GPIO_PROBE_DEFER_TEST_CONSUMER, + .id =3D PLATFORM_DEVID_NONE, + .data =3D &gpio_probe_defer_pdata_template, + .size_data =3D sizeof(gpio_probe_defer_pdata_template), + .properties =3D properties, + }; + + cons =3D kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons); + + wait_for_device_probe(); + scoped_guard(device, &cons->dev) + bound =3D device_is_bound(&cons->dev); + + KUNIT_ASSERT_FALSE(test, bound); + + pdata =3D dev_get_platdata(&cons->dev); + KUNIT_ASSERT_GT(test, pdata->probe_count, 0); + KUNIT_ASSERT_EQ(test, pdata->gpio_err, -EPROBE_DEFER); + + fwnode =3D kunit_software_node_register(test, &gpio_test_provider_swnode); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); + + pdevinfo =3D (struct platform_device_info){ + .name =3D GPIO_TEST_PROVIDER, + .id =3D PLATFORM_DEVID_NONE, + .swnode =3D &gpio_test_provider_swnode, + }; + + prvd =3D kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd); + + wait_for_device_probe(); + + scoped_guard(device, &prvd->dev) + bound =3D device_is_bound(&prvd->dev); + KUNIT_ASSERT_TRUE(test, bound); + + scoped_guard(device, &cons->dev) + bound =3D device_is_bound(&cons->dev); + KUNIT_ASSERT_TRUE(test, bound); + + pdata =3D dev_get_platdata(&cons->dev); + KUNIT_ASSERT_EQ(test, pdata->gpio_err, 0); + + /* Tear down the consumer before the provider to free the GPIO. */ + kunit_platform_device_unregister(test, cons); +} + +static int gpio_swnode_probe_order_test_init(struct kunit *test) +{ + /* + * A prior test may have left a managed device link teardown queued on + * the device_link_mq. Flush it so that software_node_register() + * doesn't spuriously see the node as registered and fail with -EEXIST. + */ + device_link_wait_removal(); + + return 0; +} + +static struct kunit_case gpio_swnode_probe_order_tests[] =3D { + KUNIT_CASE(gpio_swnode_probe_order), + KUNIT_CASE(gpio_swnode_probe_defer_on_unregistered), + { } +}; + +static struct kunit_suite gpio_swnode_probe_order_test_suite =3D { + .name =3D "gpio-swnode-probe-order", + .test_cases =3D gpio_swnode_probe_order_tests, + .init =3D gpio_swnode_probe_order_test_init, +}; + static BLOCKING_NOTIFIER_HEAD(gpio_unbind_notifier); =20 struct gpio_unbind_consumer_drvdata { @@ -310,15 +575,24 @@ static void gpio_unbind_with_consumers(struct kunit *= test) 0, GPIO_ACTIVE_HIGH); properties[1] =3D (struct property_entry){ }; =20 - pdevinfo =3D (struct platform_device_info){ - .name =3D GPIO_UNBIND_TEST_CONSUMER, - .id =3D PLATFORM_DEVID_NONE, - .properties =3D properties, - }; - - cons =3D kunit_platform_device_register_full(test, &pdevinfo); + /* + * This test deliberately keeps the consumer bound while the provider + * is unregistered. fw_devlink would force-unbind the consumer before + * the provider so use the FWNODE_FLAG_LINKS_ADDED flag to opt out of + * it as a workaround. + */ + cons =3D kunit_platform_device_alloc(test, GPIO_UNBIND_TEST_CONSUMER, + PLATFORM_DEVID_NONE); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons); =20 + ret =3D device_create_managed_software_node(&cons->dev, properties, NULL); + KUNIT_ASSERT_EQ(test, ret, 0); + + fwnode_set_flag(dev_fwnode(&cons->dev), FWNODE_FLAG_LINKS_ADDED); + + ret =3D kunit_platform_device_add(test, cons); + KUNIT_ASSERT_EQ(test, ret, 0); + wait_for_device_probe(); scoped_guard(device, &cons->dev) bound =3D device_is_bound(&cons->dev); @@ -346,10 +620,13 @@ static struct kunit_case gpio_unbind_with_consumers_t= ests[] =3D { static struct kunit_suite gpio_unbind_with_consumers_test_suite =3D { .name =3D "gpio-unbind-with-consumers", .test_cases =3D gpio_unbind_with_consumers_tests, + /* We need this here too to clean any left over links. */ + .init =3D gpio_swnode_probe_order_test_init, }; =20 kunit_test_suites( &gpio_swnode_lookup_test_suite, + &gpio_swnode_probe_order_test_suite, &gpio_unbind_with_consumers_test_suite, ); =20 --=20 2.47.3