1 /* 2 * Copyright (c) 2018 Intel Corporation. 3 * Copyright (c) 2022 Nordic Semiconductor ASA 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #include <stdint.h> 9 10 #include <zephyr/kernel.h> 11 #include <zephyr/pm/policy.h> 12 #include <zephyr/spinlock.h> 13 #include <zephyr/sys_clock.h> 14 #include <zephyr/sys/time_units.h> 15 16 /** Lock to synchronize access to the events list. */ 17 static struct k_spinlock events_lock; 18 /** List of events. */ 19 static sys_slist_t events_list; 20 /** Pointer to Next Event. */ 21 struct pm_policy_event *next_event; 22 update_next_event(void)23static void update_next_event(void) 24 { 25 struct pm_policy_event *evt; 26 27 next_event = NULL; 28 29 SYS_SLIST_FOR_EACH_CONTAINER(&events_list, evt, node) { 30 if (next_event == NULL) { 31 next_event = evt; 32 continue; 33 } 34 35 if (next_event->uptime_ticks <= evt->uptime_ticks) { 36 continue; 37 } 38 39 next_event = evt; 40 } 41 } 42 pm_policy_next_event_ticks(void)43int64_t pm_policy_next_event_ticks(void) 44 { 45 int64_t ticks = -1; 46 47 K_SPINLOCK(&events_lock) { 48 if (next_event == NULL) { 49 K_SPINLOCK_BREAK; 50 } 51 52 ticks = next_event->uptime_ticks - k_uptime_ticks(); 53 54 if (ticks < 0) { 55 ticks = 0; 56 } 57 } 58 59 return ticks; 60 } 61 pm_policy_event_register(struct pm_policy_event * evt,int64_t uptime_ticks)62void pm_policy_event_register(struct pm_policy_event *evt, int64_t uptime_ticks) 63 { 64 K_SPINLOCK(&events_lock) { 65 evt->uptime_ticks = uptime_ticks; 66 sys_slist_append(&events_list, &evt->node); 67 update_next_event(); 68 } 69 } 70 pm_policy_event_update(struct pm_policy_event * evt,int64_t uptime_ticks)71void pm_policy_event_update(struct pm_policy_event *evt, int64_t uptime_ticks) 72 { 73 K_SPINLOCK(&events_lock) { 74 evt->uptime_ticks = uptime_ticks; 75 update_next_event(); 76 } 77 } 78 pm_policy_event_unregister(struct pm_policy_event * evt)79void pm_policy_event_unregister(struct pm_policy_event *evt) 80 { 81 K_SPINLOCK(&events_lock) { 82 (void)sys_slist_find_and_remove(&events_list, &evt->node); 83 update_next_event(); 84 } 85 } 86