On Wed, Oct 27, 2021 at 11:18 PM Dmitry Osipenko <digetx@xxxxxxxxx> wrote:
SoC platforms often have multiple options of how to perform system's power-off and restart operations. Meanwhile today's kernel is limited to a single option. Add combined power-off+restart handler call chain API, which is inspired by the restart API. The new API provides both power-off and restart functionality. The old pm_power_off method will be kept around till all users are converted to the new API. Current restart API will be replaced by the new unified API since new API is its superset. The restart functionality of the power-handler API is built upon the existing restart-notifier APIs. In order to ease conversion to the new API, convenient helpers are added for the common use-cases. They will reduce amount of boilerplate code and remove global variables. These helpers preserve old behaviour for cases where only one power-off handler is executed, this is what existing drivers want, and thus, they could be easily converted to the new API. Users of the new API should explicitly enable power-off chaining by setting corresponding flag of the power_handler structure. Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx> --- include/linux/reboot.h | 176 +++++++++++- kernel/power/hibernate.c | 2 +- kernel/reboot.c | 601 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 768 insertions(+), 11 deletions(-) diff --git a/include/linux/reboot.h b/include/linux/reboot.h index b7fa25726323..0ec835338c27 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -8,10 +8,16 @@ struct device; -#define SYS_DOWN 0x0001 /* Notify of system down */ -#define SYS_RESTART SYS_DOWN -#define SYS_HALT 0x0002 /* Notify of system halt */ -#define SYS_POWER_OFF 0x0003 /* Notify of system power off */ +enum reboot_prepare_mode { + SYS_DOWN = 1, /* Notify of system down */ + SYS_RESTART = SYS_DOWN, + SYS_HALT, /* Notify of system halt */ + SYS_POWER_OFF, /* Notify of system power off */ +}; + +#define RESTART_PRIO_RESERVED 0 +#define RESTART_PRIO_DEFAULT 128 +#define RESTART_PRIO_HIGH 192 enum reboot_mode { REBOOT_UNDEFINED = -1, @@ -49,6 +55,167 @@ int register_restart_handler(struct notifier_block *); int unregister_restart_handler(struct notifier_block *); void do_kernel_restart(char *cmd); +/* + * Unified poweroff + restart API. + */ + +#define POWEROFF_PRIO_RESERVED 0 +#define POWEROFF_PRIO_PLATFORM 1 +#define POWEROFF_PRIO_DEFAULT 128 +#define POWEROFF_PRIO_HIGH 192 +#define POWEROFF_PRIO_FIRMWARE 224 + +enum poweroff_mode { + POWEROFF_NORMAL = 0, + POWEROFF_PREPARE, +}; + +struct power_off_data { + void *cb_data; +}; + +struct power_off_prep_data { + void *cb_data; +}; + +struct restart_data { + void *cb_data; + const char *cmd; + enum reboot_mode mode; +}; + +struct reboot_prep_data { + void *cb_data; + const char *cmd; + enum reboot_prepare_mode mode; +}; + +struct power_handler_private_data { + struct notifier_block reboot_prep_nb; + struct notifier_block power_off_nb; + struct notifier_block restart_nb; + void (*trivial_power_off_cb)(void); + void (*simple_power_off_cb)(void *data); + void *simple_power_off_cb_data; + bool registered; +}; + +/** + * struct power_handler - Machine power-off + restart handler + * + * Describes power-off and restart handlers which are invoked by kernel + * to power off or restart this machine. Supports prioritized chaining for + * both restart and power-off handlers. Callback's priority must be unique. + * Intended to be used by device drivers that are responsible for restarting + * and powering off hardware which kernel is running on. + * + * Struct power_handler can be static. Members of this structure must not be + * altered while handler is registered. + * + * Fill the structure members and pass it to register_power_handler(). + */ +struct power_handler {
The name of this structure is too generic IMV. There are many things that it might apply to in principle. What about calling power_off_handler or sys_off_handler as it need not be about power at all?