* [PATCH 1/4] dt-bindings: thermal-zones: Document critical-action
@ 2023-08-25 10:24 Fabio Estevam
2023-08-25 10:24 ` [PATCH 2/4] dt-bindings: thermal: Document the values for the 'critical-action' Fabio Estevam
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Fabio Estevam @ 2023-08-25 10:24 UTC (permalink / raw)
To: daniel.lezcano
Cc: rafael, amitk, rui.zhang, linux-pm, krzysztof.kozlowski+dt,
robh+dt, conor+dt, devicetree, Fabio Estevam
From: Fabio Estevam <festevam@denx.de>
Document the critical-action property to describe the thermal
action that will be taken after the critical temperature is reached.
The possible values are:
- 0 for shutdown
- 1 for reboot.
Signed-off-by: Fabio Estevam <festevam@denx.de>
---
.../devicetree/bindings/thermal/thermal-zones.yaml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
index 4f3acdc4dec0..782cbb4ea487 100644
--- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
+++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
@@ -75,6 +75,14 @@ patternProperties:
framework and assumes that the thermal sensors in this zone
support interrupts.
+ critical-action:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ The action that happens after the critical temperature is reached.
+ Possible values are 0 for shutdown and 1 for reboot.
+
+ enum: [ 0, 1 ]
+
thermal-sensors:
$ref: /schemas/types.yaml#/definitions/phandle-array
maxItems: 1
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/4] dt-bindings: thermal: Document the values for the 'critical-action'
2023-08-25 10:24 [PATCH 1/4] dt-bindings: thermal-zones: Document critical-action Fabio Estevam
@ 2023-08-25 10:24 ` Fabio Estevam
2023-08-25 10:24 ` [PATCH 3/4] reboot: Introduce hw_protection_reboot() Fabio Estevam
2023-08-25 10:24 ` [PATCH 4/4] thermal: thermal_core: Allow rebooting after critical temp Fabio Estevam
2 siblings, 0 replies; 4+ messages in thread
From: Fabio Estevam @ 2023-08-25 10:24 UTC (permalink / raw)
To: daniel.lezcano
Cc: rafael, amitk, rui.zhang, linux-pm, krzysztof.kozlowski+dt,
robh+dt, conor+dt, devicetree, Fabio Estevam
From: Fabio Estevam <festevam@denx.de>
Document the possible values for the 'critical-action' property to make
it more readable in the devicetree.
Signed-off-by: Fabio Estevam <festevam@denx.de>
---
include/dt-bindings/thermal/thermal.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/dt-bindings/thermal/thermal.h b/include/dt-bindings/thermal/thermal.h
index bc7babb1a67c..f433b6b0ffb7 100644
--- a/include/dt-bindings/thermal/thermal.h
+++ b/include/dt-bindings/thermal/thermal.h
@@ -12,5 +12,9 @@
/* On cooling devices upper and lower limits */
#define THERMAL_NO_LIMIT (~0)
+/* Possible values for the 'critical-action' property */
+#define THERMAL_CRITICAL_ACTION_SHUTDOWN 0
+#define THERMAL_CRITICAL_ACTION_REBOOT 1
+
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/4] reboot: Introduce hw_protection_reboot()
2023-08-25 10:24 [PATCH 1/4] dt-bindings: thermal-zones: Document critical-action Fabio Estevam
2023-08-25 10:24 ` [PATCH 2/4] dt-bindings: thermal: Document the values for the 'critical-action' Fabio Estevam
@ 2023-08-25 10:24 ` Fabio Estevam
2023-08-25 10:24 ` [PATCH 4/4] thermal: thermal_core: Allow rebooting after critical temp Fabio Estevam
2 siblings, 0 replies; 4+ messages in thread
From: Fabio Estevam @ 2023-08-25 10:24 UTC (permalink / raw)
To: daniel.lezcano
Cc: rafael, amitk, rui.zhang, linux-pm, krzysztof.kozlowski+dt,
robh+dt, conor+dt, devicetree, Fabio Estevam
From: Fabio Estevam <festevam@denx.de>
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@denx.de>
---
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..64517d1e4c55 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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 4/4] thermal: thermal_core: Allow rebooting after critical temp
2023-08-25 10:24 [PATCH 1/4] dt-bindings: thermal-zones: Document critical-action Fabio Estevam
2023-08-25 10:24 ` [PATCH 2/4] dt-bindings: thermal: Document the values for the 'critical-action' Fabio Estevam
2023-08-25 10:24 ` [PATCH 3/4] reboot: Introduce hw_protection_reboot() Fabio Estevam
@ 2023-08-25 10:24 ` Fabio Estevam
2 siblings, 0 replies; 4+ messages in thread
From: Fabio Estevam @ 2023-08-25 10:24 UTC (permalink / raw)
To: daniel.lezcano
Cc: rafael, amitk, rui.zhang, linux-pm, krzysztof.kozlowski+dt,
robh+dt, conor+dt, devicetree, Fabio Estevam
From: Fabio Estevam <festevam@denx.de>
Currently, the default mechanism is to trigger a shutdown after the
critical temperature is reached.
In some embedded cases, such behavior does not suit well, as the board may
be unattended in the field and rebooting may be a better approach.
The bootloader may also check the temperature and only allow the boot to
proceed when the temperature is below a certain threshold.
Introduce support for allowing a reboot to be triggered after the
critical temperature is reached.
If the "critical-action" devicetree property is not found, fall back to
the shutdown action to preserve the existing default behavior.
Tested on a i.MX8MM board with the following devicetre changes:
thermal-zones {
cpu-thermal {
critical-action = <THERMAL_CRITICAL_ACTION_REBOOT>;
};
};
Signed-off-by: Fabio Estevam <festevam@denx.de>
---
drivers/thermal/thermal_core.c | 8 +++++++-
drivers/thermal/thermal_of.c | 17 ++++++++++++++---
include/linux/thermal.h | 6 ++++++
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index cc2b5e81c620..3f4ea27560f8 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -320,11 +320,17 @@ void thermal_zone_device_critical(struct thermal_zone_device *tz)
* Its a must for forced_emergency_poweroff_work to be scheduled.
*/
int poweroff_delay_ms = CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS;
+ void (*hw_protection_action)(const char *reason, int ms_until_forced);
dev_emerg(&tz->device, "%s: critical temperature reached, "
"shutting down\n", tz->type);
- hw_protection_shutdown("Temperature too high", poweroff_delay_ms);
+ hw_protection_action = hw_protection_shutdown;
+
+ if (tz->action == THERMAL_CRITICAL_ACTION_REBOOT)
+ hw_protection_action = hw_protection_reboot;
+
+ hw_protection_action("Temperature too high", poweroff_delay_ms);
}
EXPORT_SYMBOL(thermal_zone_device_critical);
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index 330690a3a208..36a2c82d3405 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -218,7 +218,8 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int
return tz;
}
-static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdelay)
+static int thermal_of_monitor_init(struct device_node *np, int *delay,
+ int *pdelay, int *critical_action)
{
int ret;
@@ -234,6 +235,14 @@ static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdel
return ret;
}
+ /*
+ * If the "critical-action" property is not found, fall back to
+ * the shutdown action to keep the existing behavior.
+ */
+ ret = of_property_read_u32(np, "critical-action", critical_action);
+ if (ret < 0)
+ *critical_action = THERMAL_CRITICAL_ACTION_SHUTDOWN;
+
return 0;
}
@@ -471,7 +480,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
struct thermal_zone_params tzp = {};
struct thermal_zone_device_ops *of_ops;
struct device_node *np;
- int delay, pdelay;
+ int delay, pdelay, critical_action;
int ntrips, mask;
int ret;
@@ -494,7 +503,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
goto out_kfree_of_ops;
}
- ret = thermal_of_monitor_init(np, &delay, &pdelay);
+ ret = thermal_of_monitor_init(np, &delay, &pdelay, &critical_action);
if (ret) {
pr_err("Failed to initialize monitoring delays from %pOFn\n", np);
goto out_kfree_trips;
@@ -516,6 +525,8 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
goto out_kfree_trips;
}
+ tz->action = critical_action;
+
ret = thermal_zone_device_enable(tz);
if (ret) {
pr_err("Failed to enabled thermal zone '%s', id=%d: %d\n",
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index dee66ade89a0..48f29ab16218 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -34,6 +34,11 @@ struct thermal_cooling_device;
struct thermal_instance;
struct thermal_attr;
+enum thermal_action {
+ THERMAL_CRITICAL_ACTION_SHUTDOWN, /* shutdown when crit temperature is reached */
+ THERMAL_CRITICAL_ACTION_REBOOT, /* reboot when crit temperature is reached */
+};
+
enum thermal_trend {
THERMAL_TREND_STABLE, /* temperature is stable */
THERMAL_TREND_RAISING, /* temperature is raising */
@@ -185,6 +190,7 @@ struct thermal_zone_device {
struct list_head node;
struct delayed_work poll_queue;
enum thermal_notify_event notify_event;
+ enum thermal_action action;
};
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-08-25 10:26 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-25 10:24 [PATCH 1/4] dt-bindings: thermal-zones: Document critical-action Fabio Estevam
2023-08-25 10:24 ` [PATCH 2/4] dt-bindings: thermal: Document the values for the 'critical-action' Fabio Estevam
2023-08-25 10:24 ` [PATCH 3/4] reboot: Introduce hw_protection_reboot() Fabio Estevam
2023-08-25 10:24 ` [PATCH 4/4] thermal: thermal_core: Allow rebooting after critical temp Fabio Estevam
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.