* [PATCH v3 0/3] gpio: add kunit tests for GPIO core
@ 2026-05-22 13:42 Bartosz Golaszewski
2026-05-22 13:42 ` [PATCH v3 1/3] kunit: provide kunit_platform_device_register_full() Bartosz Golaszewski
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Bartosz Golaszewski @ 2026-05-22 13:42 UTC (permalink / raw)
To: Brendan Higgins, David Gow, Rae Moar, Linus Walleij, Bartosz Golaszewski
Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio,
Bartosz Golaszewski
This series adds a first batch of kunit tests for GPIO core. I intend to
gradually add more coverage for functionalities that can't really be
tested from user-space with the existing kernel selftests or libgpiod
tests.
Merging strategy: with an Ack from kunit maintainers, this can go
through the GPIO tree for v7.2.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
Changes in v3:
- Make kunit_platform_device_unregister() handle both cases of platform
devices created with kunit_platform_device_alloc() +
kunit_platform_device_add() and kunit_platform_device_register_full()
(sashiko)
- Link to v2: https://patch.msgid.link/20260520-gpiolib-kunit-v2-0-cc9db39881da@oss.qualcomm.com
Changes in v2:
- Remove cases of kunit killing a thread on test failure with device lock
taken
- Fix a platform device leak on test failure
- New patch: provide kunit_platform_device_unregister()
- Link to v1: https://patch.msgid.link/20260518-gpiolib-kunit-v1-0-131ec646c4df@oss.qualcomm.com
---
Bartosz Golaszewski (3):
kunit: provide kunit_platform_device_register_full()
kunit: provide kunit_platform_device_unregister()
gpio: add kunit test cases for the GPIO subsystem
drivers/gpio/Kconfig | 8 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpiolib-kunit.c | 358 ++++++++++++++++++++++++++++++++++++++++
include/kunit/platform_device.h | 6 +
lib/kunit/platform.c | 64 +++++++
5 files changed, 437 insertions(+)
---
base-commit: 80dd246accce631c328ea43294e53b2b2dd2aa32
change-id: 20260326-gpiolib-kunit-d7f1b5541ffa
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v3 1/3] kunit: provide kunit_platform_device_register_full() 2026-05-22 13:42 [PATCH v3 0/3] gpio: add kunit tests for GPIO core Bartosz Golaszewski @ 2026-05-22 13:42 ` Bartosz Golaszewski 2026-05-26 8:58 ` David Gow 2026-05-22 13:42 ` [PATCH v3 2/3] kunit: provide kunit_platform_device_unregister() Bartosz Golaszewski ` (3 subsequent siblings) 4 siblings, 1 reply; 10+ messages in thread From: Bartosz Golaszewski @ 2026-05-22 13:42 UTC (permalink / raw) To: Brendan Higgins, David Gow, Rae Moar, Linus Walleij, Bartosz Golaszewski Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio, Bartosz Golaszewski Provide a kunit-managed variant of platform_device_register_full(). Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> --- include/kunit/platform_device.h | 4 ++++ lib/kunit/platform.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/kunit/platform_device.h b/include/kunit/platform_device.h index f8236a8536f7ebcee6b0e00a7bd799a14b345c1b..8cad6e1c3e7efba862862b579089f2f317784a73 100644 --- a/include/kunit/platform_device.h +++ b/include/kunit/platform_device.h @@ -6,10 +6,14 @@ struct completion; struct kunit; struct platform_device; struct platform_driver; +struct platform_device_info; struct platform_device * kunit_platform_device_alloc(struct kunit *test, const char *name, int id); int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev); +struct platform_device * +kunit_platform_device_register_full(struct kunit *test, + const struct platform_device_info *pdevinfo); int kunit_platform_device_prepare_wait_for_probe(struct kunit *test, struct platform_device *pdev, diff --git a/lib/kunit/platform.c b/lib/kunit/platform.c index 0b518de26065d65dac3bd49dd94a4b3e7ea0634b..583b50b538c79599ebbf33e261fe2e9ced35efa9 100644 --- a/lib/kunit/platform.c +++ b/lib/kunit/platform.c @@ -6,6 +6,7 @@ #include <linux/completion.h> #include <linux/device/bus.h> #include <linux/device/driver.h> +#include <linux/err.h> #include <linux/platform_device.h> #include <kunit/platform_device.h> @@ -130,6 +131,36 @@ int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev) } EXPORT_SYMBOL_GPL(kunit_platform_device_add); +/** + * kunit_platform_device_register_full() - Register a KUnit test-managed platform + * device described by platform device info + * @test: test context + * @pdevinfo: platform device information describing the new device + * + * Register a test-managed platform device. The device is unregistered when the + * test completes. + * + * Return: New platform device on success, IS_ERR() on error. + */ +struct platform_device * +kunit_platform_device_register_full(struct kunit *test, + const struct platform_device_info *pdevinfo) +{ + struct platform_device *pdev; + int ret; + + pdev = platform_device_register_full(pdevinfo); + if (IS_ERR(pdev)) + return pdev; + + ret = kunit_add_action_or_reset(test, platform_device_unregister_wrapper, pdev); + if (ret) + return ERR_PTR(ret); + + return pdev; +} +EXPORT_SYMBOL_GPL(kunit_platform_device_register_full); + struct kunit_platform_device_probe_nb { struct completion *x; struct device *dev; -- 2.47.3 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/3] kunit: provide kunit_platform_device_register_full() 2026-05-22 13:42 ` [PATCH v3 1/3] kunit: provide kunit_platform_device_register_full() Bartosz Golaszewski @ 2026-05-26 8:58 ` David Gow 0 siblings, 0 replies; 10+ messages in thread From: David Gow @ 2026-05-26 8:58 UTC (permalink / raw) To: Bartosz Golaszewski, Brendan Higgins, Rae Moar, Linus Walleij, Bartosz Golaszewski Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio Le 22/05/2026 à 9:42 PM, Bartosz Golaszewski a écrit : > Provide a kunit-managed variant of platform_device_register_full(). > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> > --- Thanks! This looks good to me. Reviewed-by: David Gow <david@davidgow.net> Cheers, -- David > include/kunit/platform_device.h | 4 ++++ > lib/kunit/platform.c | 31 +++++++++++++++++++++++++++++++ > 2 files changed, 35 insertions(+) > > diff --git a/include/kunit/platform_device.h b/include/kunit/platform_device.h > index f8236a8536f7ebcee6b0e00a7bd799a14b345c1b..8cad6e1c3e7efba862862b579089f2f317784a73 100644 > --- a/include/kunit/platform_device.h > +++ b/include/kunit/platform_device.h > @@ -6,10 +6,14 @@ struct completion; > struct kunit; > struct platform_device; > struct platform_driver; > +struct platform_device_info; > > struct platform_device * > kunit_platform_device_alloc(struct kunit *test, const char *name, int id); > int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev); > +struct platform_device * > +kunit_platform_device_register_full(struct kunit *test, > + const struct platform_device_info *pdevinfo); > > int kunit_platform_device_prepare_wait_for_probe(struct kunit *test, > struct platform_device *pdev, > diff --git a/lib/kunit/platform.c b/lib/kunit/platform.c > index 0b518de26065d65dac3bd49dd94a4b3e7ea0634b..583b50b538c79599ebbf33e261fe2e9ced35efa9 100644 > --- a/lib/kunit/platform.c > +++ b/lib/kunit/platform.c > @@ -6,6 +6,7 @@ > #include <linux/completion.h> > #include <linux/device/bus.h> > #include <linux/device/driver.h> > +#include <linux/err.h> > #include <linux/platform_device.h> > > #include <kunit/platform_device.h> > @@ -130,6 +131,36 @@ int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev) > } > EXPORT_SYMBOL_GPL(kunit_platform_device_add); > > +/** > + * kunit_platform_device_register_full() - Register a KUnit test-managed platform > + * device described by platform device info > + * @test: test context > + * @pdevinfo: platform device information describing the new device > + * > + * Register a test-managed platform device. The device is unregistered when the > + * test completes. > + * > + * Return: New platform device on success, IS_ERR() on error. > + */ > +struct platform_device * > +kunit_platform_device_register_full(struct kunit *test, > + const struct platform_device_info *pdevinfo) > +{ > + struct platform_device *pdev; > + int ret; > + > + pdev = platform_device_register_full(pdevinfo); > + if (IS_ERR(pdev)) > + return pdev; > + > + ret = kunit_add_action_or_reset(test, platform_device_unregister_wrapper, pdev); > + if (ret) > + return ERR_PTR(ret); > + > + return pdev; > +} > +EXPORT_SYMBOL_GPL(kunit_platform_device_register_full); > + > struct kunit_platform_device_probe_nb { > struct completion *x; > struct device *dev; > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 2/3] kunit: provide kunit_platform_device_unregister() 2026-05-22 13:42 [PATCH v3 0/3] gpio: add kunit tests for GPIO core Bartosz Golaszewski 2026-05-22 13:42 ` [PATCH v3 1/3] kunit: provide kunit_platform_device_register_full() Bartosz Golaszewski @ 2026-05-22 13:42 ` Bartosz Golaszewski 2026-05-26 8:58 ` David Gow 2026-05-22 13:42 ` [PATCH v3 3/3] gpio: add kunit test cases for the GPIO subsystem Bartosz Golaszewski ` (2 subsequent siblings) 4 siblings, 1 reply; 10+ messages in thread From: Bartosz Golaszewski @ 2026-05-22 13:42 UTC (permalink / raw) To: Brendan Higgins, David Gow, Rae Moar, Linus Walleij, Bartosz Golaszewski Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio, Bartosz Golaszewski Tests may want to unregister a platform device as part of the test case logic. Using the regular platform_device_register() with kunit assertions may result in a platform device leak or otherwise requires cumbersome error handling. Provide a function that unregisters a kunit-managed platform device and drops the release action from the test's list. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> --- include/kunit/platform_device.h | 2 ++ lib/kunit/platform.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/kunit/platform_device.h b/include/kunit/platform_device.h index 8cad6e1c3e7efba862862b579089f2f317784a73..eee565d5d1d35c1d1bc82b45eb91d21d00c68428 100644 --- a/include/kunit/platform_device.h +++ b/include/kunit/platform_device.h @@ -14,6 +14,8 @@ int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev); struct platform_device * kunit_platform_device_register_full(struct kunit *test, const struct platform_device_info *pdevinfo); +void kunit_platform_device_unregister(struct kunit *test, + struct platform_device *pdev); int kunit_platform_device_prepare_wait_for_probe(struct kunit *test, struct platform_device *pdev, diff --git a/lib/kunit/platform.c b/lib/kunit/platform.c index 583b50b538c79599ebbf33e261fe2e9ced35efa9..737758d710b2839fab29c5cbcf3bc5ba00e20094 100644 --- a/lib/kunit/platform.c +++ b/lib/kunit/platform.c @@ -161,6 +161,39 @@ kunit_platform_device_register_full(struct kunit *test, } EXPORT_SYMBOL_GPL(kunit_platform_device_register_full); +static bool +kunit_platform_device_add_match(struct kunit *test, struct kunit_resource *res, + void *match_data) +{ + struct platform_device *pdev = match_data; + + return res->data == pdev && res->free == kunit_platform_device_add_exit; +} + +/** + * kunit_platform_device_unregister() - Unregister a KUnit-managed platform device + * @test: test context + * @pdev: platform device to unregister + * + * Unregister a test-managed platform device and cancel its release action. + */ +void kunit_platform_device_unregister(struct kunit *test, + struct platform_device *pdev) +{ + struct kunit_resource *res; + + res = kunit_find_resource(test, kunit_platform_device_add_match, pdev); + if (res) { + res->free = NULL; + kunit_put_resource(res); + } else { + kunit_remove_action(test, platform_device_unregister_wrapper, pdev); + } + + platform_device_unregister(pdev); +} +EXPORT_SYMBOL_GPL(kunit_platform_device_unregister); + struct kunit_platform_device_probe_nb { struct completion *x; struct device *dev; -- 2.47.3 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 2/3] kunit: provide kunit_platform_device_unregister() 2026-05-22 13:42 ` [PATCH v3 2/3] kunit: provide kunit_platform_device_unregister() Bartosz Golaszewski @ 2026-05-26 8:58 ` David Gow 0 siblings, 0 replies; 10+ messages in thread From: David Gow @ 2026-05-26 8:58 UTC (permalink / raw) To: Bartosz Golaszewski, Brendan Higgins, Rae Moar, Linus Walleij, Bartosz Golaszewski Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio Le 22/05/2026 à 9:42 PM, Bartosz Golaszewski a écrit : > Tests may want to unregister a platform device as part of the test case > logic. Using the regular platform_device_register() with kunit > assertions may result in a platform device leak or otherwise requires > cumbersome error handling. Provide a function that unregisters a > kunit-managed platform device and drops the release action from the > test's list. > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> > --- Looks good, thanks. Reviewed-by: David Gow <david@davidgow.net> Cheers, -- David > include/kunit/platform_device.h | 2 ++ > lib/kunit/platform.c | 33 +++++++++++++++++++++++++++++++++ > 2 files changed, 35 insertions(+) > > diff --git a/include/kunit/platform_device.h b/include/kunit/platform_device.h > index 8cad6e1c3e7efba862862b579089f2f317784a73..eee565d5d1d35c1d1bc82b45eb91d21d00c68428 100644 > --- a/include/kunit/platform_device.h > +++ b/include/kunit/platform_device.h > @@ -14,6 +14,8 @@ int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev); > struct platform_device * > kunit_platform_device_register_full(struct kunit *test, > const struct platform_device_info *pdevinfo); > +void kunit_platform_device_unregister(struct kunit *test, > + struct platform_device *pdev); > > int kunit_platform_device_prepare_wait_for_probe(struct kunit *test, > struct platform_device *pdev, > diff --git a/lib/kunit/platform.c b/lib/kunit/platform.c > index 583b50b538c79599ebbf33e261fe2e9ced35efa9..737758d710b2839fab29c5cbcf3bc5ba00e20094 100644 > --- a/lib/kunit/platform.c > +++ b/lib/kunit/platform.c > @@ -161,6 +161,39 @@ kunit_platform_device_register_full(struct kunit *test, > } > EXPORT_SYMBOL_GPL(kunit_platform_device_register_full); > > +static bool > +kunit_platform_device_add_match(struct kunit *test, struct kunit_resource *res, > + void *match_data) > +{ > + struct platform_device *pdev = match_data; > + > + return res->data == pdev && res->free == kunit_platform_device_add_exit; > +} > + > +/** > + * kunit_platform_device_unregister() - Unregister a KUnit-managed platform device > + * @test: test context > + * @pdev: platform device to unregister > + * > + * Unregister a test-managed platform device and cancel its release action. > + */ > +void kunit_platform_device_unregister(struct kunit *test, > + struct platform_device *pdev) > +{ > + struct kunit_resource *res; > + > + res = kunit_find_resource(test, kunit_platform_device_add_match, pdev); > + if (res) { > + res->free = NULL; > + kunit_put_resource(res); > + } else { > + kunit_remove_action(test, platform_device_unregister_wrapper, pdev); > + } > + > + platform_device_unregister(pdev); > +} > +EXPORT_SYMBOL_GPL(kunit_platform_device_unregister); > + > struct kunit_platform_device_probe_nb { > struct completion *x; > struct device *dev; > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 3/3] gpio: add kunit test cases for the GPIO subsystem 2026-05-22 13:42 [PATCH v3 0/3] gpio: add kunit tests for GPIO core Bartosz Golaszewski 2026-05-22 13:42 ` [PATCH v3 1/3] kunit: provide kunit_platform_device_register_full() Bartosz Golaszewski 2026-05-22 13:42 ` [PATCH v3 2/3] kunit: provide kunit_platform_device_unregister() Bartosz Golaszewski @ 2026-05-22 13:42 ` Bartosz Golaszewski 2026-05-26 8:58 ` David Gow 2026-05-25 13:33 ` [PATCH v3 0/3] gpio: add kunit tests for GPIO core Linus Walleij 2026-05-26 9:20 ` Bartosz Golaszewski 4 siblings, 1 reply; 10+ messages in thread From: Bartosz Golaszewski @ 2026-05-22 13:42 UTC (permalink / raw) To: Brendan Higgins, David Gow, Rae Moar, Linus Walleij, Bartosz Golaszewski Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio, Bartosz Golaszewski Add a module containing kunit test cases for GPIO core. The idea is to use it to test functionalities that can't easily be tested from user-space with kernel selftests or GPIO character device test suites provided by the libgpiod package. For now add test cases that verify software node based lookup and ensure that a GPIO provider unbinding with active consumers does not cause a crash. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> --- drivers/gpio/Kconfig | 8 + drivers/gpio/Makefile | 1 + drivers/gpio/gpiolib-kunit.c | 358 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 367 insertions(+) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 00fcab5d09a4294ed778cea78af5867a0f6e481b..0306005fb7d65ae85905e967b9065fd74db753db 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -102,6 +102,14 @@ config GPIO_CDEV_V1 This ABI version is deprecated. Please use the latest ABI for new developments. +config GPIO_KUNIT + tristate "Build GPIO Kunit test cases" + depends on KUNIT + default KUNIT_ALL_TESTS + help + Say Y here to build the module containing Kunit test cases verifying + the functionality of the GPIO subsystem. + config GPIO_GENERIC depends on HAS_IOMEM # Only for IOMEM drivers tristate diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 2ea47d9d3dca948e1cdc46965e83b0e1b6de5f70..c66b6dd659b16b80b6bb6b15fac3e3f462dec596 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o gpiolib-acpi-y := gpiolib-acpi-core.o gpiolib-acpi-quirks.o obj-$(CONFIG_GPIOLIB) += gpiolib-swnode.o obj-$(CONFIG_GPIO_SHARED) += gpiolib-shared.o +obj-$(CONFIG_GPIO_KUNIT) += gpiolib-kunit.o # Device drivers. Generally keep list sorted alphabetically obj-$(CONFIG_GPIO_REGMAP) += gpio-regmap.o diff --git a/drivers/gpio/gpiolib-kunit.c b/drivers/gpio/gpiolib-kunit.c new file mode 100644 index 0000000000000000000000000000000000000000..380b68f879e55433668353bb88067d561142a5bc --- /dev/null +++ b/drivers/gpio/gpiolib-kunit.c @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries + */ + +#include <linux/fwnode.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/driver.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/property.h> +#include <linux/notifier.h> +#include <linux/platform_device.h> +#include <linux/property.h> + +#include <kunit/platform_device.h> +#include <kunit/test.h> + +#define GPIO_TEST_PROVIDER "gpio-test-provider" +#define GPIO_SWNODE_TEST_CONSUMER "gpio-swnode-test-consumer" +#define GPIO_UNBIND_TEST_CONSUMER "gpio-unbind-test-consumer" + +static int gpio_test_provider_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static int gpio_test_provider_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + return 0; +} + +static int gpio_test_provider_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct gpio_chip *gc; + + gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); + if (!gc) + return -ENOMEM; + + gc->base = -1; + gc->ngpio = 4; + gc->label = "gpio-swnode-consumer-test-device"; + gc->parent = dev; + gc->owner = THIS_MODULE; + + gc->get_direction = gpio_test_provider_get_direction; + gc->set = gpio_test_provider_set; + + return devm_gpiochip_add_data(dev, gc, NULL); +} + +static struct platform_driver gpio_test_provider_driver = { + .probe = gpio_test_provider_probe, + .driver = { + .name = GPIO_TEST_PROVIDER, + }, +}; + +static const struct software_node gpio_test_provider_swnode = { + .name = "gpio-test-provider-primary", +}; + +struct gpio_swnode_consumer_pdata { + bool gpio_ok; +}; + +static const struct gpio_swnode_consumer_pdata gpio_swnode_pdata_template = { + .gpio_ok = false, +}; + +static int gpio_swnode_consumer_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct gpio_swnode_consumer_pdata *pdata = dev_get_platdata(dev); + struct gpio_desc *desc; + + desc = devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + pdata->gpio_ok = true; + + return 0; +} + +static struct platform_driver gpio_swnode_consumer_driver = { + .probe = gpio_swnode_consumer_probe, + .driver = { + .name = GPIO_SWNODE_TEST_CONSUMER, + }, +}; + +static void gpio_swnode_lookup_by_primary(struct kunit *test) +{ + struct gpio_swnode_consumer_pdata *pdata; + struct platform_device_info pdevinfo; + struct property_entry properties[2]; + struct platform_device *pdev; + bool bound = false; + int ret; + + ret = kunit_platform_driver_register(test, &gpio_test_provider_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = kunit_platform_driver_register(test, &gpio_swnode_consumer_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + pdevinfo = (struct platform_device_info){ + .name = GPIO_TEST_PROVIDER, + .id = PLATFORM_DEVID_NONE, + .swnode = &gpio_test_provider_swnode, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios", + &gpio_test_provider_swnode, + 0, GPIO_ACTIVE_HIGH); + properties[1] = (struct property_entry){ }; + + pdevinfo = (struct platform_device_info){ + .name = GPIO_SWNODE_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + .data = &gpio_swnode_pdata_template, + .size_data = sizeof(gpio_swnode_pdata_template), + .properties = properties, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + wait_for_device_probe(); + scoped_guard(device, &pdev->dev) + bound = device_is_bound(&pdev->dev); + + KUNIT_ASSERT_TRUE(test, bound); + + pdata = dev_get_platdata(&pdev->dev); + KUNIT_ASSERT_TRUE(test, pdata->gpio_ok); +} + +static void gpio_swnode_lookup_by_secondary(struct kunit *test) +{ + struct gpio_swnode_consumer_pdata *pdata; + struct platform_device_info pdevinfo; + struct property_entry properties[2]; + struct fwnode_handle *primary; + struct platform_device *pdev; + bool bound = false; + int ret; + + /* + * Can't live on the stack as it will still get referenced in cleanup + * path after this function returns. + */ + primary = kunit_kzalloc(test, sizeof(*primary), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, primary); + + ret = kunit_platform_driver_register(test, &gpio_test_provider_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = kunit_platform_driver_register(test, &gpio_swnode_consumer_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + fwnode_init(primary, NULL); + + pdevinfo = (struct platform_device_info){ + .name = GPIO_TEST_PROVIDER, + .id = PLATFORM_DEVID_NONE, + .fwnode = primary, + .swnode = &gpio_test_provider_swnode, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios", + &gpio_test_provider_swnode, + 0, GPIO_ACTIVE_HIGH); + properties[1] = (struct property_entry){ }; + + pdevinfo = (struct platform_device_info){ + .name = GPIO_SWNODE_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + .data = &gpio_swnode_pdata_template, + .size_data = sizeof(gpio_swnode_pdata_template), + .properties = properties, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + wait_for_device_probe(); + scoped_guard(device, &pdev->dev) + bound = device_is_bound(&pdev->dev); + + KUNIT_ASSERT_TRUE(test, bound); + + pdata = dev_get_platdata(&pdev->dev); + KUNIT_ASSERT_TRUE(test, pdata->gpio_ok); +} + +static struct kunit_case gpio_swnode_lookup_tests[] = { + KUNIT_CASE(gpio_swnode_lookup_by_primary), + KUNIT_CASE(gpio_swnode_lookup_by_secondary), + { } +}; + +static struct kunit_suite gpio_swnode_lookup_test_suite = { + .name = "gpio-swnode-lookup", + .test_cases = gpio_swnode_lookup_tests, +}; + +static BLOCKING_NOTIFIER_HEAD(gpio_unbind_notifier); + +struct gpio_unbind_consumer_drvdata { + struct device *dev; + struct gpio_desc *desc; + struct notifier_block nb; + int set_retval; +}; + +static int gpio_unbind_notify(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct gpio_unbind_consumer_drvdata *drvdata = + container_of(nb, struct gpio_unbind_consumer_drvdata, nb); + struct device *dev = data; + + if (dev != drvdata->dev) + return NOTIFY_DONE; + + drvdata->set_retval = gpiod_set_value_cansleep(drvdata->desc, 0); + + return NOTIFY_OK; +} + +static void gpio_unbind_unregister_notifier(void *data) +{ + struct notifier_block *nb = data; + + blocking_notifier_chain_unregister(&gpio_unbind_notifier, nb); +} + +static int gpio_unbind_consumer_probe(struct platform_device *pdev) +{ + struct gpio_unbind_consumer_drvdata *data; + struct device *dev = &pdev->dev; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = dev; + + data->desc = devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH); + if (IS_ERR(data->desc)) + return PTR_ERR(data->desc); + + data->nb.notifier_call = gpio_unbind_notify; + ret = blocking_notifier_chain_register(&gpio_unbind_notifier, &data->nb); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, gpio_unbind_unregister_notifier, &data->nb); + if (ret) + return ret; + + platform_set_drvdata(pdev, data); + + return 0; +} + +static struct platform_driver gpio_unbind_consumer_driver = { + .probe = gpio_unbind_consumer_probe, + .driver = { + .name = GPIO_UNBIND_TEST_CONSUMER, + }, +}; + +static void gpio_unbind_with_consumers(struct kunit *test) +{ + struct gpio_unbind_consumer_drvdata *cons_data; + struct platform_device_info pdevinfo; + struct property_entry properties[2]; + struct platform_device *prvd, *cons; + bool bound = false; + int ret; + + ret = kunit_platform_driver_register(test, &gpio_test_provider_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = kunit_platform_driver_register(test, &gpio_unbind_consumer_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + pdevinfo = (struct platform_device_info){ + .name = GPIO_TEST_PROVIDER, + .id = PLATFORM_DEVID_NONE, + .swnode = &gpio_test_provider_swnode, + }; + + prvd = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd); + + properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios", + &gpio_test_provider_swnode, + 0, GPIO_ACTIVE_HIGH); + properties[1] = (struct property_entry){ }; + + pdevinfo = (struct platform_device_info){ + .name = GPIO_UNBIND_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + .properties = properties, + }; + + cons = 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 = device_is_bound(&cons->dev); + + KUNIT_ASSERT_TRUE(test, bound); + + kunit_platform_device_unregister(test, prvd); + + ret = blocking_notifier_call_chain(&gpio_unbind_notifier, 0, &cons->dev); + KUNIT_ASSERT_EQ(test, ret, NOTIFY_OK); + + scoped_guard(device, &cons->dev) { + cons_data = platform_get_drvdata(cons); + ret = cons_data->set_retval; + } + + KUNIT_ASSERT_EQ(test, ret, -ENODEV); +} + +static struct kunit_case gpio_unbind_with_consumers_tests[] = { + KUNIT_CASE(gpio_unbind_with_consumers), + { } +}; + +static struct kunit_suite gpio_unbind_with_consumers_test_suite = { + .name = "gpio-unbind-with-consumers", + .test_cases = gpio_unbind_with_consumers_tests, +}; + +kunit_test_suites( + &gpio_swnode_lookup_test_suite, + &gpio_unbind_with_consumers_test_suite, +); + +MODULE_DESCRIPTION("Test module for the GPIO subsystem"); +MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>"); +MODULE_LICENSE("GPL"); -- 2.47.3 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 3/3] gpio: add kunit test cases for the GPIO subsystem 2026-05-22 13:42 ` [PATCH v3 3/3] gpio: add kunit test cases for the GPIO subsystem Bartosz Golaszewski @ 2026-05-26 8:58 ` David Gow 2026-05-26 9:19 ` Bartosz Golaszewski 0 siblings, 1 reply; 10+ messages in thread From: David Gow @ 2026-05-26 8:58 UTC (permalink / raw) To: Bartosz Golaszewski, Brendan Higgins, Rae Moar, Linus Walleij, Bartosz Golaszewski Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio Le 22/05/2026 à 9:42 PM, Bartosz Golaszewski a écrit : > Add a module containing kunit test cases for GPIO core. The idea is to > use it to test functionalities that can't easily be tested from > user-space with kernel selftests or GPIO character device test suites > provided by the libgpiod package. > > For now add test cases that verify software node based lookup and ensure > that a GPIO provider unbinding with active consumers does not cause a > crash. > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> > --- This is a nice looking test, thanks. Reviewed-by: David Gow <david@davidgow.net> Happy for this (and the previous two patches) to go in via gpio, but if you'd rather them go in via the KUnit tree, let me know. Cheers, -- David > drivers/gpio/Kconfig | 8 + > drivers/gpio/Makefile | 1 + > drivers/gpio/gpiolib-kunit.c | 358 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 367 insertions(+) > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 00fcab5d09a4294ed778cea78af5867a0f6e481b..0306005fb7d65ae85905e967b9065fd74db753db 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -102,6 +102,14 @@ config GPIO_CDEV_V1 > This ABI version is deprecated. > Please use the latest ABI for new developments. > > +config GPIO_KUNIT > + tristate "Build GPIO Kunit test cases" > + depends on KUNIT > + default KUNIT_ALL_TESTS > + help > + Say Y here to build the module containing Kunit test cases verifying > + the functionality of the GPIO subsystem. > + FYI: If you want to add CONFIG_GPIOLIB=y to tools/testing/kunit/configs/all_tests.config, we can enable these tests when the --alltests flag is passed to kunit.py. > config GPIO_GENERIC > depends on HAS_IOMEM # Only for IOMEM drivers > tristate > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > index 2ea47d9d3dca948e1cdc46965e83b0e1b6de5f70..c66b6dd659b16b80b6bb6b15fac3e3f462dec596 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -13,6 +13,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o > gpiolib-acpi-y := gpiolib-acpi-core.o gpiolib-acpi-quirks.o > obj-$(CONFIG_GPIOLIB) += gpiolib-swnode.o > obj-$(CONFIG_GPIO_SHARED) += gpiolib-shared.o > +obj-$(CONFIG_GPIO_KUNIT) += gpiolib-kunit.o > > # Device drivers. Generally keep list sorted alphabetically > obj-$(CONFIG_GPIO_REGMAP) += gpio-regmap.o > diff --git a/drivers/gpio/gpiolib-kunit.c b/drivers/gpio/gpiolib-kunit.c > new file mode 100644 > index 0000000000000000000000000000000000000000..380b68f879e55433668353bb88067d561142a5bc > --- /dev/null > +++ b/drivers/gpio/gpiolib-kunit.c > @@ -0,0 +1,358 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (C) Qualcomm Technologies, Inc. and/or its subsidiaries > + */ > + > +#include <linux/fwnode.h> > +#include <linux/gpio/consumer.h> > +#include <linux/gpio/driver.h> > +#include <linux/gpio/machine.h> > +#include <linux/gpio/property.h> > +#include <linux/notifier.h> > +#include <linux/platform_device.h> > +#include <linux/property.h> > + > +#include <kunit/platform_device.h> > +#include <kunit/test.h> > + > +#define GPIO_TEST_PROVIDER "gpio-test-provider" > +#define GPIO_SWNODE_TEST_CONSUMER "gpio-swnode-test-consumer" > +#define GPIO_UNBIND_TEST_CONSUMER "gpio-unbind-test-consumer" > + > +static int gpio_test_provider_get_direction(struct gpio_chip *gc, unsigned int offset) > +{ > + return GPIO_LINE_DIRECTION_OUT; > +} > + > +static int gpio_test_provider_set(struct gpio_chip *gc, unsigned int offset, int value) > +{ > + return 0; > +} > + > +static int gpio_test_provider_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct gpio_chip *gc; > + > + gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); > + if (!gc) > + return -ENOMEM; > + > + gc->base = -1; > + gc->ngpio = 4; > + gc->label = "gpio-swnode-consumer-test-device"; > + gc->parent = dev; > + gc->owner = THIS_MODULE; > + > + gc->get_direction = gpio_test_provider_get_direction; > + gc->set = gpio_test_provider_set; > + > + return devm_gpiochip_add_data(dev, gc, NULL); > +} > + > +static struct platform_driver gpio_test_provider_driver = { > + .probe = gpio_test_provider_probe, > + .driver = { > + .name = GPIO_TEST_PROVIDER, > + }, > +}; > + > +static const struct software_node gpio_test_provider_swnode = { > + .name = "gpio-test-provider-primary", > +}; > + > +struct gpio_swnode_consumer_pdata { > + bool gpio_ok; > +}; > + > +static const struct gpio_swnode_consumer_pdata gpio_swnode_pdata_template = { > + .gpio_ok = false, > +}; > + > +static int gpio_swnode_consumer_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct gpio_swnode_consumer_pdata *pdata = dev_get_platdata(dev); > + struct gpio_desc *desc; > + > + desc = devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH); > + if (IS_ERR(desc)) > + return PTR_ERR(desc); > + > + pdata->gpio_ok = true; > + > + return 0; > +} > + > +static struct platform_driver gpio_swnode_consumer_driver = { > + .probe = gpio_swnode_consumer_probe, > + .driver = { > + .name = GPIO_SWNODE_TEST_CONSUMER, > + }, > +}; > + > +static void gpio_swnode_lookup_by_primary(struct kunit *test) > +{ > + struct gpio_swnode_consumer_pdata *pdata; > + struct platform_device_info pdevinfo; > + struct property_entry properties[2]; > + struct platform_device *pdev; > + bool bound = false; > + int ret; > + > + ret = kunit_platform_driver_register(test, &gpio_test_provider_driver); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + ret = kunit_platform_driver_register(test, &gpio_swnode_consumer_driver); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + pdevinfo = (struct platform_device_info){ > + .name = GPIO_TEST_PROVIDER, > + .id = PLATFORM_DEVID_NONE, > + .swnode = &gpio_test_provider_swnode, > + }; > + > + pdev = kunit_platform_device_register_full(test, &pdevinfo); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); > + > + properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios", > + &gpio_test_provider_swnode, > + 0, GPIO_ACTIVE_HIGH); > + properties[1] = (struct property_entry){ }; > + > + pdevinfo = (struct platform_device_info){ > + .name = GPIO_SWNODE_TEST_CONSUMER, > + .id = PLATFORM_DEVID_NONE, > + .data = &gpio_swnode_pdata_template, > + .size_data = sizeof(gpio_swnode_pdata_template), > + .properties = properties, > + }; > + > + pdev = kunit_platform_device_register_full(test, &pdevinfo); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); > + > + wait_for_device_probe(); > + scoped_guard(device, &pdev->dev) > + bound = device_is_bound(&pdev->dev); > + > + KUNIT_ASSERT_TRUE(test, bound); > + > + pdata = dev_get_platdata(&pdev->dev); > + KUNIT_ASSERT_TRUE(test, pdata->gpio_ok); > +} > + > +static void gpio_swnode_lookup_by_secondary(struct kunit *test) > +{ > + struct gpio_swnode_consumer_pdata *pdata; > + struct platform_device_info pdevinfo; > + struct property_entry properties[2]; > + struct fwnode_handle *primary; > + struct platform_device *pdev; > + bool bound = false; > + int ret; > + > + /* > + * Can't live on the stack as it will still get referenced in cleanup > + * path after this function returns. > + */ > + primary = kunit_kzalloc(test, sizeof(*primary), GFP_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, primary); > + > + ret = kunit_platform_driver_register(test, &gpio_test_provider_driver); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + ret = kunit_platform_driver_register(test, &gpio_swnode_consumer_driver); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + fwnode_init(primary, NULL); > + > + pdevinfo = (struct platform_device_info){ > + .name = GPIO_TEST_PROVIDER, > + .id = PLATFORM_DEVID_NONE, > + .fwnode = primary, > + .swnode = &gpio_test_provider_swnode, > + }; > + > + pdev = kunit_platform_device_register_full(test, &pdevinfo); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); > + > + properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios", > + &gpio_test_provider_swnode, > + 0, GPIO_ACTIVE_HIGH); > + properties[1] = (struct property_entry){ }; > + > + pdevinfo = (struct platform_device_info){ > + .name = GPIO_SWNODE_TEST_CONSUMER, > + .id = PLATFORM_DEVID_NONE, > + .data = &gpio_swnode_pdata_template, > + .size_data = sizeof(gpio_swnode_pdata_template), > + .properties = properties, > + }; > + > + pdev = kunit_platform_device_register_full(test, &pdevinfo); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); > + > + wait_for_device_probe(); > + scoped_guard(device, &pdev->dev) > + bound = device_is_bound(&pdev->dev); > + > + KUNIT_ASSERT_TRUE(test, bound); > + > + pdata = dev_get_platdata(&pdev->dev); > + KUNIT_ASSERT_TRUE(test, pdata->gpio_ok); > +} > + > +static struct kunit_case gpio_swnode_lookup_tests[] = { > + KUNIT_CASE(gpio_swnode_lookup_by_primary), > + KUNIT_CASE(gpio_swnode_lookup_by_secondary), > + { } > +}; > + > +static struct kunit_suite gpio_swnode_lookup_test_suite = { > + .name = "gpio-swnode-lookup", > + .test_cases = gpio_swnode_lookup_tests, > +}; > + > +static BLOCKING_NOTIFIER_HEAD(gpio_unbind_notifier); > + > +struct gpio_unbind_consumer_drvdata { > + struct device *dev; > + struct gpio_desc *desc; > + struct notifier_block nb; > + int set_retval; > +}; > + > +static int gpio_unbind_notify(struct notifier_block *nb, unsigned long action, > + void *data) > +{ > + struct gpio_unbind_consumer_drvdata *drvdata = > + container_of(nb, struct gpio_unbind_consumer_drvdata, nb); > + struct device *dev = data; > + > + if (dev != drvdata->dev) > + return NOTIFY_DONE; > + > + drvdata->set_retval = gpiod_set_value_cansleep(drvdata->desc, 0); > + > + return NOTIFY_OK; > +} > + > +static void gpio_unbind_unregister_notifier(void *data) > +{ > + struct notifier_block *nb = data; > + > + blocking_notifier_chain_unregister(&gpio_unbind_notifier, nb); > +} > + > +static int gpio_unbind_consumer_probe(struct platform_device *pdev) > +{ > + struct gpio_unbind_consumer_drvdata *data; > + struct device *dev = &pdev->dev; > + int ret; > + > + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + data->dev = dev; > + > + data->desc = devm_gpiod_get(dev, "foo", GPIOD_OUT_HIGH); > + if (IS_ERR(data->desc)) > + return PTR_ERR(data->desc); > + > + data->nb.notifier_call = gpio_unbind_notify; > + ret = blocking_notifier_chain_register(&gpio_unbind_notifier, &data->nb); > + if (ret) > + return ret; > + > + ret = devm_add_action_or_reset(dev, gpio_unbind_unregister_notifier, &data->nb); > + if (ret) > + return ret; > + > + platform_set_drvdata(pdev, data); > + > + return 0; > +} > + > +static struct platform_driver gpio_unbind_consumer_driver = { > + .probe = gpio_unbind_consumer_probe, > + .driver = { > + .name = GPIO_UNBIND_TEST_CONSUMER, > + }, > +}; > + > +static void gpio_unbind_with_consumers(struct kunit *test) > +{ > + struct gpio_unbind_consumer_drvdata *cons_data; > + struct platform_device_info pdevinfo; > + struct property_entry properties[2]; > + struct platform_device *prvd, *cons; > + bool bound = false; > + int ret; > + > + ret = kunit_platform_driver_register(test, &gpio_test_provider_driver); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + ret = kunit_platform_driver_register(test, &gpio_unbind_consumer_driver); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + pdevinfo = (struct platform_device_info){ > + .name = GPIO_TEST_PROVIDER, > + .id = PLATFORM_DEVID_NONE, > + .swnode = &gpio_test_provider_swnode, > + }; > + > + prvd = kunit_platform_device_register_full(test, &pdevinfo); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd); > + > + properties[0] = PROPERTY_ENTRY_GPIO("foo-gpios", > + &gpio_test_provider_swnode, > + 0, GPIO_ACTIVE_HIGH); > + properties[1] = (struct property_entry){ }; > + > + pdevinfo = (struct platform_device_info){ > + .name = GPIO_UNBIND_TEST_CONSUMER, > + .id = PLATFORM_DEVID_NONE, > + .properties = properties, > + }; > + > + cons = 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 = device_is_bound(&cons->dev); > + > + KUNIT_ASSERT_TRUE(test, bound); > + > + kunit_platform_device_unregister(test, prvd); > + > + ret = blocking_notifier_call_chain(&gpio_unbind_notifier, 0, &cons->dev); > + KUNIT_ASSERT_EQ(test, ret, NOTIFY_OK); > + > + scoped_guard(device, &cons->dev) { > + cons_data = platform_get_drvdata(cons); > + ret = cons_data->set_retval; > + } > + > + KUNIT_ASSERT_EQ(test, ret, -ENODEV); > +} > + > +static struct kunit_case gpio_unbind_with_consumers_tests[] = { > + KUNIT_CASE(gpio_unbind_with_consumers), > + { } > +}; > + > +static struct kunit_suite gpio_unbind_with_consumers_test_suite = { > + .name = "gpio-unbind-with-consumers", > + .test_cases = gpio_unbind_with_consumers_tests, > +}; > + > +kunit_test_suites( > + &gpio_swnode_lookup_test_suite, > + &gpio_unbind_with_consumers_test_suite, > +); > + > +MODULE_DESCRIPTION("Test module for the GPIO subsystem"); > +MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>"); > +MODULE_LICENSE("GPL"); > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 3/3] gpio: add kunit test cases for the GPIO subsystem 2026-05-26 8:58 ` David Gow @ 2026-05-26 9:19 ` Bartosz Golaszewski 0 siblings, 0 replies; 10+ messages in thread From: Bartosz Golaszewski @ 2026-05-26 9:19 UTC (permalink / raw) To: David Gow Cc: Bartosz Golaszewski, Brendan Higgins, Rae Moar, Linus Walleij, linux-kselftest, kunit-dev, linux-kernel, linux-gpio On Tue, May 26, 2026 at 11:07 AM David Gow <david@davidgow.net> wrote: > > Le 22/05/2026 à 9:42 PM, Bartosz Golaszewski a écrit : > > Add a module containing kunit test cases for GPIO core. The idea is to > > use it to test functionalities that can't easily be tested from > > user-space with kernel selftests or GPIO character device test suites > > provided by the libgpiod package. > > > > For now add test cases that verify software node based lookup and ensure > > that a GPIO provider unbinding with active consumers does not cause a > > crash. > > > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> > > --- > > This is a nice looking test, thanks. > > Reviewed-by: David Gow <david@davidgow.net> > > Happy for this (and the previous two patches) to go in via gpio, but if > you'd rather them go in via the KUnit tree, let me know. > I'll take it through the GPIO tree, thanks. > Cheers, > -- David > > > drivers/gpio/Kconfig | 8 + > > drivers/gpio/Makefile | 1 + > > drivers/gpio/gpiolib-kunit.c | 358 +++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 367 insertions(+) > > > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > > index 00fcab5d09a4294ed778cea78af5867a0f6e481b..0306005fb7d65ae85905e967b9065fd74db753db 100644 > > --- a/drivers/gpio/Kconfig > > +++ b/drivers/gpio/Kconfig > > @@ -102,6 +102,14 @@ config GPIO_CDEV_V1 > > This ABI version is deprecated. > > Please use the latest ABI for new developments. > > > > +config GPIO_KUNIT > > + tristate "Build GPIO Kunit test cases" > > + depends on KUNIT > > + default KUNIT_ALL_TESTS > > + help > > + Say Y here to build the module containing Kunit test cases verifying > > + the functionality of the GPIO subsystem. > > + > > > FYI: If you want to add CONFIG_GPIOLIB=y to > tools/testing/kunit/configs/all_tests.config, we can enable these tests > when the --alltests flag is passed to kunit.py. > Sure, I'll send a separate patch for this. Bart ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 0/3] gpio: add kunit tests for GPIO core 2026-05-22 13:42 [PATCH v3 0/3] gpio: add kunit tests for GPIO core Bartosz Golaszewski ` (2 preceding siblings ...) 2026-05-22 13:42 ` [PATCH v3 3/3] gpio: add kunit test cases for the GPIO subsystem Bartosz Golaszewski @ 2026-05-25 13:33 ` Linus Walleij 2026-05-26 9:20 ` Bartosz Golaszewski 4 siblings, 0 replies; 10+ messages in thread From: Linus Walleij @ 2026-05-25 13:33 UTC (permalink / raw) To: Bartosz Golaszewski Cc: Brendan Higgins, David Gow, Rae Moar, Bartosz Golaszewski, linux-kselftest, kunit-dev, linux-kernel, linux-gpio On Fri, May 22, 2026 at 3:42 PM Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> wrote: > This series adds a first batch of kunit tests for GPIO core. I intend to > gradually add more coverage for functionalities that can't really be > tested from user-space with the existing kernel selftests or libgpiod > tests. > > Merging strategy: with an Ack from kunit maintainers, this can go > through the GPIO tree for v7.2. > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> The series: Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 0/3] gpio: add kunit tests for GPIO core 2026-05-22 13:42 [PATCH v3 0/3] gpio: add kunit tests for GPIO core Bartosz Golaszewski ` (3 preceding siblings ...) 2026-05-25 13:33 ` [PATCH v3 0/3] gpio: add kunit tests for GPIO core Linus Walleij @ 2026-05-26 9:20 ` Bartosz Golaszewski 4 siblings, 0 replies; 10+ messages in thread From: Bartosz Golaszewski @ 2026-05-26 9:20 UTC (permalink / raw) To: Brendan Higgins, David Gow, Rae Moar, Linus Walleij, Bartosz Golaszewski, Bartosz Golaszewski Cc: linux-kselftest, kunit-dev, linux-kernel, linux-gpio On Fri, 22 May 2026 15:42:15 +0200, Bartosz Golaszewski wrote: > This series adds a first batch of kunit tests for GPIO core. I intend to > gradually add more coverage for functionalities that can't really be > tested from user-space with the existing kernel selftests or libgpiod > tests. > > Merging strategy: with an Ack from kunit maintainers, this can go > through the GPIO tree for v7.2. > > [...] Applied, thanks! [1/3] kunit: provide kunit_platform_device_register_full() https://git.kernel.org/brgl/c/4c237ab773c93959aa2a7750f9dba772b5f1baee [2/3] kunit: provide kunit_platform_device_unregister() https://git.kernel.org/brgl/c/136569e6bc7b2d62e6777ef47caf0a417d70bf4a [3/3] gpio: add kunit test cases for the GPIO subsystem https://git.kernel.org/brgl/c/a6d2a3b403cbcbcdb3ffdb63e52ac090c1003d05 Best regards, -- Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-05-26 9:20 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-05-22 13:42 [PATCH v3 0/3] gpio: add kunit tests for GPIO core Bartosz Golaszewski 2026-05-22 13:42 ` [PATCH v3 1/3] kunit: provide kunit_platform_device_register_full() Bartosz Golaszewski 2026-05-26 8:58 ` David Gow 2026-05-22 13:42 ` [PATCH v3 2/3] kunit: provide kunit_platform_device_unregister() Bartosz Golaszewski 2026-05-26 8:58 ` David Gow 2026-05-22 13:42 ` [PATCH v3 3/3] gpio: add kunit test cases for the GPIO subsystem Bartosz Golaszewski 2026-05-26 8:58 ` David Gow 2026-05-26 9:19 ` Bartosz Golaszewski 2026-05-25 13:33 ` [PATCH v3 0/3] gpio: add kunit tests for GPIO core Linus Walleij 2026-05-26 9:20 ` Bartosz Golaszewski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®