Messages in this thread Patch in this message | | | From | Fabio Estevam <> | Subject | [PATCH v3] thermal: imx8mm: Allow reboot after critical temperature | Date | Thu, 24 Aug 2023 09:21:02 -0300 |
| |
From: Fabio Estevam <festevam@denx.de>
Currently, after the SoC reaches the critical temperature, the board goes through a poweroff mechanism.
In some 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 a reboot_on_critical parameter to indicate that the board will go through a reboot after the critical temperature is reached.
When this parameter is not passed, the default behavior of forcing a shutdown is preserved.
Tested on a imx8mm-evk board by passing 'imx8mm_thermal.reboot_on_critical' via kernel command line.
Signed-off-by: Fabio Estevam <festevam@denx.de> --- Changes since v2: - Set the .critical ops at init time and get rid of the thermal_zone_device_critical(tz) call. (Daniel)
drivers/thermal/imx8mm_thermal.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c index e89b11b3f2b9..f156e6e81abc 100644 --- a/drivers/thermal/imx8mm_thermal.c +++ b/drivers/thermal/imx8mm_thermal.c @@ -10,9 +10,11 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/nvmem-consumer.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/slab.h> #include <linux/thermal.h> @@ -75,6 +77,11 @@ #define TMU_VER1 0x1 #define TMU_VER2 0x2 +static bool reboot_on_critical; +module_param(reboot_on_critical, bool, 0444); +MODULE_PARM_DESC(reboot_on_critical, + "Reboot the system after the critical temperature is reached."); + struct thermal_soc_data { u32 num_sensors; u32 version; @@ -146,7 +153,7 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) return tmu->socdata->get_temp(sensor, temp); } -static const struct thermal_zone_device_ops tmu_tz_ops = { +static struct thermal_zone_device_ops tmu_tz_ops = { .get_temp = tmu_get_temp, }; @@ -293,6 +300,13 @@ static int imx8mm_tmu_probe_set_calib(struct platform_device *pdev, return imx8mm_tmu_probe_set_calib_v2(pdev, tmu); } +static void tmu_critical(struct thermal_zone_device *tz) +{ + dev_emerg(thermal_zone_device(tz), "%s: critical temperature reached\n", + thermal_zone_device_type(tz)); + kernel_restart(NULL); +} + static int imx8mm_tmu_probe(struct platform_device *pdev) { const struct thermal_soc_data *data; @@ -327,6 +341,9 @@ static int imx8mm_tmu_probe(struct platform_device *pdev) /* disable the monitor during initialization */ imx8mm_tmu_enable(tmu, false); + if (reboot_on_critical) + tmu_tz_ops.critical = tmu_critical; + for (i = 0; i < data->num_sensors; i++) { tmu->sensors[i].priv = tmu; tmu->sensors[i].tzd = -- 2.34.1
| |