@@ -21,6 +21,9 @@ struct dev_data_hfxo {
2121	onoff_notify_fn  notify ;
2222	struct  k_timer  timer ;
2323	sys_snode_t  hfxo_node ;
24+ #if  defined(CONFIG_ZERO_LATENCY_IRQS )
25+ 	uint16_t  request_count ;
26+ #endif  /* CONFIG_ZERO_LATENCY_IRQS */ 
2427};
2528
2629struct  dev_config_hfxo  {
@@ -29,6 +32,31 @@ struct dev_config_hfxo {
2932	k_timeout_t  start_up_time ;
3033};
3134
35+ #if  defined(CONFIG_ZERO_LATENCY_IRQS )
36+ static  uint32_t  full_irq_lock (void )
37+ {
38+ 	uint32_t  mcu_critical_state ;
39+ 
40+ 	if  (IS_ENABLED (CONFIG_ZERO_LATENCY_IRQS )) {
41+ 		mcu_critical_state  =  __get_PRIMASK ();
42+ 		__disable_irq ();
43+ 	} else  {
44+ 		mcu_critical_state  =  irq_lock ();
45+ 	}
46+ 
47+ 	return  mcu_critical_state ;
48+ }
49+ 
50+ static  void  full_irq_unlock (uint32_t  mcu_critical_state )
51+ {
52+ 	if  (IS_ENABLED (CONFIG_ZERO_LATENCY_IRQS )) {
53+ 		__set_PRIMASK (mcu_critical_state );
54+ 	} else  {
55+ 		irq_unlock (mcu_critical_state );
56+ 	}
57+ }
58+ #endif  /* CONFIG_ZERO_LATENCY_IRQS */ 
59+ 
3260static  void  hfxo_start_up_timer_handler (struct  k_timer  * timer )
3361{
3462	struct  dev_data_hfxo  * dev_data  = 
@@ -48,6 +76,40 @@ static void hfxo_start_up_timer_handler(struct k_timer *timer)
4876	}
4977}
5078
79+ static  void  start_hfxo (struct  dev_data_hfxo  * dev_data )
80+ {
81+ 	nrf_lrcconf_event_clear (NRF_LRCCONF010 , NRF_LRCCONF_EVENT_HFXOSTARTED );
82+ 	soc_lrcconf_poweron_request (& dev_data -> hfxo_node , NRF_LRCCONF_POWER_MAIN );
83+ 	nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_REQHFXO );
84+ }
85+ 
86+ static  void  request_hfxo (struct  dev_data_hfxo  * dev_data )
87+ {
88+ #if  defined(CONFIG_ZERO_LATENCY_IRQS )
89+ 	unsigned int   key ;
90+ 
91+ 	key  =  full_irq_lock ();
92+ 	if  (dev_data -> request_count  ==  0 ) {
93+ 		start_hfxo (dev_data );
94+ 	}
95+ 
96+ 	dev_data -> request_count ++ ;
97+ 	full_irq_unlock (key );
98+ #else 
99+ 	start_hfxo (dev_data );
100+ #endif  /* CONFIG_ZERO_LATENCY_IRQS */ 
101+ }
102+ 
103+ #if  IS_ENABLED (CONFIG_ZERO_LATENCY_IRQS )
104+ void  nrf_clock_control_hfxo_request (void )
105+ {
106+ 	const  struct  device  * dev  =  DEVICE_DT_INST_GET (0 );
107+ 	struct  dev_data_hfxo  * dev_data  =  dev -> data ;
108+ 
109+ 	request_hfxo (dev_data );
110+ }
111+ #endif  /* CONFIG_ZERO_LATENCY_IRQS */ 
112+ 
51113static  void  onoff_start_hfxo (struct  onoff_manager  * mgr , onoff_notify_fn  notify )
52114{
53115	struct  dev_data_hfxo  * dev_data  = 
@@ -56,10 +118,7 @@ static void onoff_start_hfxo(struct onoff_manager *mgr, onoff_notify_fn notify)
56118	const  struct  dev_config_hfxo  * dev_config  =  dev -> config ;
57119
58120	dev_data -> notify  =  notify ;
59- 
60- 	nrf_lrcconf_event_clear (NRF_LRCCONF010 , NRF_LRCCONF_EVENT_HFXOSTARTED );
61- 	soc_lrcconf_poweron_request (& dev_data -> hfxo_node , NRF_LRCCONF_POWER_MAIN );
62- 	nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_REQHFXO );
121+ 	request_hfxo (dev_data );
63122
64123	/* Due to a hardware issue, the HFXOSTARTED event is currently 
65124	 * unreliable. Hence the timer is used to simply wait the expected 
@@ -68,13 +127,53 @@ static void onoff_start_hfxo(struct onoff_manager *mgr, onoff_notify_fn notify)
68127	k_timer_start (& dev_data -> timer , dev_config -> start_up_time , K_NO_WAIT );
69128}
70129
130+ static  void  stop_hfxo (struct  dev_data_hfxo  * dev_data )
131+ {
132+ 	nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_STOPREQHFXO );
133+ 	soc_lrcconf_poweron_release (& dev_data -> hfxo_node , NRF_LRCCONF_POWER_MAIN );
134+ }
135+ 
136+ static  void  release_hfxo (struct  dev_data_hfxo  * dev_data )
137+ {
138+ #if  IS_ENABLED (CONFIG_ZERO_LATENCY_IRQS )
139+ 	unsigned int   key ;
140+ 
141+ 	key  =  full_irq_lock ();
142+ 	if  (dev_data -> request_count  <  1 ) {
143+ 		full_irq_unlock (key );
144+ 		/* Misuse of the API, release without request? */ 
145+ 		__ASSERT_NO_MSG (false);
146+ 		/* In case asserts are disabled early return due to no requests pending */ 
147+ 		return ;
148+ 	}
149+ 
150+ 	dev_data -> request_count -- ;
151+ 	if  (dev_data -> request_count  <  1 ) {
152+ 		stop_hfxo (dev_data );
153+ 	}
154+ 
155+ 	full_irq_unlock (key );
156+ #else 
157+ 	stop_hfxo (dev_data );
158+ #endif  /* CONFIG_ZERO_LATENCY_IRQS */ 
159+ }
160+ 
161+ #if  IS_ENABLED (CONFIG_ZERO_LATENCY_IRQS )
162+ void  nrf_clock_control_hfxo_release (void )
163+ {
164+ 	const  struct  device  * dev  =  DEVICE_DT_INST_GET (0 );
165+ 	struct  dev_data_hfxo  * dev_data  =  dev -> data ;
166+ 
167+ 	release_hfxo (dev_data );
168+ }
169+ #endif  /* IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) */ 
170+ 
71171static  void  onoff_stop_hfxo (struct  onoff_manager  * mgr , onoff_notify_fn  notify )
72172{
73173	struct  dev_data_hfxo  * dev_data  = 
74174		CONTAINER_OF (mgr , struct  dev_data_hfxo , mgr );
75175
76- 	nrf_lrcconf_task_trigger (NRF_LRCCONF010 , NRF_LRCCONF_TASK_STOPREQHFXO );
77- 	soc_lrcconf_poweron_release (& dev_data -> hfxo_node , NRF_LRCCONF_POWER_MAIN );
176+ 	release_hfxo (dev_data );
78177	notify (mgr , 0 );
79178}
80179
0 commit comments