blob: 8bc7789fa4b0688c1913367be680e165a311c256 [file] [log] [blame]
/*
* Copyright (c) 2022, Commonwealth Scientific and Industrial Research
* Organisation (CSIRO) ABN 41 687 119 230.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
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), "");
TC_PRINT("Cycling: %s\n", reg_1->name);
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");
}
ZTEST_SUITE(device_power_domain, NULL, NULL, NULL, NULL, NULL);