Message ID | 20230824112705.451411-1-festevam@gmail.com |
---|---|
State | New |
Headers | show |
Series | [v2] thermal: imx8mm: Allow reboot after critical temperature | expand |
Hi Fabio, On 24/08/2023 13:27, Fabio Estevam wrote: > From: Fabio Estevam <festevam@denx.de> > > Currently, after the board reaches the critical temperature, the system > 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 selected, 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 v1: > - Introduce a module_param() instead of a devicetree property. > > drivers/thermal/imx8mm_thermal.c | 19 +++++++++++++++++++ > 1 file changed, 19 insertions(+) > > diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c > index e89b11b3f2b9..2427bd46ac6c 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,8 +153,20 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) > return tmu->socdata->get_temp(sensor, temp); > } > > +static void tmu_critical(struct thermal_zone_device *tz) > +{ > + if (reboot_on_critical) { > + dev_emerg(thermal_zone_device(tz), "%s: critical temperature reached\n", > + thermal_zone_device_type(tz)); > + kernel_restart(NULL); > + } else { > + thermal_zone_device_critical(tz); > + } > +} Is it possible to set the .critical ops at init time instead and get rid of the thermal_zone_device_critical(tz) call ? > static const struct thermal_zone_device_ops tmu_tz_ops = { > .get_temp = tmu_get_temp, > + .critical = tmu_critical, > }; > > static void imx8mm_tmu_enable(struct imx8mm_tmu *tmu, bool enable)
diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c index e89b11b3f2b9..2427bd46ac6c 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,8 +153,20 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) return tmu->socdata->get_temp(sensor, temp); } +static void tmu_critical(struct thermal_zone_device *tz) +{ + if (reboot_on_critical) { + dev_emerg(thermal_zone_device(tz), "%s: critical temperature reached\n", + thermal_zone_device_type(tz)); + kernel_restart(NULL); + } else { + thermal_zone_device_critical(tz); + } +} + static const struct thermal_zone_device_ops tmu_tz_ops = { .get_temp = tmu_get_temp, + .critical = tmu_critical, }; static void imx8mm_tmu_enable(struct imx8mm_tmu *tmu, bool enable)