From: Fabio Estevam <festevam@xxxxxxx> Introduce hw_protection_reboot() to trigger an emergency reboot. It is a counterpart of hw_protection_shutdown() with the difference that it will force a reboot instead of shutdown. The motivation for doing this is to allow the thermal subystem to trigger a reboot when the temperature reaches the critical temperature. Signed-off-by: Fabio Estevam <festevam@xxxxxxx> --- Changes since v3: - None include/linux/reboot.h | 1 + kernel/reboot.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 2b6bb593be5b..4a319bc24f6a 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -174,6 +174,7 @@ void ctrl_alt_del(void); extern void orderly_poweroff(bool force); extern void orderly_reboot(void); +void hw_protection_reboot(const char *reason, int ms_until_forced); void hw_protection_shutdown(const char *reason, int ms_until_forced); /* diff --git a/kernel/reboot.c b/kernel/reboot.c index 3bba88c7ffc6..05333ae8bc6b 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -952,6 +952,40 @@ static void hw_failure_emergency_poweroff(int poweroff_delay_ms) msecs_to_jiffies(poweroff_delay_ms)); } +/** + * hw_protection_reboot - Trigger an emergency system reboot + * + * @reason: Reason of emergency reboot to be printed. + * @ms_until_forced: Time to wait for orderly reboot before tiggering a + * forced reboot. Negative value disables the forced + * reboot. + * + * Initiate an emergency system reboot in order to protect hardware from + * further damage. Usage examples include a thermal protection. + * + * NOTE: The request is ignored if protection reboot is already pending even + * if the previous request has given a large timeout for forced reboot. + * Can be called from any context. + */ +void hw_protection_reboot(const char *reason, int ms_until_forced) +{ + static atomic_t allow_proceed = ATOMIC_INIT(1); + + pr_emerg("HARDWARE PROTECTION reboot (%s)\n", reason); + + /* Reboot should be initiated only once. */ + if (!atomic_dec_and_test(&allow_proceed)) + return; + + /* + * Queue a backup emergency reboot in the event of + * orderly_reboot failure + */ + hw_failure_emergency_poweroff(ms_until_forced); + orderly_reboot(); +} +EXPORT_SYMBOL_GPL(hw_protection_reboot); + /** * hw_protection_shutdown - Trigger an emergency system poweroff * -- 2.34.1