From b6bd40f5fad47866d1c7ad65f06ef1d65746b3d8 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Thu, 29 Jul 2021 14:53:30 -0700 Subject: [PATCH] tests: pm: Add device wakeup test Add a test to exercise PM device wakeup API. Signed-off-by: Flavio Ceolin --- .../pm/device_wakeup_api/CMakeLists.txt | 9 ++ .../boards/native_posix.overlay | 11 ++ tests/subsys/pm/device_wakeup_api/prj.conf | 7 ++ tests/subsys/pm/device_wakeup_api/src/main.c | 117 ++++++++++++++++++ .../subsys/pm/device_wakeup_api/testcase.yaml | 4 + 5 files changed, 148 insertions(+) create mode 100644 tests/subsys/pm/device_wakeup_api/CMakeLists.txt create mode 100644 tests/subsys/pm/device_wakeup_api/boards/native_posix.overlay create mode 100644 tests/subsys/pm/device_wakeup_api/prj.conf create mode 100644 tests/subsys/pm/device_wakeup_api/src/main.c create mode 100644 tests/subsys/pm/device_wakeup_api/testcase.yaml diff --git a/tests/subsys/pm/device_wakeup_api/CMakeLists.txt b/tests/subsys/pm/device_wakeup_api/CMakeLists.txt new file mode 100644 index 00000000000..31663a41b1b --- /dev/null +++ b/tests/subsys/pm/device_wakeup_api/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2021 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13.1) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(pm-states-test) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/pm/device_wakeup_api/boards/native_posix.overlay b/tests/subsys/pm/device_wakeup_api/boards/native_posix.overlay new file mode 100644 index 00000000000..97fa7c3c71a --- /dev/null +++ b/tests/subsys/pm/device_wakeup_api/boards/native_posix.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2021 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&gpio0 { + compatible = "zephyr,gpio-emul"; + gpio-controller; + wakeup-source; +}; diff --git a/tests/subsys/pm/device_wakeup_api/prj.conf b/tests/subsys/pm/device_wakeup_api/prj.conf new file mode 100644 index 00000000000..2bb16fddcba --- /dev/null +++ b/tests/subsys/pm/device_wakeup_api/prj.conf @@ -0,0 +1,7 @@ +CONFIG_ZTEST=y +CONFIG_PM_DEVICE=y +CONFIG_PM=y +CONFIG_PM_POLICY_APP=y + +CONFIG_GPIO=y +CONFIG_GPIO_EMUL=y diff --git a/tests/subsys/pm/device_wakeup_api/src/main.c b/tests/subsys/pm/device_wakeup_api/src/main.c new file mode 100644 index 00000000000..ff96c9bf4cc --- /dev/null +++ b/tests/subsys/pm/device_wakeup_api/src/main.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define DEV_NAME DT_NODELABEL(gpio0) + + +static const struct device *dev; +static uint8_t sleep_count; + + +void pm_power_state_set(struct pm_state_info info) +{ + ARG_UNUSED(info); + + enum pm_device_state state; + + switch (sleep_count) { + case 1: + /* Just a sanity check that the system is the right state. + * Devices are suspended before SoC on PM_STATE_SUSPEND_TO_RAM, that is why + * we can check the device state here. + */ + zassert_equal(info.state, PM_STATE_SUSPEND_TO_RAM, "Wrong system state"); + + (void)pm_device_state_get(dev, &state); + zassert_equal(state, PM_DEVICE_STATE_SUSPENDED, "Wrong device state"); + + /* Enable wakeup source. Next time the system is called + * to sleep, this device will still be active. + */ + (void)pm_device_wakeup_enable((struct device *)dev, true); + break; + case 2: + zassert_equal(info.state, PM_STATE_SUSPEND_TO_RAM, "Wrong system state"); + + /* Second time this function is called, the system is asked to standby + * and devices were suspended. + */ + (void)pm_device_state_get(dev, &state); + zassert_equal(state, PM_DEVICE_STATE_ACTIVE, "Wrong device state"); + break; + default: + break; + } +} + +void pm_power_state_exit_post_ops(struct pm_state_info info) +{ + irq_unlock(0); +} + +struct pm_state_info pm_policy_next_state(int32_t ticks) +{ + while (sleep_count < 3) { + sleep_count++; + return (struct pm_state_info){PM_STATE_SUSPEND_TO_RAM, 0, 0, 0}; + } + + return (struct pm_state_info){PM_STATE_ACTIVE, 0, 0, 0}; +} + +void test_wakeup_device_api(void) +{ + bool ret = false; + + dev = DEVICE_DT_GET(DEV_NAME); + zassert_not_null(dev, "Failed to get device"); + + ret = pm_device_wakeup_is_capable(dev); + zassert_true(ret, "Device marked as capable"); + + ret = pm_device_wakeup_enable((struct device *)dev, true); + zassert_true(ret, "Could not enable wakeup source"); + + ret = pm_device_wakeup_is_enabled(dev); + zassert_true(ret, "Wakeup source not enabled"); + + ret = pm_device_wakeup_enable((struct device *)dev, false); + zassert_true(ret, "Could not disable wakeup source"); + + ret = pm_device_wakeup_is_enabled(dev); + zassert_false(ret, "Wakeup source is enabled"); +} + +void test_wakeup_device_system_pm(void) +{ + /* + * Trigger system PM. The policy manager will return + * PM_STATE_SUSPEND_TO_RAM and then the PM subsystem will + * suspend all devices. As gpio is wakeup capability is not + * enabled, the device will be suspended. This will be + * confirmed in pm_power_state_set(). + * + * As the native posix implementation does not properly sleeps, + * the idle thread will call several times the PM subsystem. This + * test workaround this problem keeping track of the calls using + * the sleep_count variable. + */ + k_sleep(K_SECONDS(1)); +} + +void test_main(void) +{ + ztest_test_suite(wakeup_device_test, + ztest_1cpu_unit_test(test_wakeup_device_api), + ztest_1cpu_unit_test(test_wakeup_device_system_pm) + ); + ztest_run_test_suite(wakeup_device_test); +} diff --git a/tests/subsys/pm/device_wakeup_api/testcase.yaml b/tests/subsys/pm/device_wakeup_api/testcase.yaml new file mode 100644 index 00000000000..62cd8dd4b52 --- /dev/null +++ b/tests/subsys/pm/device_wakeup_api/testcase.yaml @@ -0,0 +1,4 @@ +tests: + pm-device-wakeup-api.dts: + tags: power + platform_allow: native_posix