From d55dceff371c4080d179fb26e6f175927cc48768 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 16 Apr 2022 14:25:49 +0100 Subject: apps: Add ability to do a clean reboot Allow a clean shutdown to end in either power off or reboot. Add a new event SYS_REBOOT to signal it and sys_reboot() to trigger the event. SYS_REBOOT signals a reboot request and should be listened for alongside SYS_POWEROFF events. Change-Id: I99ba7fb5feed2bb5a0a40a274e8466ad74fe3a43 --- firmware/backlight.c | 1 + firmware/export/powermgmt.h | 9 ++++++++- firmware/kernel/include/queue.h | 1 + firmware/powermgmt.c | 38 ++++++++++++++++++++++++++++++++------ 4 files changed, 42 insertions(+), 7 deletions(-) (limited to 'firmware') diff --git a/firmware/backlight.c b/firmware/backlight.c index 1284db4659..9575ecdc22 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c @@ -668,6 +668,7 @@ void backlight_thread(void) #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */ #endif /* HAVE_BUTTON_LIGHT */ + case SYS_REBOOT: case SYS_POWEROFF: /* Lock backlight on poweroff so it doesn't */ locked = true; /* go off before power is actually cut. */ #if !defined(BOOTLOADER) diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index 3095d2c97b..6ae5ccfd13 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -70,6 +70,12 @@ extern unsigned int power_thread_inputs; #endif /* CONFIG_CHARGING */ +enum shutdown_type +{ + SHUTDOWN_POWER_OFF, + SHUTDOWN_REBOOT, +}; + #if CONFIG_CHARGING == CHARGING_TARGET /* Include target-specific definitions */ #include "powermgmt-target.h" @@ -164,8 +170,9 @@ void handle_auto_poweroff(void); void set_car_adapter_mode(bool setting); void reset_poweroff_timer(void); void cancel_shutdown(void); -void shutdown_hw(void); +void shutdown_hw(enum shutdown_type sd_type); void sys_poweroff(void); +void sys_reboot(void); /* Returns true if the system should force shutdown for some reason - * eg. low battery */ bool query_force_shutdown(void); diff --git a/firmware/kernel/include/queue.h b/firmware/kernel/include/queue.h index 515a7e43a8..6740b88760 100644 --- a/firmware/kernel/include/queue.h +++ b/firmware/kernel/include/queue.h @@ -58,6 +58,7 @@ #define SYS_CHARGER_CONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 1) #define SYS_CHARGER_DISCONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 2) #define SYS_BATTERY_UPDATE MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 3) +#define SYS_REBOOT MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 4) #define SYS_FS_CHANGED MAKE_SYS_EVENT(SYS_EVENT_CLS_FILESYS, 0) #define SYS_HOTSWAP_INSERTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 0) #define SYS_HOTSWAP_EXTRACTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 1) diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 2cafd4b759..c33ad387ae 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -823,7 +823,7 @@ void powermgmt_init(void) } /* Various hardware housekeeping tasks relating to shutting down the player */ -void shutdown_hw(void) +void shutdown_hw(enum shutdown_type sd_type) { charging_algorithm_close(); audio_stop(); @@ -863,7 +863,17 @@ void shutdown_hw(void) eeprom chips are quite slow and might be still writing the last byte. */ sleep(HZ/4); - power_off(); + + switch (sd_type) { + case SHUTDOWN_POWER_OFF: + default: + power_off(); + break; + + case SHUTDOWN_REBOOT: + system_reboot(); + break; + } } void set_poweroff_timeout(int timeout) @@ -878,10 +888,9 @@ void reset_poweroff_timer(void) set_sleep_timer(sleeptimer_duration); } -void sys_poweroff(void) -{ #ifndef BOOTLOADER - logf("sys_poweroff()"); +static void sys_shutdown_common(void) +{ /* If the main thread fails to shut down the system, we will force a power off after an 20 second timeout - 28 seconds if recording */ if (shutdown_timeout == 0) { @@ -899,9 +908,26 @@ void sys_poweroff(void) shutdown_timeout += HZ*20; #endif } +} +#endif /* BOOTLOADER */ +void sys_poweroff(void) +{ +#ifndef BOOTLOADER + logf("sys_poweroff()"); + sys_shutdown_common(); queue_broadcast(SYS_POWEROFF, 0); -#endif /* BOOTLOADER */ +#endif +} + +/* not to be confused with system_reboot... :( */ +void sys_reboot(void) +{ +#ifndef BOOTLOADER + logf("sys_reboot()"); + sys_shutdown_common(); + queue_broadcast(SYS_REBOOT, 0); +#endif } void cancel_shutdown(void) -- cgit v1.2.3