···582This function serves as an arbitrator to set the state of a cooling583device. It sets the cooling device to the deepest cooling state if584possible.000000000000000000000
···582This function serves as an arbitrator to set the state of a cooling583device. It sets the cooling device to the deepest cooling state if584possible.585+586+6. thermal_emergency_poweroff:587+588+On an event of critical trip temperature crossing. Thermal framework589+allows the system to shutdown gracefully by calling orderly_poweroff().590+In the event of a failure of orderly_poweroff() to shut down the system591+we are in danger of keeping the system alive at undesirably high592+temperatures. To mitigate this high risk scenario we program a work593+queue to fire after a pre-determined number of seconds to start594+an emergency shutdown of the device using the kernel_power_off()595+function. In case kernel_power_off() fails then finally596+emergency_restart() is called in the worst case.597+598+The delay should be carefully profiled so as to give adequate time for599+orderly_poweroff(). In case of failure of an orderly_poweroff() the600+emergency poweroff kicks in after the delay has elapsed and shuts down601+the system.602+603+If set to 0 emergency poweroff will not be supported. So a carefully604+profiled non-zero positive value is a must for emergerncy poweroff to be605+triggered.
···1516if THERMAL1718+config THERMAL_EMERGENCY_POWEROFF_DELAY_MS19+ int "Emergency poweroff delay in milli-seconds"20+ depends on THERMAL21+ default 022+ help23+ Thermal subsystem will issue a graceful shutdown when24+ critical temperatures are reached using orderly_poweroff(). In25+ case of failure of an orderly_poweroff(), the thermal emergency26+ poweroff kicks in after a delay has elapsed and shuts down the system.27+ This config is number of milliseconds to delay before emergency28+ poweroff kicks in. Similarly to the critical trip point,29+ the delay should be carefully profiled so as to give adequate30+ time for orderly_poweroff() to finish on regular execution.31+ If set to 0 emergency poweroff will not be supported.32+33+ In doubt, leave as 0.34+35config THERMAL_HWMON36 bool37 prompt "Expose thermal sensors as hwmon device"
+63-1
drivers/thermal/thermal_core.c
···4546static DEFINE_MUTEX(thermal_list_lock);47static DEFINE_MUTEX(thermal_governor_lock);04849static atomic_t in_suspend;05051static struct thermal_governor *def_governor;52···324 def_governor->throttle(tz, trip);325}326000000000000000000000000000000000000000000000000327static void handle_critical_trips(struct thermal_zone_device *tz,328 int trip, enum thermal_trip_type trip_type)329{···392 dev_emerg(&tz->device,393 "critical temperature reached(%d C),shutting down\n",394 tz->temperature / 1000);395- orderly_poweroff(true);0000000000396 }397}398···1523{1524 int result;152501526 result = thermal_register_governors();1527 if (result)1528 goto error;···1558 ida_destroy(&thermal_cdev_ida);1559 mutex_destroy(&thermal_list_lock);1560 mutex_destroy(&thermal_governor_lock);01561 return result;1562}1563
···4546static DEFINE_MUTEX(thermal_list_lock);47static DEFINE_MUTEX(thermal_governor_lock);48+static DEFINE_MUTEX(poweroff_lock);4950static atomic_t in_suspend;51+static bool power_off_triggered;5253static struct thermal_governor *def_governor;54···322 def_governor->throttle(tz, trip);323}324325+/**326+ * thermal_emergency_poweroff_func - emergency poweroff work after a known delay327+ * @work: work_struct associated with the emergency poweroff function328+ *329+ * This function is called in very critical situations to force330+ * a kernel poweroff after a configurable timeout value.331+ */332+static void thermal_emergency_poweroff_func(struct work_struct *work)333+{334+ /*335+ * We have reached here after the emergency thermal shutdown336+ * Waiting period has expired. This means orderly_poweroff has337+ * not been able to shut off the system for some reason.338+ * Try to shut down the system immediately using kernel_power_off339+ * if populated340+ */341+ WARN(1, "Attempting kernel_power_off: Temperature too high\n");342+ kernel_power_off();343+344+ /*345+ * Worst of the worst case trigger emergency restart346+ */347+ WARN(1, "Attempting emergency_restart: Temperature too high\n");348+ emergency_restart();349+}350+351+static DECLARE_DELAYED_WORK(thermal_emergency_poweroff_work,352+ thermal_emergency_poweroff_func);353+354+/**355+ * thermal_emergency_poweroff - Trigger an emergency system poweroff356+ *357+ * This may be called from any critical situation to trigger a system shutdown358+ * after a known period of time. By default this is not scheduled.359+ */360+void thermal_emergency_poweroff(void)361+{362+ int poweroff_delay_ms = CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS;363+ /*364+ * poweroff_delay_ms must be a carefully profiled positive value.365+ * Its a must for thermal_emergency_poweroff_work to be scheduled366+ */367+ if (poweroff_delay_ms <= 0)368+ return;369+ schedule_delayed_work(&thermal_emergency_poweroff_work,370+ msecs_to_jiffies(poweroff_delay_ms));371+}372+373static void handle_critical_trips(struct thermal_zone_device *tz,374 int trip, enum thermal_trip_type trip_type)375{···342 dev_emerg(&tz->device,343 "critical temperature reached(%d C),shutting down\n",344 tz->temperature / 1000);345+ mutex_lock(&poweroff_lock);346+ if (!power_off_triggered) {347+ /*348+ * Queue a backup emergency shutdown in the event of349+ * orderly_poweroff failure350+ */351+ thermal_emergency_poweroff();352+ orderly_poweroff(true);353+ power_off_triggered = true;354+ }355+ mutex_unlock(&poweroff_lock);356 }357}358···1463{1464 int result;14651466+ mutex_init(&poweroff_lock);1467 result = thermal_register_governors();1468 if (result)1469 goto error;···1497 ida_destroy(&thermal_cdev_ida);1498 mutex_destroy(&thermal_list_lock);1499 mutex_destroy(&thermal_governor_lock);1500+ mutex_destroy(&poweroff_lock);1501 return result;1502}1503