Message ID | 20231001030014.1244633-2-festevam@gmail.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | [v9,1/3] dt-bindings: thermal-zones: Document critical-action | expand |
On 01/10/2023 05:00, Fabio Estevam wrote: > From: Fabio Estevam <festevam@denx.de> > > Introduce thermal_zone_device_critical_reboot() to trigger an > emergency reboot. > > It is a counterpart of thermal_zone_device_critical() 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@denx.de> > --- > Changes since v8: > - Introduce thermal_zone_device_critical_reboot() to accomodate > Daniel's suggestions. > > drivers/thermal/thermal_core.c | 19 +++++++++++++++++-- > include/linux/reboot.h | 13 ++++++++++++- > include/linux/thermal.h | 1 + > kernel/reboot.c | 32 +++++++++++++++++++------------- > 4 files changed, 49 insertions(+), 16 deletions(-) > > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c > index 38d393f139d8..277aafb294db 100644 > --- a/drivers/thermal/thermal_core.c > +++ b/drivers/thermal/thermal_core.c > @@ -313,21 +313,36 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip) > def_governor->throttle(tz, trip); > } > > -void thermal_zone_device_critical(struct thermal_zone_device *tz) > +static void thermal_zone_device_shutdown(struct thermal_zone_device *tz, bool shutdown) Probably nit picking but is it possible to rename to: static void thermal_zone_device_halt(struct thermal_zone_device *tz, bool shutdown) > { > /* > * poweroff_delay_ms must be a carefully profiled positive value. > * Its a must for forced_emergency_poweroff_work to be scheduled. > */ > int poweroff_delay_ms = CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS; > + static const char *msg = "Temperature too high"; Why use 'static' ? > dev_emerg(&tz->device, "%s: critical temperature reached, " > "shutting down\n", tz->type); Now the function can do 'shutdown' or 'reboot', so the message should reflect that. However, the reason will be displayed in the hw_protection_shutdown/reboot, so having: dev_emerg(&tz->device, "%s: critical temperature reached\n", tz->type); > - hw_protection_shutdown("Temperature too high", poweroff_delay_ms); > + if (shutdown) > + hw_protection_shutdown(msg, poweroff_delay_ms); > + else > + hw_protection_reboot(msg, poweroff_delay_ms); > +} > + > +void thermal_zone_device_critical(struct thermal_zone_device *tz) > +{ > + thermal_zone_device_shutdown(tz, true); > } > EXPORT_SYMBOL(thermal_zone_device_critical); Rename to thermal_zone_device_critical_shutdown() for consistency (in a separate patch). > > +void thermal_zone_device_critical_reboot(struct thermal_zone_device *tz) > +{ > + thermal_zone_device_shutdown(tz, false); > +} > +EXPORT_SYMBOL(thermal_zone_device_critical_reboot); > + > static void handle_critical_trips(struct thermal_zone_device *tz, > int trip, int trip_temp, enum thermal_trip_type trip_type) > { > diff --git a/include/linux/reboot.h b/include/linux/reboot.h > index c4cc3b89ced1..4683e117c753 100644 > --- a/include/linux/reboot.h > +++ b/include/linux/reboot.h > @@ -177,7 +177,18 @@ void ctrl_alt_del(void); > > extern void orderly_poweroff(bool force); > extern void orderly_reboot(void); > -void hw_protection_shutdown(const char *reason, int ms_until_forced); > + > +void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shutdown); > + > +static inline void hw_protection_reboot(const char *reason, int ms_until_forced) > +{ > + __hw_protection_shutdown(reason, ms_until_forced, false); > +} > + > +static inline void hw_protection_shutdown(const char *reason, int ms_until_forced) > +{ > + __hw_protection_shutdown(reason, ms_until_forced, true); > +} Those changes should be in a separate patch. > /* > * Emergency restart, callable from an interrupt handler. > diff --git a/include/linux/thermal.h b/include/linux/thermal.h > index 6cfcae22ba12..c5ebb44ae8a6 100644 > --- a/include/linux/thermal.h > +++ b/include/linux/thermal.h > @@ -353,6 +353,7 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz); > int thermal_zone_device_enable(struct thermal_zone_device *tz); > int thermal_zone_device_disable(struct thermal_zone_device *tz); > void thermal_zone_device_critical(struct thermal_zone_device *tz); > +void thermal_zone_device_critical_reboot(struct thermal_zone_device *tz); > #else > static inline struct thermal_zone_device *thermal_zone_device_register_with_trips( > const char *type, > diff --git a/kernel/reboot.c b/kernel/reboot.c > index 395a0ea3c7a8..8b3010b88ed6 100644 > --- a/kernel/reboot.c > +++ b/kernel/reboot.c > @@ -957,21 +957,25 @@ static void hw_failure_emergency_poweroff(int poweroff_delay_ms) > } > > /** > - * hw_protection_shutdown - Trigger an emergency system poweroff > + * __hw_protection_shutdown - Trigger an emergency system shutdown or reboot > * > - * @reason: Reason of emergency shutdown to be printed. > - * @ms_until_forced: Time to wait for orderly shutdown before tiggering a > - * forced shudown. Negative value disables the forced > - * shutdown. > + * @reason: Reason of emergency shutdown or reboot to be printed. > + * @ms_until_forced: Time to wait for orderly shutdown or reboot before > + * triggering it. Negative value disables the forced > + * shutdown or reboot. > + * @shutdown: If true, indicates that a shutdown will happen > + * after the critical tempeature is reached. > + * If false, indicates that a reboot will happen > + * after the critical tempeature is reached. > * > - * Initiate an emergency system shutdown in order to protect hardware from > - * further damage. Usage examples include a thermal protection or a voltage or > - * current regulator failures. > - * NOTE: The request is ignored if protection shutdown is already pending even > - * if the previous request has given a large timeout for forced shutdown. > + * Initiate an emergency system shutdown or reboot in order to protect > + * hardware from further damage. Usage examples include a thermal protection. > + * NOTE: The request is ignored if protection shutdown or reboot is already > + * pending even if the previous request has given a large timeout for forced > + * shutdown/reboot. > * Can be called from any context. > */ > -void hw_protection_shutdown(const char *reason, int ms_until_forced) > +void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shutdown) > { > static atomic_t allow_proceed = ATOMIC_INIT(1); > > @@ -986,9 +990,11 @@ void hw_protection_shutdown(const char *reason, int ms_until_forced) > * orderly_poweroff failure > */ > hw_failure_emergency_poweroff(ms_until_forced); > - orderly_poweroff(true); > + if (shutdown) > + orderly_poweroff(true); > + else > + orderly_reboot(); > } > -EXPORT_SYMBOL_GPL(hw_protection_shutdown); Same comment > static int __init reboot_setup(char *str) > {
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 38d393f139d8..277aafb294db 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -313,21 +313,36 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip) def_governor->throttle(tz, trip); } -void thermal_zone_device_critical(struct thermal_zone_device *tz) +static void thermal_zone_device_shutdown(struct thermal_zone_device *tz, bool shutdown) { /* * poweroff_delay_ms must be a carefully profiled positive value. * Its a must for forced_emergency_poweroff_work to be scheduled. */ int poweroff_delay_ms = CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS; + static const char *msg = "Temperature too high"; dev_emerg(&tz->device, "%s: critical temperature reached, " "shutting down\n", tz->type); - hw_protection_shutdown("Temperature too high", poweroff_delay_ms); + if (shutdown) + hw_protection_shutdown(msg, poweroff_delay_ms); + else + hw_protection_reboot(msg, poweroff_delay_ms); +} + +void thermal_zone_device_critical(struct thermal_zone_device *tz) +{ + thermal_zone_device_shutdown(tz, true); } EXPORT_SYMBOL(thermal_zone_device_critical); +void thermal_zone_device_critical_reboot(struct thermal_zone_device *tz) +{ + thermal_zone_device_shutdown(tz, false); +} +EXPORT_SYMBOL(thermal_zone_device_critical_reboot); + static void handle_critical_trips(struct thermal_zone_device *tz, int trip, int trip_temp, enum thermal_trip_type trip_type) { diff --git a/include/linux/reboot.h b/include/linux/reboot.h index c4cc3b89ced1..4683e117c753 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -177,7 +177,18 @@ void ctrl_alt_del(void); extern void orderly_poweroff(bool force); extern void orderly_reboot(void); -void hw_protection_shutdown(const char *reason, int ms_until_forced); + +void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shutdown); + +static inline void hw_protection_reboot(const char *reason, int ms_until_forced) +{ + __hw_protection_shutdown(reason, ms_until_forced, false); +} + +static inline void hw_protection_shutdown(const char *reason, int ms_until_forced) +{ + __hw_protection_shutdown(reason, ms_until_forced, true); +} /* * Emergency restart, callable from an interrupt handler. diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 6cfcae22ba12..c5ebb44ae8a6 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -353,6 +353,7 @@ int thermal_zone_get_offset(struct thermal_zone_device *tz); int thermal_zone_device_enable(struct thermal_zone_device *tz); int thermal_zone_device_disable(struct thermal_zone_device *tz); void thermal_zone_device_critical(struct thermal_zone_device *tz); +void thermal_zone_device_critical_reboot(struct thermal_zone_device *tz); #else static inline struct thermal_zone_device *thermal_zone_device_register_with_trips( const char *type, diff --git a/kernel/reboot.c b/kernel/reboot.c index 395a0ea3c7a8..8b3010b88ed6 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -957,21 +957,25 @@ static void hw_failure_emergency_poweroff(int poweroff_delay_ms) } /** - * hw_protection_shutdown - Trigger an emergency system poweroff + * __hw_protection_shutdown - Trigger an emergency system shutdown or reboot * - * @reason: Reason of emergency shutdown to be printed. - * @ms_until_forced: Time to wait for orderly shutdown before tiggering a - * forced shudown. Negative value disables the forced - * shutdown. + * @reason: Reason of emergency shutdown or reboot to be printed. + * @ms_until_forced: Time to wait for orderly shutdown or reboot before + * triggering it. Negative value disables the forced + * shutdown or reboot. + * @shutdown: If true, indicates that a shutdown will happen + * after the critical tempeature is reached. + * If false, indicates that a reboot will happen + * after the critical tempeature is reached. * - * Initiate an emergency system shutdown in order to protect hardware from - * further damage. Usage examples include a thermal protection or a voltage or - * current regulator failures. - * NOTE: The request is ignored if protection shutdown is already pending even - * if the previous request has given a large timeout for forced shutdown. + * Initiate an emergency system shutdown or reboot in order to protect + * hardware from further damage. Usage examples include a thermal protection. + * NOTE: The request is ignored if protection shutdown or reboot is already + * pending even if the previous request has given a large timeout for forced + * shutdown/reboot. * Can be called from any context. */ -void hw_protection_shutdown(const char *reason, int ms_until_forced) +void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shutdown) { static atomic_t allow_proceed = ATOMIC_INIT(1); @@ -986,9 +990,11 @@ void hw_protection_shutdown(const char *reason, int ms_until_forced) * orderly_poweroff failure */ hw_failure_emergency_poweroff(ms_until_forced); - orderly_poweroff(true); + if (shutdown) + orderly_poweroff(true); + else + orderly_reboot(); } -EXPORT_SYMBOL_GPL(hw_protection_shutdown); static int __init reboot_setup(char *str) {