blob: 29b235d2b5ecac224e48a0959eb92a83933b5152 [file] [log] [blame]
/*
* Copyright (c) 2019, Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(test);
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
static struct onoff_manager *get_mgr(void)
{
return z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
}
static bool clock_is_off(void)
{
const struct device *const clk = DEVICE_DT_GET_ONE(nordic_nrf_clock);
zassert_true(device_is_ready(clk), "Device is not ready");
return clock_control_get_status(clk, CLOCK_CONTROL_NRF_SUBSYS_HF) ==
CLOCK_CONTROL_STATUS_OFF;
}
static void clock_off(void)
{
struct onoff_manager *mgr = get_mgr();
do {
(void)onoff_release(mgr);
} while (!clock_is_off());
}
ZTEST(clock_control_onoff, test_clock_blocking_on)
{
struct onoff_client cli;
struct onoff_manager *mgr = get_mgr();
int err;
clock_off();
sys_notify_init_spinwait(&cli.notify);
err = onoff_request(mgr, &cli);
zassert_true(err >= 0, "");
while (sys_notify_fetch_result(&cli.notify, &err) < 0) {
/* empty */
}
zassert_true(err >= 0, "");
/* clock on, now turn it off */
err = onoff_release(mgr);
zassert_true(err >= 0, "");
}
ZTEST(clock_control_onoff, test_clock_spinwait_release_before_start)
{
struct onoff_client cli;
struct onoff_manager *mgr = get_mgr();
int err;
clock_off();
k_busy_wait(10000);
sys_notify_init_spinwait(&cli.notify);
err = onoff_request(mgr, &cli);
zassert_true(err >= 0, "err: %d", err);
/* Attempt to release while ongoing start. Cannot do that */
err = onoff_cancel_or_release(mgr, &cli);
zassert_true(err >= 0, "err: %d", err);
k_busy_wait(100000);
zassert_true(clock_is_off(), "");
}
static void request_cb(struct onoff_manager *mgr, struct onoff_client *cli,
uint32_t state, int res)
{
int err;
err = onoff_cancel_or_release(mgr, cli);
zassert_true(err >= 0, "err: %d", err);
}
/* Test checks if premature clock release works ok. If clock is released before
* it is started it is the best to do that release from the callback to avoid
* waiting until clock is started in the release context.
*/
ZTEST(clock_control_onoff, test_clock_release_from_callback)
{
struct onoff_client cli;
struct onoff_manager *mgr = get_mgr();
int err;
clock_off();
k_busy_wait(100);
sys_notify_init_callback(&cli.notify, request_cb);
err = onoff_request(mgr, &cli);
zassert_true(err >= 0, "err: %d", err);
k_busy_wait(100000);
/* clock should be turned off in the started callback */
zassert_true(clock_is_off(), "clock should be off");
}
ZTEST_SUITE(clock_control_onoff, NULL, NULL, NULL, NULL, NULL);