From 217d03411df5197d7bf9f7ff0c60b2cedba53d33 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Thu, 22 Sep 2022 20:59:20 +0800 Subject: [PATCH] power: reset: reboot-mode: Don't miss panic reboot mode pre_restart will rewrite reboot mode with normal mode when panic. Fixes: c0b196cd5b85 ("power: reset: reboot-mode: Register callback for kernel pre restart") Signed-off-by: Tao Huang Change-Id: I8ad03b8f699b9c1a544a46bbdb60d118381d8356 --- drivers/power/reset/reboot-mode.c | 21 +++++++++++++++++++-- include/linux/reboot-mode.h | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index feaaa80caa9f..b0bb534f241e 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c @@ -51,6 +51,8 @@ static int get_reboot_mode_magic(struct reboot_mode_driver *reboot, return magic; } +static int last_magic; + static void reboot_mode_write(struct reboot_mode_driver *reboot, const void *cmd) { @@ -59,8 +61,10 @@ static void reboot_mode_write(struct reboot_mode_driver *reboot, magic = get_reboot_mode_magic(reboot, cmd); if (!magic) magic = get_reboot_mode_magic(reboot, NULL); - if (magic) + if (magic) { reboot->write(reboot, magic); + last_magic = magic; + } } static int reboot_mode_notify(struct notifier_block *this, @@ -74,6 +78,18 @@ static int reboot_mode_notify(struct notifier_block *this, return NOTIFY_DONE; } +static int reboot_mode_pre_restart_notify(struct notifier_block *this, + unsigned long mode, void *cmd) +{ + struct reboot_mode_driver *reboot; + + reboot = container_of(this, struct reboot_mode_driver, pre_restart_notifier); + if (cmd || !last_magic) + reboot_mode_write(reboot, cmd); + + return NOTIFY_DONE; +} + static int reboot_mode_panic_notify(struct notifier_block *this, unsigned long ev, void *ptr) { @@ -151,9 +167,10 @@ int reboot_mode_register(struct reboot_mode_driver *reboot) boot_mode_parse(reboot); reboot->reboot_notifier.notifier_call = reboot_mode_notify; + reboot->pre_restart_notifier.notifier_call = reboot_mode_pre_restart_notify; reboot->panic_notifier.notifier_call = reboot_mode_panic_notify; register_reboot_notifier(&reboot->reboot_notifier); - register_pre_restart_handler(&reboot->reboot_notifier); + register_pre_restart_handler(&reboot->pre_restart_notifier); atomic_notifier_chain_register(&panic_notifier_list, &reboot->panic_notifier); ret = sysfs_create_file(kernel_kobj, &kobj_boot_mode.attr); diff --git a/include/linux/reboot-mode.h b/include/linux/reboot-mode.h index a7aa69d004c4..250147abb6f3 100644 --- a/include/linux/reboot-mode.h +++ b/include/linux/reboot-mode.h @@ -8,6 +8,7 @@ struct reboot_mode_driver { int (*write)(struct reboot_mode_driver *reboot, unsigned int magic); int (*read)(struct reboot_mode_driver *reboot); struct notifier_block reboot_notifier; + struct notifier_block pre_restart_notifier; struct notifier_block panic_notifier; };