1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <soc_lrcconf.h>
8 #include <zephyr/kernel.h>
9 
10 static struct k_spinlock lock;
11 static sys_slist_t poweron_main_list;
12 static sys_slist_t poweron_active_list;
13 
soc_lrcconf_poweron_request(sys_snode_t * node,nrf_lrcconf_power_domain_mask_t domain)14 void soc_lrcconf_poweron_request(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain)
15 {
16 	__ASSERT(is_power_of_two(domain), "Only one bit can be set for the domain parameter");
17 
18 	sys_slist_t *poweron_list;
19 
20 	if (domain == NRF_LRCCONF_POWER_MAIN) {
21 		poweron_list = &poweron_main_list;
22 	} else if (domain == NRF_LRCCONF_POWER_DOMAIN_0) {
23 		poweron_list = &poweron_active_list;
24 	} else {
25 		return;
26 	}
27 
28 	K_SPINLOCK(&lock) {
29 		if (sys_slist_len(poweron_list) == 0) {
30 			nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, domain, true);
31 		}
32 
33 		sys_slist_find_and_remove(poweron_list, node);
34 		sys_slist_append(poweron_list, node);
35 	}
36 }
37 
soc_lrcconf_poweron_release(sys_snode_t * node,nrf_lrcconf_power_domain_mask_t domain)38 void soc_lrcconf_poweron_release(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain)
39 {
40 	__ASSERT(is_power_of_two(domain), "Only one bit can be set for the domain parameter");
41 
42 	sys_slist_t *poweron_list;
43 
44 	if (domain == NRF_LRCCONF_POWER_MAIN) {
45 		poweron_list = &poweron_main_list;
46 	} else if (domain == NRF_LRCCONF_POWER_DOMAIN_0) {
47 		poweron_list = &poweron_active_list;
48 	} else {
49 		return;
50 	}
51 
52 	K_SPINLOCK(&lock) {
53 		if (!sys_slist_find_and_remove(poweron_list, node)) {
54 			K_SPINLOCK_BREAK;
55 		}
56 
57 		if (sys_slist_len(poweron_list) > 0) {
58 			K_SPINLOCK_BREAK;
59 		}
60 		nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, domain, false);
61 	}
62 }
63