1313#include <zephyr/device.h>
1414#include <zephyr/pm/state.h>
1515#include <zephyr/sys/slist.h>
16+ #include <zephyr/sys/onoff.h>
1617#include <zephyr/toolchain.h>
1718
1819#ifdef __cplusplus
@@ -27,37 +28,29 @@ extern "C" {
2728 */
2829
2930/**
30- * @brief Callback to notify when maximum latency changes.
31- *
32- * @param latency New maximum latency. Positive value represents latency in
33- * microseconds. SYS_FOREVER_US value lifts the latency constraint. Other values
34- * are forbidden.
35- */
36- typedef void (* pm_policy_latency_changed_cb_t )(int32_t latency );
37-
38- /**
39- * @brief Latency change subscription.
31+ * @brief Latency request.
4032 *
4133 * @note All fields in this structure are meant for private usage.
4234 */
43- struct pm_policy_latency_subscription {
35+ struct pm_policy_latency_request {
4436 /** @cond INTERNAL_HIDDEN */
4537 sys_snode_t node ;
46- pm_policy_latency_changed_cb_t cb ;
38+ uint32_t value_us ;
39+ struct onoff_client cli ;
40+ void * internal ;
41+ uint32_t flags ;
4742 /** @endcond */
4843};
4944
5045/**
51- * @brief Latency request .
46+ * @brief Callback to notify when maximum latency changes .
5247 *
53- * @note All fields in this structure are meant for private usage.
48+ * @param latency New maximum latency. Positive value represents latency in
49+ * microseconds. SYS_FOREVER_US value lifts the latency constraint. Other values
50+ * are forbidden.
5451 */
55- struct pm_policy_latency_request {
56- /** @cond INTERNAL_HIDDEN */
57- sys_snode_t node ;
58- uint32_t value_us ;
59- /** @endcond */
60- };
52+ typedef void (* pm_policy_latency_changed_cb_t )(struct pm_policy_latency_request * req ,
53+ int32_t latency );
6154
6255/**
6356 * @brief Event.
@@ -275,63 +268,140 @@ static inline int32_t pm_policy_next_event_ticks(void)
275268 * The system will not enter any power state that would make the system to
276269 * exceed the given latency value.
277270 *
271+ * If immediate control manager is provided request may trigger an action asynchronous action
272+ * to reconfigure the system runtime to fullfil requested latency. @p req contains an
273+ * asynchronous notification field that must be initialize prior to the call to get the
274+ * notification.
275+ *
278276 * @param req Latency request.
279277 * @param value_us Maximum allowed latency in microseconds.
278+ *
279+ * @retval 0 if request is applied.
280+ * @retval 1 if request required immediate action that is not completed. Configured completion
281+ * notification will inform about completion.
282+ * @retval -EIO immediate action returned error.
283+ */
284+ int pm_policy_latency_request_add (struct pm_policy_latency_request * req , uint32_t value_us );
285+
286+ /**
287+ * @brief Synchronously add a new latency requirement.
288+ *
289+ * If immediate control manager is not used then it is an equivalent of
290+ * @ref pm_policy_latency_request_add. If immediate control manager is used then context
291+ * blocks until request is completed. It can only be called from the thread context.
292+ * Asynchronous notification field in the @p req is configured and used internally.
293+ *
294+ * @retval 0 if request required immediate action that is not completed. Configured completion
295+ * notification will inform about completion.
296+ * @retval -EIO immediate action returned error.
280297 */
281- void pm_policy_latency_request_add (struct pm_policy_latency_request * req ,
282- uint32_t value_us );
298+ int pm_policy_latency_request_add_sync (struct pm_policy_latency_request * req , uint32_t value_us );
283299
284300/**
285301 * @brief Update a latency requirement.
286302 *
287303 * @param req Latency request.
288304 * @param value_us New maximum allowed latency in microseconds.
305+ *
306+ * @retval 0 if request is applied.
307+ * @retval 1 if request required immediate action that is not completed. Configured completion
308+ * notification will inform about completion.
309+ * @retval -EIO immediate action returned error.
310+ */
311+ int pm_policy_latency_request_update (struct pm_policy_latency_request * req , uint32_t value_us );
312+
313+ /**
314+ * @brief Synchronously update a latency requirement.
315+ *
316+ * If immediate control manager is not used then it is an equivalent of
317+ * @ref pm_policy_latency_request_update. If immediate control manager is used then context
318+ * blocks until request is completed. It can only be called from the thread context.
319+ * Asynchronous notification field in the @p req is configured and used internally.
320+ *
321+ * @retval 0 if request required immediate action that is not completed. Configured completion
322+ * notification will inform about completion.
323+ * @retval -EIO immediate action returned error.
289324 */
290- void pm_policy_latency_request_update (struct pm_policy_latency_request * req ,
291- uint32_t value_us );
325+ int pm_policy_latency_request_update_sync (struct pm_policy_latency_request * req , uint32_t value_us );
292326
293327/**
294328 * @brief Remove a latency requirement.
295329 *
296330 * @param req Latency request.
331+ *
332+ * @retval 0 if request removed successfully.
333+ * @retval -EALREADY if request is not active and cannot be removed.
334+ * @retval -EIO immediate action returned error.
335+ */
336+ int pm_policy_latency_request_remove (struct pm_policy_latency_request * req );
337+
338+ /** @brief Immediate action manager for single threshold.
339+ *
340+ * If there is only a single threshold that triggers an action then @ref onoff_manager
341+ * can handle that. Structure must be persistent.
297342 */
298- void pm_policy_latency_request_remove (struct pm_policy_latency_request * req );
343+ struct pm_policy_latency_immediate_binary {
344+ /** Onoff manager. */
345+ struct onoff_manager * mgr ;
346+ /** Latency threshold. Value below threshold trigger 'on' action. */
347+ int32_t thr ;
348+ };
349+
350+ struct pm_policy_latency_immediate_ctrl {
351+ /** Indication that onoff manager is used. In future gradual manager might
352+ * also be supported.
353+ */
354+ bool onoff ;
355+ /** Pointer to the manager which controls immediate action. */
356+ union {
357+ struct pm_policy_latency_immediate_binary * bin_mgr ;
358+ void * mgr ;
359+ };
360+ };
299361
300362/**
301363 * @brief Subscribe to maximum latency changes.
302364 *
303365 * @param req Subscription request.
304366 * @param cb Callback function (NULL to disable).
305367 */
306- void pm_policy_latency_changed_subscribe (struct pm_policy_latency_subscription * req ,
307- pm_policy_latency_changed_cb_t cb );
368+ int pm_policy_latency_immediate_ctrl_add (struct pm_policy_latency_immediate_ctrl * mgr );
308369
309370/**
310371 * @brief Unsubscribe to maximum latency changes.
311372 *
312373 * @param req Subscription request.
313374 */
314- void pm_policy_latency_changed_unsubscribe (struct pm_policy_latency_subscription * req );
315375#else
316- static inline void pm_policy_latency_request_add (
376+ static inline int pm_policy_latency_request_add (
317377 struct pm_policy_latency_request * req , uint32_t value_us )
318378{
319379 ARG_UNUSED (req );
320380 ARG_UNUSED (value_us );
381+ return 0 ;
321382}
322383
323- static inline void pm_policy_latency_request_update (
384+ static inline int pm_policy_latency_request_update (
324385 struct pm_policy_latency_request * req , uint32_t value_us )
325386{
326387 ARG_UNUSED (req );
327388 ARG_UNUSED (value_us );
389+ return 0 ;
328390}
329391
330- static inline void pm_policy_latency_request_remove (
392+ static inline int pm_policy_latency_request_remove (
331393 struct pm_policy_latency_request * req )
332394{
333395 ARG_UNUSED (req );
396+ return 0 ;
334397}
398+
399+ static inline int pm_policy_latency_immediate_ctrl_add (struct pm_policy_latency_immediate_ctrl * mgr )
400+ {
401+ ARG_UNUSED (mgr );
402+ return 0 ;
403+ }
404+
335405#endif /* CONFIG_PM CONFIG_PM_POLICY_LATENCY_STANDALONE */
336406
337407/**
0 commit comments