diff mbox series

[RFC,2/4] thermal/core: Add critical and hot ops

Message ID 20201209153440.27643-2-daniel.lezcano@linaro.org
State Superseded
Headers show
Series [RFC,1/4] thermal/core: Emit a warning if the thermal zone is updated without ops | expand

Commit Message

Daniel Lezcano Dec. 9, 2020, 3:34 p.m. UTC
Currently there is no way to the sensors to directly call an ops in
interrupt mode without calling thermal_zone_device_update assuming all
the trip points are defined.

A sensor may want to do something special if a trip point is hot or
critical.

This patch adds the critical and hot ops to the thermal zone device,
so a sensor can directly invoke them or let the thermal framework to
call the sensor specific ones.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>

---
 drivers/thermal/thermal_core.c | 42 +++++++++++++++++++++-------------
 include/linux/thermal.h        |  3 +++
 2 files changed, 29 insertions(+), 16 deletions(-)

-- 
2.17.1

Comments

Kai-Heng Feng Dec. 10, 2020, 9:28 a.m. UTC | #1
> On Dec 9, 2020, at 23:34, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:

> 

> Currently there is no way to the sensors to directly call an ops in

> interrupt mode without calling thermal_zone_device_update assuming all

> the trip points are defined.

> 

> A sensor may want to do something special if a trip point is hot or

> critical.

> 

> This patch adds the critical and hot ops to the thermal zone device,

> so a sensor can directly invoke them or let the thermal framework to

> call the sensor specific ones.

> 

> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>


Thanks. This can solve my issue once .critical callbacks are added in thermal drivers.

Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>


> ---

> drivers/thermal/thermal_core.c | 42 +++++++++++++++++++++-------------

> include/linux/thermal.h        |  3 +++

> 2 files changed, 29 insertions(+), 16 deletions(-)

> 

> diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c

> index afc02e7d1045..0366f3f076cc 100644

> --- a/drivers/thermal/thermal_core.c

> +++ b/drivers/thermal/thermal_core.c

> @@ -375,6 +375,24 @@ static void thermal_emergency_poweroff(void)

> 			      msecs_to_jiffies(poweroff_delay_ms));

> }

> 

> +void thermal_zone_device_critical(struct thermal_zone_device *tz)

> +{

> +	dev_emerg(&tz->device, "%s: critical temperature reached, "

> +		  "shutting down\n", tz->type);

> +

> +	mutex_lock(&poweroff_lock);

> +	if (!power_off_triggered) {

> +		/*

> +		 * Queue a backup emergency shutdown in the event of

> +		 * orderly_poweroff failure

> +		 */

> +		thermal_emergency_poweroff();

> +		orderly_poweroff(true);

> +		power_off_triggered = true;

> +	}

> +	mutex_unlock(&poweroff_lock);

> +}

> +

> static void handle_critical_trips(struct thermal_zone_device *tz,

> 				  int trip, enum thermal_trip_type trip_type)

> {

> @@ -391,22 +409,10 @@ static void handle_critical_trips(struct thermal_zone_device *tz,

> 	if (tz->ops->notify)

> 		tz->ops->notify(tz, trip, trip_type);

> 

> -	if (trip_type == THERMAL_TRIP_CRITICAL) {

> -		dev_emerg(&tz->device,

> -			  "critical temperature reached (%d C), shutting down\n",

> -			  tz->temperature / 1000);

> -		mutex_lock(&poweroff_lock);

> -		if (!power_off_triggered) {

> -			/*

> -			 * Queue a backup emergency shutdown in the event of

> -			 * orderly_poweroff failure

> -			 */

> -			thermal_emergency_poweroff();

> -			orderly_poweroff(true);

> -			power_off_triggered = true;

> -		}

> -		mutex_unlock(&poweroff_lock);

> -	}

> +	if (trip_type == THERMAL_TRIP_HOT && tz->ops->hot)

> +		tz->ops->hot(tz);

> +	else if (trip_type == THERMAL_TRIP_CRITICAL)

> +		tz->ops->critical(tz);

> }

> 

> static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)

