Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pm: device: Add power domain get function #81793

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/zephyr/pm/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,16 @@ bool pm_device_wakeup_is_capable(const struct device *dev);
*/
bool pm_device_on_power_domain(const struct device *dev);

/**
* @brief Get the device's power domain.
*
* @param dev Device instance.
*
* @retval pd The device's power domain if on a power domain
* @retval NULL if not on a power domain
*/
const struct device *pm_device_get_power_domain(const struct device *dev);

/**
* @brief Add a device to a power domain.
*
Expand Down
13 changes: 13 additions & 0 deletions subsys/pm/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,19 @@ bool pm_device_on_power_domain(const struct device *dev)
#endif
}

const struct device *pm_device_get_power_domain(const struct device *dev)
{
#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
if (pm_device_on_power_domain(dev) == false) {
return NULL;
}
return dev->pm_base->domain;
#else
ARG_UNUSED(dev);
return NULL;
#endif
}

bool pm_device_is_powered(const struct device *dev)
{
#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
Expand Down
10 changes: 10 additions & 0 deletions tests/subsys/pm/power_domain/no_power_domain.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CONFIG_ZTEST=y
CONFIG_DEVICE_DEPS=y
CONFIG_DEVICE_DEPS_DYNAMIC=y
CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_POWER_DOMAIN=y
CONFIG_PM_DEVICE_POWER_DOMAIN=n
CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC=n
CONFIG_PM_DEVICE_RUNTIME=y
CONFIG_MP_MAX_NUM_CPUS=1
29 changes: 26 additions & 3 deletions tests/subsys/pm/power_domain/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ DEVICE_DEFINE(devc, "devc", NULL, PM_DEVICE_GET(devc),
*
* - get + put multiple devices under a domain
* - notification when domain state changes
* - CONFIG_POWER_DOMAIN is disabled
*/
ZTEST(power_domain_1cpu, test_power_domain_device_runtime)
{
Expand All @@ -122,20 +123,24 @@ ZTEST(power_domain_1cpu, test_power_domain_device_runtime)

devc = DEVICE_GET(devc);

pm_device_init_suspended(domain);
pm_device_init_suspended(deva);
pm_device_init_suspended(devb);
pm_device_init_suspended(devc);

pm_device_runtime_enable(domain);
pm_device_runtime_enable(deva);
pm_device_runtime_enable(devb);
pm_device_runtime_enable(devc);

#ifdef CONFIG_POWER_DOMAIN
pm_device_init_suspended(domain);
pm_device_runtime_enable(domain);

ret = pm_device_power_domain_remove(devc, domain);
zassert_equal(ret, -ENOENT);
zassert_equal(pm_device_get_power_domain(devc), NULL);

ret = pm_device_power_domain_add(devc, domain);
zassert_equal(pm_device_get_power_domain(devc), domain);
zassert_equal(ret, 0);

/* At this point all devices should be SUSPENDED */
Expand Down Expand Up @@ -219,7 +224,12 @@ ZTEST(power_domain_1cpu, test_power_domain_device_runtime)
zassert_equal(testing_domain_off_notitication, 0);

ret = pm_device_power_domain_remove(devc, domain);
zassert_equal(pm_device_get_power_domain(devc), NULL);
zassert_equal(ret, 0);
#else
zassert_equal(pm_device_get_power_domain(devc), NULL);
#endif

}

#define TEST_DOMAIN_BALANCED DT_NODELABEL(test_domain_balanced)
Expand All @@ -240,6 +250,7 @@ DEVICE_DT_DEFINE(TEST_DEV_BALANCED, NULL, PM_DEVICE_DT_GET(TEST_DEV_BALANCED),
*
* - get + put device with a PD while PM is disabled
*/
#ifdef CONFIG_POWER_DOMAIN
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't reduce the testing scope when adding new features.
If you have to disable existing tests when adding a new feature that means something is wrong with the implementation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my initial thought here was some of these tests don't really make sense in the secondary context of the power domain being disabled, so on the second test case where it is disabled, I do not compile in these cases. But they are still included in the base tests. Although I see now that my initial assumption is probably wrong, and that these tests might actually still work with power domain disabled? I'll test and see. And if they don't work, I can look into making whatever changes are needed to fix that.

ZTEST(power_domain_1cpu, test_power_domain_device_balanced)
{
const struct device *balanced_domain = DEVICE_DT_GET(TEST_DOMAIN_BALANCED);
Expand Down Expand Up @@ -278,23 +289,35 @@ ZTEST(power_domain_1cpu, test_power_domain_device_balanced)
pm_device_state_get(balanced_domain, &state);
zassert_equal(state, PM_DEVICE_STATE_ACTIVE);
}
#endif

ZTEST(power_domain_1cpu, test_on_power_domain)
{
zassert_true(device_is_ready(domain), "Device is not ready!");
zassert_true(device_is_ready(deva), "Device is not ready!");
devc = DEVICE_GET(devc);
zassert_true(device_is_ready(devc), "Device is not ready!");
#ifdef CONFIG_POWER_DOMAIN
zassert_true(device_is_ready(domain), "Device is not ready!");

pm_device_power_domain_remove(deva, domain);
zassert_false(pm_device_on_power_domain(deva), "deva is in the power domain.");
zassert_equal(pm_device_get_power_domain(deva), NULL);

pm_device_power_domain_add(deva, domain);
zassert_true(pm_device_on_power_domain(deva), "deva is not in the power domain.");
zassert_equal(pm_device_get_power_domain(deva), domain);

pm_device_power_domain_add(devc, domain);
zassert_true(pm_device_on_power_domain(devc), "devc is not in the power domain.");
zassert_equal(pm_device_get_power_domain(devc), domain);

pm_device_power_domain_remove(devc, domain);
zassert_false(pm_device_on_power_domain(devc), "devc in the power domain.");
zassert_equal(pm_device_get_power_domain(devc), NULL);
#else
zassert_equal(pm_device_get_power_domain(deva), NULL);
zassert_equal(pm_device_get_power_domain(devc), NULL);
#endif
}

ZTEST_SUITE(power_domain_1cpu, NULL, NULL, ztest_simple_1cpu_before,
Expand Down
7 changes: 7 additions & 0 deletions tests/subsys/pm/power_domain/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@ tests:
integration_platforms:
- native_sim
tags: pm
pm.no_power_domain:
platform_allow:
- native_sim
integration_platforms:
- native_sim
tags: pm
extra_args: CONF_FILE=no_power_domain.conf
Loading