@@ -43,9 +43,12 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_SLM_START_SLEEP),
4343static struct k_work_delayable indicate_work ;
4444
4545struct k_work_q slm_work_q ;
46+ static atomic_t callback_wakeup_running ;
4647
4748/* Forward declarations */
4849static void indicate_wk (struct k_work * work );
50+ static void power_pin_callback_wakeup (const struct device * dev ,
51+ struct gpio_callback * gpio_callback , uint32_t );
4952
5053NRF_MODEM_LIB_ON_INIT (lwm2m_init_hook , on_modem_lib_init , NULL );
5154NRF_MODEM_LIB_ON_DFU_RES (main_dfu_hook , on_modem_dfu_res , NULL );
@@ -149,19 +152,24 @@ static int configure_power_pin_interrupt(gpio_callback_handler_t handler, gpio_f
149152 return err ;
150153 }
151154
152- LOG_DBG ("Configured interrupt (0x%x) on power pin (%u)." , flags , pin );
155+ LOG_DBG ("Configured interrupt (0x%x) on power pin (%u) with handler (%p)." ,
156+ flags , pin , handler );
153157 return 0 ;
154158}
155159
156- static void power_pin_callback_poweroff ( const struct device * , struct gpio_callback * , uint32_t )
160+ static void slm_enter_sleep_work_fn ( struct k_work * )
157161{
158- LOG_INF ("Power off triggered." );
159162 slm_enter_sleep ();
160163}
161164
162- static void poweroff_interrupt_enabler (struct k_work * )
165+ static void power_pin_callback_poweroff (const struct device * dev ,
166+ struct gpio_callback * gpio_callback , uint32_t )
163167{
164- configure_power_pin_interrupt (power_pin_callback_poweroff , GPIO_INT_EDGE_RISING );
168+ static K_WORK_DEFINE (work , slm_enter_sleep_work_fn ) ;
169+
170+ LOG_INF ("Power off triggered." );
171+ gpio_remove_callback (dev , gpio_callback );
172+ k_work_submit (& work );
165173}
166174
167175#endif /* POWER_PIN_IS_ENABLED */
@@ -237,28 +245,16 @@ static void indicate_stop(void)
237245static void power_pin_callback_enable_poweroff (const struct device * dev ,
238246 struct gpio_callback * gpio_callback , uint32_t )
239247{
240- static K_WORK_DELAYABLE_DEFINE (work , poweroff_interrupt_enabler ) ;
241-
242248 LOG_DBG ("Enabling the poweroff interrupt shortly..." );
243249 gpio_remove_callback (dev , gpio_callback );
244250
245- /* Enable the poweroff interrupt after a small delay
246- * so that it doesn't fire right away (which it does if enabled here).
247- */
248- k_work_schedule (& work , K_MSEC (1 ));
251+ configure_power_pin_interrupt (power_pin_callback_poweroff , GPIO_INT_EDGE_RISING );
249252}
250253
251- static void power_pin_callback_wakeup (const struct device * dev ,
252- struct gpio_callback * gpio_callback , uint32_t )
254+ static void power_pin_callback_wakeup_work_fn (struct k_work * )
253255{
254- static atomic_t callback_running ;
255256 int err ;
256257
257- /* Prevent level triggered interrupt running this multiple times. */
258- if (!atomic_cas (& callback_running , false, true)) {
259- return ;
260- }
261-
262258 LOG_INF ("Resuming from idle." );
263259 if (k_work_delayable_is_pending (& indicate_work )) {
264260 k_work_cancel_delayable (& indicate_work );
@@ -271,17 +267,32 @@ static void power_pin_callback_wakeup(const struct device *dev,
271267 }
272268 err = slm_at_host_power_on ();
273269 if (err ) {
274- atomic_set (& callback_running , false);
275- LOG_ERR ("Failed to power on uart: %d" , err );
270+ LOG_ERR ("Failed to power on uart: %d. Resetting SLM." , err );
271+ gpio_remove_callback (gpio_dev , & gpio_cb );
272+ slm_reset ();
273+ return ;
274+ }
275+
276+ atomic_set (& callback_wakeup_running , false);
277+ }
278+
279+ static void power_pin_callback_wakeup (const struct device * dev ,
280+ struct gpio_callback * gpio_callback , uint32_t )
281+ {
282+ static K_WORK_DEFINE (work , power_pin_callback_wakeup_work_fn ) ;
283+
284+ /* Prevent level triggered interrupt running this multiple times. */
285+ if (!atomic_cas (& callback_wakeup_running , false, true)) {
276286 return ;
277287 }
278288
289+ LOG_INF ("Resuming from idle shortly..." );
279290 gpio_remove_callback (dev , gpio_callback );
280291
281292 /* Enable the poweroff interrupt only when the pin will be back to a nonactive state. */
282293 configure_power_pin_interrupt (power_pin_callback_enable_poweroff , GPIO_INT_EDGE_RISING );
283294
284- atomic_set ( & callback_running , false );
295+ k_work_submit ( & work );
285296}
286297
287298void slm_enter_idle (void )
0 commit comments