From fe0e2dbc6044ffa74b27bfcba335980bc5a6ae64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 11 Dec 2024 09:51:59 +0100 Subject: [PATCH] drivers: clock_control: nrf: Add API for synchronous request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add API for synchronous request for clock attributes. Signed-off-by: Krzysztof Chruściński --- .../clock_control/clock_control_nrf2_common.c | 44 +++++++++++++++++++ .../drivers/clock_control/nrf_clock_control.h | 18 ++++++++ 2 files changed, 62 insertions(+) diff --git a/drivers/clock_control/clock_control_nrf2_common.c b/drivers/clock_control/clock_control_nrf2_common.c index f3b21a5dd1fbe0..7bf8576880ba9a 100644 --- a/drivers/clock_control/clock_control_nrf2_common.c +++ b/drivers/clock_control/clock_control_nrf2_common.c @@ -4,6 +4,7 @@ */ #include "clock_control_nrf2_common.h" +#include #include LOG_MODULE_REGISTER(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); @@ -24,6 +25,13 @@ LOG_MODULE_REGISTER(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); */ STRUCT_CLOCK_CONFIG(generic, ONOFF_CNT_MAX); +/* Structure used for synchronous clock request. */ +struct sync_req { + struct onoff_client cli; + struct k_sem sem; + int res; +}; + static void update_config(struct clock_config_generic *cfg) { atomic_val_t prev_flags = atomic_or(&cfg->flags, FLAG_UPDATE_NEEDED); @@ -159,3 +167,39 @@ int api_nosys_on_off(const struct device *dev, clock_control_subsys_t sys) return -ENOSYS; } + +static void sync_cb(struct onoff_manager *mgr, struct onoff_client *cli, uint32_t state, int res) +{ + struct sync_req *req = CONTAINER_OF(cli, struct sync_req, cli); + + req->res = res; + k_sem_give(&req->sem); +} + +int nrf_clock_control_request_sync(const struct device *dev, + const struct nrf_clock_spec *spec, + k_timeout_t timeout) +{ + struct sync_req req = { + .sem = Z_SEM_INITIALIZER(req.sem, 0, 1) + }; + int err; + + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + sys_notify_init_callback(&req.cli.notify, sync_cb); + + err = nrf_clock_control_request(dev, spec, &req.cli); + if (err < 0) { + return err; + } + + err = k_sem_take(&req.sem, timeout); + if (err < 0) { + return err; + } + + return req.res; +} diff --git a/include/zephyr/drivers/clock_control/nrf_clock_control.h b/include/zephyr/drivers/clock_control/nrf_clock_control.h index 1db5b1242ee82d..2578feffd2b409 100644 --- a/include/zephyr/drivers/clock_control/nrf_clock_control.h +++ b/include/zephyr/drivers/clock_control/nrf_clock_control.h @@ -242,6 +242,24 @@ int nrf_clock_control_request(const struct device *dev, return api->request(dev, spec, cli); } +/** + * @brief Synchronously request a reservation to use a given clock with specified attributes. + * + * Function can only be called from thread context as it blocks until request is completed. + * @see nrf_clock_control_request(). + * + * @param dev pointer to the clock device structure. + * @param spec See nrf_clock_control_request(). + * @param timeout Request timeout. + * + * @retval 0 if request is fulfilled. + * @retval -EWOULDBLOCK if request is called from the interrupt context. + * @retval negative See error codes returned by nrf_clock_control_request(). + */ +int nrf_clock_control_request_sync(const struct device *dev, + const struct nrf_clock_spec *spec, + k_timeout_t timeout); + /** * @brief Release a reserved use of a clock. *