From 9eaf1f8b44381235506f506d64a8d9ec06044bf7 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 22 Jan 2023 11:45:14 +1000 Subject: [PATCH] tests: pm: power domains: test supported device Validate the powered state and transitions for an arbitrary device hanging off a power domain. Signed-off-by: Jordan Yates --- .../pm/device_power_domains/app.overlay | 7 +++ .../dts/bindings/test-device-pm.yaml | 15 +++++ .../subsys/pm/device_power_domains/src/main.c | 59 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 tests/subsys/pm/device_power_domains/dts/bindings/test-device-pm.yaml diff --git a/tests/subsys/pm/device_power_domains/app.overlay b/tests/subsys/pm/device_power_domains/app.overlay index 1b817ec82e7..0d6dfdfbbd0 100644 --- a/tests/subsys/pm/device_power_domains/app.overlay +++ b/tests/subsys/pm/device_power_domains/app.overlay @@ -14,4 +14,11 @@ enable-gpios = <&gpio0 2 0>; power-domain = <&test_reg_0>; }; + + test_dev: test_dev { + compatible = "test-device-pm"; + status = "okay"; + power-domain = <&test_reg_1>; + alternate-domain = <&test_reg_chained>; + }; }; diff --git a/tests/subsys/pm/device_power_domains/dts/bindings/test-device-pm.yaml b/tests/subsys/pm/device_power_domains/dts/bindings/test-device-pm.yaml new file mode 100644 index 00000000000..c67c9377977 --- /dev/null +++ b/tests/subsys/pm/device_power_domains/dts/bindings/test-device-pm.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023, CSIRO +# SPDX-License-Identifier: Apache-2.0 + +include: [base.yaml, pm.yaml] + +description: | + This binding provides resources required to build and run the + tests/subsys/pm/device_power_domains test in Zephyr. + +compatible: "test-device-pm" + +properties: + alternate-domain: + type: phandle + description: Secondary domain the driver uses. diff --git a/tests/subsys/pm/device_power_domains/src/main.c b/tests/subsys/pm/device_power_domains/src/main.c index 20b3383567f..8bc7789fa4b 100644 --- a/tests/subsys/pm/device_power_domains/src/main.c +++ b/tests/subsys/pm/device_power_domains/src/main.c @@ -9,33 +9,61 @@ #include #include +static int dev_init(const struct device *dev) +{ + if (!pm_device_is_powered(dev)) { + pm_device_init_off(dev); + } + return 0; +} + +int dev_pm_control(const struct device *dev, enum pm_device_action action) +{ + ARG_UNUSED(dev); + ARG_UNUSED(action); + + return 0; +} + +PM_DEVICE_DT_DEFINE(DT_NODELABEL(test_dev), dev_pm_control); +DEVICE_DT_DEFINE(DT_NODELABEL(test_dev), dev_init, PM_DEVICE_DT_GET(DT_NODELABEL(test_dev)), + NULL, NULL, POST_KERNEL, 80, NULL); + ZTEST(device_power_domain, test_demo) { const struct device *const reg_0 = DEVICE_DT_GET(DT_NODELABEL(test_reg_0)); const struct device *const reg_1 = DEVICE_DT_GET(DT_NODELABEL(test_reg_1)); const struct device *const reg_chained = DEVICE_DT_GET(DT_NODELABEL(test_reg_chained)); + const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(test_dev)); + enum pm_device_state state; /* Initial power state */ zassert_true(pm_device_is_powered(reg_0), ""); zassert_true(pm_device_is_powered(reg_1), ""); zassert_false(pm_device_is_powered(reg_chained), ""); + zassert_false(pm_device_is_powered(dev), ""); TC_PRINT("Enabling runtime power management on regulators\n"); pm_device_runtime_enable(reg_0); pm_device_runtime_enable(reg_1); pm_device_runtime_enable(reg_chained); + pm_device_runtime_enable(dev); /* State shouldn't have changed */ zassert_true(pm_device_is_powered(reg_0), ""); zassert_true(pm_device_is_powered(reg_1), ""); zassert_false(pm_device_is_powered(reg_chained), ""); + zassert_false(pm_device_is_powered(dev), ""); + pm_device_state_get(dev, &state); + zassert_equal(PM_DEVICE_STATE_OFF, state, ""); TC_PRINT("Cycling: %s\n", reg_0->name); /* reg_chained is powered off reg_0, so it's power state should change */ pm_device_runtime_get(reg_0); zassert_true(pm_device_is_powered(reg_chained), ""); + zassert_false(pm_device_is_powered(dev), ""); pm_device_runtime_put(reg_0); zassert_false(pm_device_is_powered(reg_chained), ""); @@ -43,15 +71,46 @@ ZTEST(device_power_domain, test_demo) pm_device_runtime_get(reg_1); zassert_false(pm_device_is_powered(reg_chained), ""); + zassert_true(pm_device_is_powered(dev), ""); + /* dev is on reg_1, should have automatically moved to suspended */ + pm_device_state_get(dev, &state); + zassert_equal(PM_DEVICE_STATE_SUSPENDED, state, ""); pm_device_runtime_put(reg_1); + pm_device_state_get(dev, &state); + zassert_equal(PM_DEVICE_STATE_OFF, state, ""); TC_PRINT("Cycling: %s\n", reg_chained->name); /* reg_chained should be powered after being requested */ pm_device_runtime_get(reg_chained); zassert_true(pm_device_is_powered(reg_chained), ""); + zassert_false(pm_device_is_powered(dev), ""); + /* dev is not on reg_chained but does reference it, should still be in OFF */ + pm_device_state_get(dev, &state); + zassert_equal(PM_DEVICE_STATE_OFF, state, ""); pm_device_runtime_put(reg_chained); + TC_PRINT("Requesting dev: %s\n", dev->name); + + /* Directly request the supported device */ + pm_device_runtime_get(dev); + zassert_true(pm_device_is_powered(dev), ""); + pm_device_state_get(dev, &state); + zassert_equal(PM_DEVICE_STATE_ACTIVE, state, ""); + pm_device_state_get(reg_1, &state); + zassert_equal(PM_DEVICE_STATE_ACTIVE, state, ""); + pm_device_state_get(reg_chained, &state); + zassert_equal(PM_DEVICE_STATE_OFF, state, ""); + /* Directly release the supported device */ + pm_device_runtime_put(dev); + zassert_false(pm_device_is_powered(dev), ""); + pm_device_state_get(dev, &state); + zassert_equal(PM_DEVICE_STATE_OFF, state, ""); + pm_device_state_get(reg_1, &state); + zassert_equal(PM_DEVICE_STATE_SUSPENDED, state, ""); + pm_device_state_get(reg_chained, &state); + zassert_equal(PM_DEVICE_STATE_OFF, state, ""); + TC_PRINT("DONE\n"); }