thermal/core: Add critical and hot ops
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
This commit is contained in:
parent
433178e758
commit
d7203eedf4
@ -380,6 +380,25 @@ static void thermal_emergency_poweroff(void)
|
|||||||
msecs_to_jiffies(poweroff_delay_ms));
|
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,
|
static void handle_critical_trips(struct thermal_zone_device *tz,
|
||||||
int trip, enum thermal_trip_type trip_type)
|
int trip, enum thermal_trip_type trip_type)
|
||||||
{
|
{
|
||||||
@ -396,22 +415,10 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
|
|||||||
if (tz->ops->notify)
|
if (tz->ops->notify)
|
||||||
tz->ops->notify(tz, trip, trip_type);
|
tz->ops->notify(tz, trip, trip_type);
|
||||||
|
|
||||||
if (trip_type == THERMAL_TRIP_CRITICAL) {
|
if (trip_type == THERMAL_TRIP_HOT && tz->ops->hot)
|
||||||
dev_emerg(&tz->device,
|
tz->ops->hot(tz);
|
||||||
"critical temperature reached (%d C), shutting down\n",
|
else if (trip_type == THERMAL_TRIP_CRITICAL)
|
||||||
tz->temperature / 1000);
|
tz->ops->critical(tz);
|
||||||
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_thermal_trip(struct thermal_zone_device *tz, int trip)
|
static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
||||||
@ -1336,6 +1343,10 @@ thermal_zone_device_register(const char *type, int trips, int mask,
|
|||||||
|
|
||||||
tz->id = id;
|
tz->id = id;
|
||||||
strlcpy(tz->type, type, sizeof(tz->type));
|
strlcpy(tz->type, type, sizeof(tz->type));
|
||||||
|
|
||||||
|
if (!ops->critical)
|
||||||
|
ops->critical = thermal_zone_device_critical;
|
||||||
|
|
||||||
tz->ops = ops;
|
tz->ops = ops;
|
||||||
tz->tzp = tzp;
|
tz->tzp = tzp;
|
||||||
tz->device.class = &thermal_class;
|
tz->device.class = &thermal_class;
|
||||||
|
@ -79,6 +79,8 @@ struct thermal_zone_device_ops {
|
|||||||
enum thermal_trend *);
|
enum thermal_trend *);
|
||||||
int (*notify) (struct thermal_zone_device *, int,
|
int (*notify) (struct thermal_zone_device *, int,
|
||||||
enum thermal_trip_type);
|
enum thermal_trip_type);
|
||||||
|
void (*hot)(struct thermal_zone_device *);
|
||||||
|
void (*critical)(struct thermal_zone_device *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct thermal_cooling_device_ops {
|
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);
|
void thermal_notify_framework(struct thermal_zone_device *, int);
|
||||||
int thermal_zone_device_enable(struct thermal_zone_device *tz);
|
int thermal_zone_device_enable(struct thermal_zone_device *tz);
|
||||||
int thermal_zone_device_disable(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
|
#else
|
||||||
static inline struct thermal_zone_device *thermal_zone_device_register(
|
static inline struct thermal_zone_device *thermal_zone_device_register(
|
||||||
const char *type, int trips, int mask, void *devdata,
|
const char *type, int trips, int mask, void *devdata,
|
||||||
|
Loading…
Reference in New Issue
Block a user