On Mon, Jun 29, 2026 at 12:52:08PM +0200, Bartosz Golaszewski wrote:
> 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.

...

> ---
>  drivers/base/test/Kconfig               |   5 +
>  drivers/base/test/Makefile              |   3 +
>  drivers/base/test/swnode-devlink-test.c | 336 
> ++++++++++++++++++++++++++++++++

+ MAINTAINERS.

...


>  CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
> +
> +obj-$(CONFIG_DRIVER_SWNODE_KUNIT_TEST) += swnode-devlink-test.o
> +CFLAGS_swnode-devlink-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)

Is it the case for this?

...

> +#include <linux/device.h>
> +#include <linux/fwnode.h>

+ list.h

> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/types.h>
> +#include <linux/wait.h>

...

> +static int swnode_count_suppliers(struct fwnode_handle *fwnode)
> +{
> +     struct fwnode_link *link;
> +     int ret = 0;

Why signed? Also it's not 'ret' semantically it's 'count'.

> +     /*
> +      * 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)
> +             ret++;
> +
> +     return ret;
> +}

...

> +/* 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 = {
> +             .name = "swnode-devlink-test-supplier"

Keep trailing comma.

> +     };

> +

Redundant blank line.

> +     struct fwnode_handle *cons_fwnode, *supp_fwnode;
> +     int ret;
> +
> +     const struct property_entry props[] = {
> +             PROPERTY_ENTRY_REF("supplier", &supp_swnode),
> +             { }
> +     };
> +
> +     supp_fwnode = kunit_software_node_register(test, &supp_swnode);
> +     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supp_fwnode);
> +
> +     cons_fwnode = kunit_fwnode_create_software_node(test, props, NULL);
> +     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons_fwnode);
> +
> +     ret = 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 = {
> +             .name = "swnode-devlink-test-supplier-1"

Keep comma.

> +     };
> +     static const struct software_node supp2_swnode = {
> +             .name = "swnode-devlink-test-supplier-2"

Ditto.

> +     };
> +     static const struct software_node *supp_nodes[] = {
> +             &supp1_swnode, &supp2_swnode, NULL

Here it's fine.

> +     };

> +

Redundant blank line.

> +     const struct property_entry props[] = {
> +             PROPERTY_ENTRY_REF("foo", &supp1_swnode),
> +             PROPERTY_ENTRY_REF("bar", &supp2_swnode),
> +             { }
> +     };
> +
> +     struct fwnode_handle *fwnode;
> +     int ret;
> +
> +     ret = kunit_software_node_register_node_group(test, supp_nodes);
> +     KUNIT_ASSERT_EQ(test, ret, 0);
> +
> +     fwnode = kunit_fwnode_create_software_node(test, props, NULL);
> +     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
> +
> +     ret = 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(&supp1_swnode)));
> +     KUNIT_EXPECT_TRUE(test, swnode_has_link(fwnode, 
> software_node_fwnode(&supp2_swnode)));
> +}

...

> +static void swnode_devlink_test_unregistered_ref(struct kunit *test)

Same comments as per above.

...

> +static void swnode_devlink_test_remote_endpoint_excluded(struct kunit *test)

Ditto.

...

> +static void swnode_devlink_test_ref_array(struct kunit *test)

Ditto.

...

> +#define SWNODE_DEVLINK_TEST_TIMEOUT_MS       2000

(2 * MSEC_PER_SEC) ?
(will require time.h).

...

> +static int swnode_test_record_probe(struct platform_device *pdev)
> +{
> +     struct swnode_test_probe_order *order = platform_get_drvdata(pdev);
> +
> +     if (order && order->count < ARRAY_SIZE(order->probed)) {

+ array_size.h

> +             order->probed[order->count++] = dev_name(&pdev->dev);
> +             wake_up_interruptible(&order->wq);
> +     }
> +
> +     return 0;
> +}

...

> +static void swnode_devlink_test_probe_order(struct kunit *test)

As per above comments.

...

> +static struct kunit_suite swnode_test_suite = {
> +     .name = "software-node-links",
> +     .test_cases = swnode_test_cases,
> +};

> +

Redundant blank line.

> +kunit_test_suite(swnode_test_suite);

-- 
With Best Regards,
Andy Shevchenko



Reply via email to