thermal/thermal_of: Allow rebooting after critical temp
authorFabio Estevam <festevam@denx.de>
Wed, 29 Nov 2023 12:43:30 +0000 (09:43 -0300)
committerDaniel Lezcano <daniel.lezcano@linaro.org>
Tue, 2 Jan 2024 08:33:18 +0000 (09:33 +0100)
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.

If a custom ops->critical exists, then it takes preference over
critical-actions.

Tested on a i.MX8MM board with the following devicetree changes:

thermal-zones {
cpu-thermal {
critical-action = "reboot";
};
};

Signed-off-by: Fabio Estevam <festevam@denx.de>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20231129124330.519423-4-festevam@gmail.com
drivers/thermal/thermal_of.c

index 1e0655b63259fe391f8a43a3a71f01172b5f74b8..4d6c22e0ed85bf55a27fcc508fb5e196da492657 100644 (file)
@@ -475,6 +475,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;
+       const char *action;
        int delay, pdelay;
        int ntrips, mask;
        int ret;
@@ -511,6 +512,11 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
 
        mask = GENMASK_ULL((ntrips) - 1, 0);
 
+       ret = of_property_read_string(np, "critical-action", &action);
+       if (!ret)
+               if (!of_ops->critical && !strcasecmp(action, "reboot"))
+                       of_ops->critical = thermal_zone_device_critical_reboot;
+
        tz = thermal_zone_device_register_with_trips(np->name, trips, ntrips,
                                                     mask, data, of_ops, &tzp,
                                                     pdelay, delay);