> @@ -1331,6 +1337,10 @@ thermal_zone_device_register(const char *type, int trips, int mask,

> 

> 	tz->id = id;

> 	strlcpy(tz->type, type, sizeof(tz->type));

> +

> +	if (!ops->critical)

> +		ops->critical = thermal_zone_device_critical;

> +

> 	tz->ops = ops;

> 	tz->tzp = tzp;

> 	tz->device.class = &thermal_class;

> diff --git a/include/linux/thermal.h b/include/linux/thermal.h

> index f23a388ded15..125c8a4d52e6 100644

> --- a/include/linux/thermal.h

> +++ b/include/linux/thermal.h

> @@ -79,6 +79,8 @@ struct thermal_zone_device_ops {

> 			  enum thermal_trend *);

> 	int (*notify) (struct thermal_zone_device *, int,

> 		       enum thermal_trip_type);

> +	void (*hot)(struct thermal_zone_device *);

> +	void (*critical)(struct thermal_zone_device *);

> };

> 

> struct thermal_cooling_device_ops {

> @@ -399,6 +401,7 @@ void thermal_cdev_update(struct thermal_cooling_device *);

> void thermal_notify_framework(struct thermal_zone_device *, int);

> int thermal_zone_device_enable(struct thermal_zone_device *tz);

> int thermal_zone_device_disable(struct thermal_zone_device *tz);

> +void thermal_zone_device_critical(struct thermal_zone_device *tz);

> #else

> static inline struct thermal_zone_device *thermal_zone_device_register(

> 	const char *type, int trips, int mask, void *devdata,

> -- 

> 2.17.1

>
diff mbox series

Patch

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index afc02e7d1045..0366f3f076cc 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -375,6 +375,24 @@  static void thermal_emergency_poweroff(void)
 			      msecs_to_jiffies(poweroff_delay_ms));
 }
 
+void thermal_zone_device_critical(struct thermal_zone_device *tz)
+{
+	dev_emerg(&tz->device, "%s: critical temperature reached, "
+		  "shutting down\n", tz->type);
+
+	mutex_lock(&poweroff_lock);
+	if (!power_off_triggered) {
+		/*
+		 * Queue a backup emergency shutdown in the event of
+		 * orderly_poweroff failure
+		 */
+		thermal_emergency_poweroff();
+		orderly_poweroff(true);
+		power_off_triggered = true;
+	}
+	mutex_unlock(&poweroff_lock);
+}
+
 static void handle_critical_trips(struct thermal_zone_device *tz,
 				  int trip, enum thermal_trip_type trip_type)
 {
@@ -391,22 +409,10 @@  static void handle_critical_trips(struct thermal_zone_device *tz,
 	if (tz->ops->notify)
 		tz->ops->notify(tz, trip, trip_type);
 
-	if (trip_type == THERMAL_TRIP_CRITICAL) {
-		dev_emerg(&tz->device,
-			  "critical temperature reached (%d C), shutting down\n",
-			  tz->temperature / 1000);
-		mutex_lock(&poweroff_lock);
-		if (!power_off_triggered) {
-			/*
-			 * Queue a backup emergency shutdown in the event of
-			 * orderly_poweroff failure
-			 */
-			thermal_emergency_poweroff();
-			orderly_poweroff(true);
-			power_off_triggered = true;
-		}
-		mutex_unlock(&poweroff_lock);
-	}
+	if (trip_type == THERMAL_TRIP_HOT && tz->ops->hot)
+		tz->ops->hot(tz);
+	else if (trip_type == THERMAL_TRIP_CRITICAL)
+		tz->ops->critical(tz);
 }
 
 static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
@@ -1331,6 +1337,10 @@  thermal_zone_device_register(const char *type, int trips, int mask,
 
 	tz->id = id;
 	strlcpy(tz->type, type, sizeof(tz->type));
+
+	if (!ops->critical)
+		ops->critical = thermal_zone_device_critical;
+
 	tz->ops = ops;
 	tz->tzp = tzp;
 	tz->device.class = &thermal_class;
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index f23a388ded15..125c8a4d52e6 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -79,6 +79,8 @@  struct thermal_zone_device_ops {
 			  enum thermal_trend *);
 	int (*notify) (struct thermal_zone_device *, int,
 		       enum thermal_trip_type);
+	void (*hot)(struct thermal_zone_device *);
+	void (*critical)(struct thermal_zone_device *);
 };
 
 struct thermal_cooling_device_ops {
@@ -399,6 +401,7 @@  void thermal_cdev_update(struct thermal_cooling_device *);
 void thermal_notify_framework(struct thermal_zone_device *, int);
 int thermal_zone_device_enable(struct thermal_zone_device *tz);
 int thermal_zone_device_disable(struct thermal_zone_device *tz);
+void thermal_zone_device_critical(struct thermal_zone_device *tz);
 #else
 static inline struct thermal_zone_device *thermal_zone_device_register(
 	const char *type, int trips, int mask, void *devdata,