diff options
| author | Pranav Sanwal <[email protected]> | 2026-07-30 15:18:17 +0530 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-08-19 08:48:18 -0600 |
| commit | ef019bb9ebce5f3025cd93f2da6d3b586a13293d (patch) | |
| tree | 058870f9084e5fb863161358c32853172f1f5338 | |
| parent | 7b1ae01ed37ae3527422fdf5bd7ac8110e80c288 (diff) | |
test: dm: add sandbox coverage for gpio-delay
gpio-delay had no sandbox coverage, which is how two bugs in it went
unnoticed: gpio_delay_xlate() never propagated the requested index
into the descriptor offset, so every consumer past the first silently
collided with the first consumer's already-claimed offset 0; and the
claimed/name tracking arrays were sized and bounds-checked against a
hardcoded 32 instead of the driver's actual GPIO count. Both are fixed
by a companion series that is a dependency of this patch: applied
without it, this test fails outright, since it directly exercises
both fixes.
Add a test requesting both consumers wired up by gpio-delay-test in
test.dts (gpio_a 9 and 18): a third consumer colliding with an
already-claimed offset must fail with -EBUSY, each consumer's write
must land on its own wrapped GPIO line, and a request past the
wrapped GPIO count must fail with -EINVAL rather than succeed against
a hardcoded bound of 32.
Gated on CONFIG_GPIO_DELAY, since not every sandbox variant that
builds test/dm/gpio.c enables it (sandbox_vpl, sandbox_spl,
sandbox_noinst, sandbox_flattree).
Signed-off-by: Pranav Sanwal <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
| -rw-r--r-- | test/dm/gpio.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/test/dm/gpio.c b/test/dm/gpio.c index e9fa41ce9d4..3d966e0d1a6 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -446,6 +446,75 @@ static int dm_test_gpio_get_dir_flags(struct unit_test_state *uts) } DM_TEST(dm_test_gpio_get_dir_flags, UTF_SCAN_PDATA | UTF_SCAN_FDT); +/* + * Test that gpio-delay correctly routes each consumer to its own wrapped + * real GPIO line. See gpio-delay-test in test.dts, which wraps gpio_a 9 + * and gpio_a 18. + */ +#if IS_ENABLED(CONFIG_GPIO_DELAY) +static int dm_test_gpio_delay(struct unit_test_state *uts) +{ + struct gpio_desc desc0, desc1, desc2, desc3; + struct udevice *dev, *gpio_a; + + ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); + ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio_a)); + ut_asserteq_str("base-gpios", gpio_a->name); + + /* + * Requesting both consumers must succeed. Before the offset was + * propagated in gpio_delay_xlate(), both descriptors came back with + * offset 0, so this second request would fail with -EBUSY as it + * collided with the first consumer's already-claimed offset. + */ + ut_assertok(gpio_request_by_name(dev, "test6-gpios", 0, &desc0, 0)); + ut_assertok(gpio_request_by_name(dev, "test6-gpios", 1, &desc1, 0)); + + ut_asserteq_ptr(desc0.dev, desc1.dev); + ut_asserteq(0, desc0.offset); + ut_asserteq(1, desc1.offset); + + /* + * A third consumer mapped to the same offset as the first must be + * rejected as already requested. + */ + ut_asserteq(-EBUSY, gpio_request_by_name(dev, "test6-gpios", 2, &desc2, + 0)); + + /* + * Drive each consumer to a different level and confirm the write + * lands on its own wrapped real GPIO line, not the other one's. + * gpio_a has no set_value op of its own (it implements set_flags), + * so dm_gpio_set_value() routes through GPIOD_IS_OUT_ACTIVE. + */ + ut_assertok(dm_gpio_set_value(&desc0, 0)); + ut_assertok(dm_gpio_set_value(&desc1, 1)); + ut_asserteq(0, sandbox_gpio_get_flags(gpio_a, 9) & GPIOD_IS_OUT_ACTIVE); + ut_asserteq(GPIOD_IS_OUT_ACTIVE, + sandbox_gpio_get_flags(gpio_a, 18) & GPIOD_IS_OUT_ACTIVE); + + ut_assertok(dm_gpio_set_value(&desc0, 1)); + ut_assertok(dm_gpio_set_value(&desc1, 0)); + ut_asserteq(GPIOD_IS_OUT_ACTIVE, + sandbox_gpio_get_flags(gpio_a, 9) & GPIOD_IS_OUT_ACTIVE); + ut_asserteq(0, sandbox_gpio_get_flags(gpio_a, 18) & GPIOD_IS_OUT_ACTIVE); + + ut_assertok(dm_gpio_free(dev, &desc0)); + ut_assertok(dm_gpio_free(dev, &desc1)); + + /* + * An index beyond the wrapped GPIO count (2 here) must be rejected. + * Before gpio_count was set from the "gpios" property, this bound + * was checked against a hardcoded 32 and would have been let through. + */ + ut_asserteq(-EINVAL, gpio_request_by_name(dev, "test7-gpios", 0, &desc3, + 0)); + + return 0; +} +DM_TEST(dm_test_gpio_delay, UTF_SCAN_PDATA | UTF_SCAN_FDT); +#endif /* CONFIG_GPIO_DELAY */ + /* Test of gpio_get_acpi() */ static int dm_test_gpio_get_acpi(struct unit_test_state *uts) { |
