Skip to content

Commit

Permalink
thermal/core: Add critical and hot ops
Browse files Browse the repository at this point in the history
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.

Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Link: https://lore.kernel.org/r/20201210121514.25760-2-daniel.lezcano@linaro.org
  • Loading branch information
Daniel Lezcano committed Dec 11, 2020
1 parent 433178e commit d7203ee
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
43 changes: 27 additions & 16 deletions drivers/thermal/thermal_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,25 @@ 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);
}
EXPORT_SYMBOL(thermal_zone_device_critical);

static void handle_critical_trips(struct thermal_zone_device *tz,
int trip, enum thermal_trip_type trip_type)
{
Expand All @@ -396,22 +415,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)
Expand Down Expand Up @@ -1336,6 +1343,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;
Expand Down
3 changes: 3 additions & 0 deletions include/linux/thermal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit d7203ee

Please sign in to comment.