1010#include <soc.h>
1111#include <zephyr/device.h>
1212#include <zephyr/drivers/gpio.h>
13+ #include <zephyr/sys/atomic.h>
1314#include <zephyr/sys/util.h>
15+ #include <zephyr/sys/reboot.h>
1416
1517#include <caf/key_id.h>
1618#include <caf/gpio_pins.h>
@@ -52,6 +54,7 @@ static struct gpio_callback gpio_cb[ARRAY_SIZE(gpio_devs)];
5254static struct k_work_delayable matrix_scan ;
5355static struct k_work_delayable button_pressed ;
5456static enum state state ;
57+ static atomic_t system_power_off = ATOMIC_INIT (false);
5558
5659
5760static void scan_fn (struct k_work * work );
@@ -408,6 +411,14 @@ static void button_pressed_isr(const struct device *gpio_dev,
408411{
409412 int err = 0 ;
410413
414+ if (IS_ENABLED (CONFIG_CAF_BUTTONS_PM_EVENTS ) && atomic_get (& system_power_off )) {
415+ /* Instantly reboot the system to prevent system power off with GPIO
416+ * interrupts disabled.
417+ */
418+ sys_reboot (SYS_REBOOT_WARM );
419+ return ;
420+ }
421+
411422 /* Scanning will be scheduled, switch off pins */
412423 if (set_cols (0 )) {
413424 LOG_ERR ("Cannot control pins" );
@@ -598,6 +609,22 @@ static bool app_event_handler(const struct app_event_header *aeh)
598609 return true;
599610 }
600611
612+ if (IS_ENABLED (CONFIG_CAF_BUTTONS_PM_EVENTS ) &&
613+ is_power_off_event (aeh )) {
614+ (void )atomic_set (& system_power_off , true);
615+
616+ if ((state != STATE_IDLE ) ||
617+ k_work_delayable_is_pending (& button_pressed ) ||
618+ k_work_delayable_is_pending (& matrix_scan )) {
619+ /* Instantly reboot the system to prevent system power off with GPIO
620+ * interrupts disabled.
621+ */
622+ sys_reboot (SYS_REBOOT_WARM );
623+ }
624+
625+ return false;
626+ }
627+
601628 /* If event is unhandled, unsubscribe. */
602629 __ASSERT_NO_MSG (false);
603630
@@ -607,5 +634,6 @@ APP_EVENT_LISTENER(MODULE, app_event_handler);
607634APP_EVENT_SUBSCRIBE (MODULE , module_state_event );
608635#if CONFIG_CAF_BUTTONS_PM_EVENTS
609636APP_EVENT_SUBSCRIBE_EARLY (MODULE , power_down_event );
637+ APP_EVENT_SUBSCRIBE (MODULE , power_off_event );
610638APP_EVENT_SUBSCRIBE (MODULE , wake_up_event );
611639#endif
0 commit comments