mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
Merge branch 'thermal-core'
Merge thermal core changes for 6.7-rc1: - Use trip pointers in thermal governors and in the related part of the thermal core (Rafael Wysocki). - Avoid updating trip points when the thermal zone temperature falls into a trip point's hysteresis range (ícolas F. R. A. Prado). * thermal-core: thermal: ACPI: Include the right header file thermal: core: Don't update trip points inside the hysteresis range thermal: core: Pass trip pointer to governor throttle callback thermal: gov_step_wise: Fold update_passive_instance() into its caller thermal: gov_power_allocator: Use trip pointers instead of trip indices thermal: gov_fair_share: Rearrange get_trip_level() thermal: trip: Define for_each_trip() macro thermal: trip: Simplify computing trip indices
This commit is contained in:
commit
598c20f964
@ -13,9 +13,10 @@
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_index)
|
||||
static int thermal_zone_trip_update(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
const struct thermal_trip *trip = &tz->trips[trip_index];
|
||||
int trip_index = thermal_zone_trip_id(tz, trip);
|
||||
struct thermal_instance *instance;
|
||||
|
||||
if (!trip->hysteresis)
|
||||
@ -89,7 +90,8 @@ static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_ind
|
||||
* (trip_temp - hyst) so that the fan gets turned off again.
|
||||
*
|
||||
*/
|
||||
static int bang_bang_control(struct thermal_zone_device *tz, int trip)
|
||||
static int bang_bang_control(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
struct thermal_instance *instance;
|
||||
int ret;
|
||||
|
@ -15,29 +15,27 @@
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
/**
|
||||
* get_trip_level: - obtains the current trip level for a zone
|
||||
* @tz: thermal zone device
|
||||
*/
|
||||
static int get_trip_level(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_trip trip;
|
||||
int count;
|
||||
const struct thermal_trip *trip, *level_trip = NULL;
|
||||
int trip_level;
|
||||
|
||||
for (count = 0; count < tz->num_trips; count++) {
|
||||
__thermal_zone_get_trip(tz, count, &trip);
|
||||
if (tz->temperature < trip.temperature)
|
||||
for_each_trip(tz, trip) {
|
||||
if (trip->temperature >= tz->temperature)
|
||||
break;
|
||||
|
||||
level_trip = trip;
|
||||
}
|
||||
|
||||
/*
|
||||
* count > 0 only if temperature is greater than first trip
|
||||
* point, in which case, trip_point = count - 1
|
||||
*/
|
||||
if (count > 0)
|
||||
trace_thermal_zone_trip(tz, count - 1, trip.type);
|
||||
/* Bail out if the temperature is not greater than any trips. */
|
||||
if (!level_trip)
|
||||
return 0;
|
||||
|
||||
return count;
|
||||
trip_level = thermal_zone_trip_id(tz, level_trip);
|
||||
|
||||
trace_thermal_zone_trip(tz, trip_level, level_trip->type);
|
||||
|
||||
return trip_level;
|
||||
}
|
||||
|
||||
static long get_target_state(struct thermal_zone_device *tz,
|
||||
@ -49,7 +47,7 @@ static long get_target_state(struct thermal_zone_device *tz,
|
||||
/**
|
||||
* fair_share_throttle - throttles devices associated with the given zone
|
||||
* @tz: thermal_zone_device
|
||||
* @trip_index: trip point index
|
||||
* @trip: trip point
|
||||
*
|
||||
* Throttling Logic: This uses three parameters to calculate the new
|
||||
* throttle state of the cooling devices associated with the given zone.
|
||||
@ -65,9 +63,9 @@ static long get_target_state(struct thermal_zone_device *tz,
|
||||
* (Heavily assumes the trip points are in ascending order)
|
||||
* new_state of cooling device = P3 * P2 * P1
|
||||
*/
|
||||
static int fair_share_throttle(struct thermal_zone_device *tz, int trip_index)
|
||||
static int fair_share_throttle(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
const struct thermal_trip *trip = &tz->trips[trip_index];
|
||||
struct thermal_instance *instance;
|
||||
int total_weight = 0;
|
||||
int total_instance = 0;
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
#define INVALID_TRIP -1
|
||||
|
||||
#define FRAC_BITS 10
|
||||
#define int_to_frac(x) ((x) << FRAC_BITS)
|
||||
#define frac_to_int(x) ((x) >> FRAC_BITS)
|
||||
@ -55,23 +53,23 @@ static inline s64 div_frac(s64 x, s64 y)
|
||||
* @err_integral: accumulated error in the PID controller.
|
||||
* @prev_err: error in the previous iteration of the PID controller.
|
||||
* Used to calculate the derivative term.
|
||||
* @sustainable_power: Sustainable power (heat) that this thermal zone can
|
||||
* dissipate
|
||||
* @trip_switch_on: first passive trip point of the thermal zone. The
|
||||
* governor switches on when this trip point is crossed.
|
||||
* If the thermal zone only has one passive trip point,
|
||||
* @trip_switch_on should be INVALID_TRIP.
|
||||
* @trip_switch_on should be NULL.
|
||||
* @trip_max_desired_temperature: last passive trip point of the thermal
|
||||
* zone. The temperature we are
|
||||
* controlling for.
|
||||
* @sustainable_power: Sustainable power (heat) that this thermal zone can
|
||||
* dissipate
|
||||
*/
|
||||
struct power_allocator_params {
|
||||
bool allocated_tzp;
|
||||
s64 err_integral;
|
||||
s32 prev_err;
|
||||
int trip_switch_on;
|
||||
int trip_max_desired_temperature;
|
||||
u32 sustainable_power;
|
||||
const struct thermal_trip *trip_switch_on;
|
||||
const struct thermal_trip *trip_max_desired_temperature;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -90,14 +88,12 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz)
|
||||
u32 sustainable_power = 0;
|
||||
struct thermal_instance *instance;
|
||||
struct power_allocator_params *params = tz->governor_data;
|
||||
const struct thermal_trip *trip_max_desired_temperature =
|
||||
&tz->trips[params->trip_max_desired_temperature];
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
||||
struct thermal_cooling_device *cdev = instance->cdev;
|
||||
u32 min_power;
|
||||
|
||||
if (instance->trip != trip_max_desired_temperature)
|
||||
if (instance->trip != params->trip_max_desired_temperature)
|
||||
continue;
|
||||
|
||||
if (!cdev_is_power_actor(cdev))
|
||||
@ -116,24 +112,22 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz)
|
||||
* estimate_pid_constants() - Estimate the constants for the PID controller
|
||||
* @tz: thermal zone for which to estimate the constants
|
||||
* @sustainable_power: sustainable power for the thermal zone
|
||||
* @trip_switch_on: trip point number for the switch on temperature
|
||||
* @trip_switch_on: trip point for the switch on temperature
|
||||
* @control_temp: target temperature for the power allocator governor
|
||||
*
|
||||
* This function is used to update the estimation of the PID
|
||||
* controller constants in struct thermal_zone_parameters.
|
||||
*/
|
||||
static void estimate_pid_constants(struct thermal_zone_device *tz,
|
||||
u32 sustainable_power, int trip_switch_on,
|
||||
u32 sustainable_power,
|
||||
const struct thermal_trip *trip_switch_on,
|
||||
int control_temp)
|
||||
{
|
||||
struct thermal_trip trip;
|
||||
u32 temperature_threshold = control_temp;
|
||||
int ret;
|
||||
s32 k_i;
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip);
|
||||
if (!ret)
|
||||
temperature_threshold -= trip.temperature;
|
||||
if (trip_switch_on)
|
||||
temperature_threshold -= trip_switch_on->temperature;
|
||||
|
||||
/*
|
||||
* estimate_pid_constants() tries to find appropriate default
|
||||
@ -386,7 +380,7 @@ static int allocate_power(struct thermal_zone_device *tz,
|
||||
struct thermal_instance *instance;
|
||||
struct power_allocator_params *params = tz->governor_data;
|
||||
const struct thermal_trip *trip_max_desired_temperature =
|
||||
&tz->trips[params->trip_max_desired_temperature];
|
||||
params->trip_max_desired_temperature;
|
||||
u32 *req_power, *max_power, *granted_power, *extra_actor_power;
|
||||
u32 *weighted_req_power;
|
||||
u32 total_req_power, max_allocatable_power, total_weighted_req_power;
|
||||
@ -496,7 +490,7 @@ static int allocate_power(struct thermal_zone_device *tz,
|
||||
}
|
||||
|
||||
/**
|
||||
* get_governor_trips() - get the number of the two trip points that are key for this governor
|
||||
* get_governor_trips() - get the two trip points that are key for this governor
|
||||
* @tz: thermal zone to operate on
|
||||
* @params: pointer to private data for this governor
|
||||
*
|
||||
@ -513,46 +507,36 @@ static int allocate_power(struct thermal_zone_device *tz,
|
||||
static void get_governor_trips(struct thermal_zone_device *tz,
|
||||
struct power_allocator_params *params)
|
||||
{
|
||||
int i, last_active, last_passive;
|
||||
bool found_first_passive;
|
||||
const struct thermal_trip *first_passive = NULL;
|
||||
const struct thermal_trip *last_passive = NULL;
|
||||
const struct thermal_trip *last_active = NULL;
|
||||
const struct thermal_trip *trip;
|
||||
|
||||
found_first_passive = false;
|
||||
last_active = INVALID_TRIP;
|
||||
last_passive = INVALID_TRIP;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
struct thermal_trip trip;
|
||||
int ret;
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret) {
|
||||
dev_warn(&tz->device,
|
||||
"Failed to get trip point %d type: %d\n", i,
|
||||
ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trip.type == THERMAL_TRIP_PASSIVE) {
|
||||
if (!found_first_passive) {
|
||||
params->trip_switch_on = i;
|
||||
found_first_passive = true;
|
||||
} else {
|
||||
last_passive = i;
|
||||
for_each_trip(tz, trip) {
|
||||
switch (trip->type) {
|
||||
case THERMAL_TRIP_PASSIVE:
|
||||
if (!first_passive) {
|
||||
first_passive = trip;
|
||||
break;
|
||||
}
|
||||
} else if (trip.type == THERMAL_TRIP_ACTIVE) {
|
||||
last_active = i;
|
||||
} else {
|
||||
last_passive = trip;
|
||||
break;
|
||||
case THERMAL_TRIP_ACTIVE:
|
||||
last_active = trip;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (last_passive != INVALID_TRIP) {
|
||||
if (last_passive) {
|
||||
params->trip_switch_on = first_passive;
|
||||
params->trip_max_desired_temperature = last_passive;
|
||||
} else if (found_first_passive) {
|
||||
params->trip_max_desired_temperature = params->trip_switch_on;
|
||||
params->trip_switch_on = INVALID_TRIP;
|
||||
} else if (first_passive) {
|
||||
params->trip_switch_on = NULL;
|
||||
params->trip_max_desired_temperature = first_passive;
|
||||
} else {
|
||||
params->trip_switch_on = INVALID_TRIP;
|
||||
params->trip_switch_on = NULL;
|
||||
params->trip_max_desired_temperature = last_active;
|
||||
}
|
||||
}
|
||||
@ -567,14 +551,12 @@ static void allow_maximum_power(struct thermal_zone_device *tz, bool update)
|
||||
{
|
||||
struct thermal_instance *instance;
|
||||
struct power_allocator_params *params = tz->governor_data;
|
||||
const struct thermal_trip *trip_max_desired_temperature =
|
||||
&tz->trips[params->trip_max_desired_temperature];
|
||||
u32 req_power;
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
||||
struct thermal_cooling_device *cdev = instance->cdev;
|
||||
|
||||
if ((instance->trip != trip_max_desired_temperature) ||
|
||||
if (instance->trip != params->trip_max_desired_temperature ||
|
||||
(!cdev_is_power_actor(instance->cdev)))
|
||||
continue;
|
||||
|
||||
@ -636,7 +618,6 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
|
||||
{
|
||||
int ret;
|
||||
struct power_allocator_params *params;
|
||||
struct thermal_trip trip;
|
||||
|
||||
ret = check_power_actors(tz);
|
||||
if (ret)
|
||||
@ -661,13 +642,11 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
|
||||
|
||||
get_governor_trips(tz, params);
|
||||
|
||||
if (tz->num_trips > 0) {
|
||||
ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
|
||||
&trip);
|
||||
if (!ret)
|
||||
estimate_pid_constants(tz, tz->tzp->sustainable_power,
|
||||
params->trip_switch_on,
|
||||
trip.temperature);
|
||||
if (params->trip_max_desired_temperature) {
|
||||
int temp = params->trip_max_desired_temperature->temperature;
|
||||
|
||||
estimate_pid_constants(tz, tz->tzp->sustainable_power,
|
||||
params->trip_switch_on, temp);
|
||||
}
|
||||
|
||||
reset_pid_controller(params);
|
||||
@ -697,11 +676,10 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
|
||||
tz->governor_data = NULL;
|
||||
}
|
||||
|
||||
static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
|
||||
static int power_allocator_throttle(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
struct power_allocator_params *params = tz->governor_data;
|
||||
struct thermal_trip trip;
|
||||
int ret;
|
||||
bool update;
|
||||
|
||||
lockdep_assert_held(&tz->lock);
|
||||
@ -710,12 +688,12 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
|
||||
* We get called for every trip point but we only need to do
|
||||
* our calculations once
|
||||
*/
|
||||
if (trip_id != params->trip_max_desired_temperature)
|
||||
if (trip != params->trip_max_desired_temperature)
|
||||
return 0;
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip);
|
||||
if (!ret && (tz->temperature < trip.temperature)) {
|
||||
update = (tz->last_temperature >= trip.temperature);
|
||||
trip = params->trip_switch_on;
|
||||
if (trip && tz->temperature < trip->temperature) {
|
||||
update = tz->last_temperature >= trip->temperature;
|
||||
tz->passive = 0;
|
||||
reset_pid_controller(params);
|
||||
allow_maximum_power(tz, update);
|
||||
@ -724,14 +702,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
|
||||
|
||||
tz->passive = 1;
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip);
|
||||
if (ret) {
|
||||
dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return allocate_power(tz, trip.temperature);
|
||||
return allocate_power(tz, params->trip_max_desired_temperature->temperature);
|
||||
}
|
||||
|
||||
static struct thermal_governor thermal_gov_power_allocator = {
|
||||
|
@ -68,26 +68,16 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
return next_target;
|
||||
}
|
||||
|
||||
static void update_passive_instance(struct thermal_zone_device *tz,
|
||||
enum thermal_trip_type type, int value)
|
||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
/*
|
||||
* If value is +1, activate a passive instance.
|
||||
* If value is -1, deactivate a passive instance.
|
||||
*/
|
||||
if (type == THERMAL_TRIP_PASSIVE)
|
||||
tz->passive += value;
|
||||
}
|
||||
|
||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id)
|
||||
{
|
||||
const struct thermal_trip *trip = &tz->trips[trip_id];
|
||||
int trip_id = thermal_zone_trip_id(tz, trip);
|
||||
enum thermal_trend trend;
|
||||
struct thermal_instance *instance;
|
||||
bool throttle = false;
|
||||
int old_target;
|
||||
|
||||
trend = get_tz_trend(tz, trip_id);
|
||||
trend = get_tz_trend(tz, trip);
|
||||
|
||||
if (tz->temperature >= trip->temperature) {
|
||||
throttle = true;
|
||||
@ -109,14 +99,17 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id
|
||||
if (instance->initialized && old_target == instance->target)
|
||||
continue;
|
||||
|
||||
/* Activate a passive thermal instance */
|
||||
if (old_target == THERMAL_NO_TARGET &&
|
||||
instance->target != THERMAL_NO_TARGET)
|
||||
update_passive_instance(tz, trip->type, 1);
|
||||
/* Deactivate a passive thermal instance */
|
||||
else if (old_target != THERMAL_NO_TARGET &&
|
||||
instance->target == THERMAL_NO_TARGET)
|
||||
update_passive_instance(tz, trip->type, -1);
|
||||
instance->target != THERMAL_NO_TARGET) {
|
||||
/* Activate a passive thermal instance */
|
||||
if (trip->type == THERMAL_TRIP_PASSIVE)
|
||||
tz->passive++;
|
||||
} else if (old_target != THERMAL_NO_TARGET &&
|
||||
instance->target == THERMAL_NO_TARGET) {
|
||||
/* Deactivate a passive thermal instance */
|
||||
if (trip->type == THERMAL_TRIP_PASSIVE)
|
||||
tz->passive--;
|
||||
}
|
||||
|
||||
instance->initialized = true;
|
||||
mutex_lock(&instance->cdev->lock);
|
||||
@ -128,7 +121,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id
|
||||
/**
|
||||
* step_wise_throttle - throttles devices associated with the given zone
|
||||
* @tz: thermal_zone_device
|
||||
* @trip: trip point index
|
||||
* @trip: trip point
|
||||
*
|
||||
* Throttling Logic: This uses the trend of the thermal zone to throttle.
|
||||
* If the thermal zone is 'heating up' this throttles all the cooling
|
||||
@ -136,7 +129,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id
|
||||
* step. If the zone is 'cooling down' it brings back the performance of
|
||||
* the devices by one step.
|
||||
*/
|
||||
static int step_wise_throttle(struct thermal_zone_device *tz, int trip)
|
||||
static int step_wise_throttle(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
struct thermal_instance *instance;
|
||||
|
||||
|
@ -25,11 +25,12 @@ static int user_space_bind(struct thermal_zone_device *tz)
|
||||
/**
|
||||
* notify_user_space - Notifies user space about thermal events
|
||||
* @tz: thermal_zone_device
|
||||
* @trip: trip point index
|
||||
* @trip: trip point
|
||||
*
|
||||
* This function notifies the user space through UEvents.
|
||||
*/
|
||||
static int notify_user_space(struct thermal_zone_device *tz, int trip)
|
||||
static int notify_user_space(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
char *thermal_prop[5];
|
||||
int i;
|
||||
@ -38,7 +39,8 @@ static int notify_user_space(struct thermal_zone_device *tz, int trip)
|
||||
|
||||
thermal_prop[0] = kasprintf(GFP_KERNEL, "NAME=%s", tz->type);
|
||||
thermal_prop[1] = kasprintf(GFP_KERNEL, "TEMP=%d", tz->temperature);
|
||||
thermal_prop[2] = kasprintf(GFP_KERNEL, "TRIP=%d", trip);
|
||||
thermal_prop[2] = kasprintf(GFP_KERNEL, "TRIP=%d",
|
||||
thermal_zone_trip_id(tz, trip));
|
||||
thermal_prop[3] = kasprintf(GFP_KERNEL, "EVENT=%d", tz->notify_event);
|
||||
thermal_prop[4] = NULL;
|
||||
kobject_uevent_env(&tz->device.kobj, KOBJ_CHANGE, thermal_prop);
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "thermal_core.h"
|
||||
#include <linux/thermal.h>
|
||||
|
||||
/*
|
||||
* Minimum temperature for full military grade is 218°K (-55°C) and
|
||||
|
@ -307,7 +307,8 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
|
||||
thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies);
|
||||
}
|
||||
|
||||
static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip)
|
||||
static void handle_non_critical_trips(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
tz->governor ? tz->governor->throttle(tz, trip) :
|
||||
def_governor->throttle(tz, trip);
|
||||
@ -329,44 +330,43 @@ void thermal_zone_device_critical(struct thermal_zone_device *tz)
|
||||
EXPORT_SYMBOL(thermal_zone_device_critical);
|
||||
|
||||
static void handle_critical_trips(struct thermal_zone_device *tz,
|
||||
int trip, int trip_temp, enum thermal_trip_type trip_type)
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
/* If we have not crossed the trip_temp, we do not care. */
|
||||
if (trip_temp <= 0 || tz->temperature < trip_temp)
|
||||
if (trip->temperature <= 0 || tz->temperature < trip->temperature)
|
||||
return;
|
||||
|
||||
trace_thermal_zone_trip(tz, trip, trip_type);
|
||||
trace_thermal_zone_trip(tz, thermal_zone_trip_id(tz, trip), trip->type);
|
||||
|
||||
if (trip_type == THERMAL_TRIP_HOT && tz->ops->hot)
|
||||
tz->ops->hot(tz);
|
||||
else if (trip_type == THERMAL_TRIP_CRITICAL)
|
||||
if (trip->type == THERMAL_TRIP_CRITICAL)
|
||||
tz->ops->critical(tz);
|
||||
else if (tz->ops->hot)
|
||||
tz->ops->hot(tz);
|
||||
}
|
||||
|
||||
static void handle_thermal_trip(struct thermal_zone_device *tz, int trip_id)
|
||||
static void handle_thermal_trip(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
struct thermal_trip trip;
|
||||
|
||||
__thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
|
||||
if (trip.temperature == THERMAL_TEMP_INVALID)
|
||||
if (trip->temperature == THERMAL_TEMP_INVALID)
|
||||
return;
|
||||
|
||||
if (tz->last_temperature != THERMAL_TEMP_INVALID) {
|
||||
if (tz->last_temperature < trip.temperature &&
|
||||
tz->temperature >= trip.temperature)
|
||||
thermal_notify_tz_trip_up(tz->id, trip_id,
|
||||
if (tz->last_temperature < trip->temperature &&
|
||||
tz->temperature >= trip->temperature)
|
||||
thermal_notify_tz_trip_up(tz->id,
|
||||
thermal_zone_trip_id(tz, trip),
|
||||
tz->temperature);
|
||||
if (tz->last_temperature >= trip.temperature &&
|
||||
tz->temperature < (trip.temperature - trip.hysteresis))
|
||||
thermal_notify_tz_trip_down(tz->id, trip_id,
|
||||
if (tz->last_temperature >= trip->temperature &&
|
||||
tz->temperature < trip->temperature - trip->hysteresis)
|
||||
thermal_notify_tz_trip_down(tz->id,
|
||||
thermal_zone_trip_id(tz, trip),
|
||||
tz->temperature);
|
||||
}
|
||||
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL || trip.type == THERMAL_TRIP_HOT)
|
||||
handle_critical_trips(tz, trip_id, trip.temperature, trip.type);
|
||||
if (trip->type == THERMAL_TRIP_CRITICAL || trip->type == THERMAL_TRIP_HOT)
|
||||
handle_critical_trips(tz, trip);
|
||||
else
|
||||
handle_non_critical_trips(tz, trip_id);
|
||||
handle_non_critical_trips(tz, trip);
|
||||
}
|
||||
|
||||
static void update_temperature(struct thermal_zone_device *tz)
|
||||
@ -403,7 +403,7 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
|
||||
void __thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
enum thermal_notify_event event)
|
||||
{
|
||||
int count;
|
||||
const struct thermal_trip *trip;
|
||||
|
||||
if (atomic_read(&in_suspend))
|
||||
return;
|
||||
@ -422,8 +422,8 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
|
||||
tz->notify_event = event;
|
||||
|
||||
for (count = 0; count < tz->num_trips; count++)
|
||||
handle_thermal_trip(tz, count);
|
||||
for_each_trip(tz, trip)
|
||||
handle_thermal_trip(tz, trip);
|
||||
|
||||
monitor_thermal_zone(tz);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
|
||||
void thermal_cdev_update(struct thermal_cooling_device *);
|
||||
void __thermal_cdev_update(struct thermal_cooling_device *cdev);
|
||||
|
||||
int get_tz_trend(struct thermal_zone_device *tz, int trip_index);
|
||||
int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip);
|
||||
|
||||
struct thermal_instance *
|
||||
get_thermal_instance(struct thermal_zone_device *tz,
|
||||
@ -116,6 +116,9 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
enum thermal_notify_event event);
|
||||
|
||||
/* Helpers */
|
||||
#define for_each_trip(__tz, __trip) \
|
||||
for (__trip = __tz->trips; __trip - __tz->trips < __tz->num_trips; __trip++)
|
||||
|
||||
void __thermal_zone_set_trips(struct thermal_zone_device *tz);
|
||||
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
struct thermal_trip *trip);
|
||||
|
@ -22,9 +22,8 @@
|
||||
#include "thermal_core.h"
|
||||
#include "thermal_trace.h"
|
||||
|
||||
int get_tz_trend(struct thermal_zone_device *tz, int trip_index)
|
||||
int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip)
|
||||
{
|
||||
struct thermal_trip *trip = tz->trips ? &tz->trips[trip_index] : NULL;
|
||||
enum thermal_trend trend;
|
||||
|
||||
if (tz->emul_temperature || !tz->ops->get_trend ||
|
||||
|
@ -13,10 +13,11 @@ int for_each_thermal_trip(struct thermal_zone_device *tz,
|
||||
int (*cb)(struct thermal_trip *, void *),
|
||||
void *data)
|
||||
{
|
||||
int i, ret;
|
||||
struct thermal_trip *trip;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
ret = cb(&tz->trips[i], data);
|
||||
for_each_trip(tz, trip) {
|
||||
ret = cb(trip, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -64,6 +65,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_trip trip;
|
||||
int low = -INT_MAX, high = INT_MAX;
|
||||
bool same_trip = false;
|
||||
int i, ret;
|
||||
|
||||
lockdep_assert_held(&tz->lock);
|
||||
@ -72,6 +74,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||
return;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
bool low_set = false;
|
||||
int trip_low;
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, i , &trip);
|
||||
@ -80,18 +83,31 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||
|
||||
trip_low = trip.temperature - trip.hysteresis;
|
||||
|
||||
if (trip_low < tz->temperature && trip_low > low)
|
||||
if (trip_low < tz->temperature && trip_low > low) {
|
||||
low = trip_low;
|
||||
low_set = true;
|
||||
same_trip = false;
|
||||
}
|
||||
|
||||
if (trip.temperature > tz->temperature &&
|
||||
trip.temperature < high)
|
||||
trip.temperature < high) {
|
||||
high = trip.temperature;
|
||||
same_trip = low_set;
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to change trip points */
|
||||
if (tz->prev_low_trip == low && tz->prev_high_trip == high)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If "high" and "low" are the same, skip the change unless this is the
|
||||
* first time.
|
||||
*/
|
||||
if (same_trip && (tz->prev_low_trip != -INT_MAX ||
|
||||
tz->prev_high_trip != INT_MAX))
|
||||
return;
|
||||
|
||||
tz->prev_low_trip = low;
|
||||
tz->prev_high_trip = high;
|
||||
|
||||
@ -173,12 +189,9 @@ int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
int thermal_zone_trip_id(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
if (&tz->trips[i] == trip)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODATA;
|
||||
/*
|
||||
* Assume the trip to be located within the bounds of the thermal
|
||||
* zone's trips[] table.
|
||||
*/
|
||||
return trip - tz->trips;
|
||||
}
|
||||
|
@ -199,7 +199,8 @@ struct thermal_governor {
|
||||
char name[THERMAL_NAME_LENGTH];
|
||||
int (*bind_to_tz)(struct thermal_zone_device *tz);
|
||||
void (*unbind_from_tz)(struct thermal_zone_device *tz);
|
||||
int (*throttle)(struct thermal_zone_device *tz, int trip);
|
||||
int (*throttle)(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip);
|
||||
struct list_head governor_list;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user