Commit 94be1d27 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

thermal: gov_power_allocator: Use trip pointers instead of trip indices

Modify the power allocator thermal governor to use trip pointers instead
of trip indices everywhere except for the power_allocator_throttle()
second argument that will be changed subsequently along with the
definition of the .throttle() governor callback.

The general functionality is not expected to be changed.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: default avatarLukasz Luba <lukasz.luba@arm.com>
Tested-by: default avatarLukasz Luba <lukasz.luba@arm.com>
parent 276f1ede
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#include "thermal_core.h" #include "thermal_core.h"
#define INVALID_TRIP -1
#define FRAC_BITS 10 #define FRAC_BITS 10
#define int_to_frac(x) ((x) << FRAC_BITS) #define int_to_frac(x) ((x) << FRAC_BITS)
#define frac_to_int(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) ...@@ -55,23 +53,23 @@ static inline s64 div_frac(s64 x, s64 y)
* @err_integral: accumulated error in the PID controller. * @err_integral: accumulated error in the PID controller.
* @prev_err: error in the previous iteration of the PID controller. * @prev_err: error in the previous iteration of the PID controller.
* Used to calculate the derivative term. * 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 * @trip_switch_on: first passive trip point of the thermal zone. The
* governor switches on when this trip point is crossed. * governor switches on when this trip point is crossed.
* If the thermal zone only has one passive trip point, * 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 * @trip_max_desired_temperature: last passive trip point of the thermal
* zone. The temperature we are * zone. The temperature we are
* controlling for. * controlling for.
* @sustainable_power: Sustainable power (heat) that this thermal zone can
* dissipate
*/ */
struct power_allocator_params { struct power_allocator_params {
bool allocated_tzp; bool allocated_tzp;
s64 err_integral; s64 err_integral;
s32 prev_err; s32 prev_err;
int trip_switch_on;
int trip_max_desired_temperature;
u32 sustainable_power; 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) ...@@ -90,14 +88,12 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz)
u32 sustainable_power = 0; u32 sustainable_power = 0;
struct thermal_instance *instance; struct thermal_instance *instance;
struct power_allocator_params *params = tz->governor_data; 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) { list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
struct thermal_cooling_device *cdev = instance->cdev; struct thermal_cooling_device *cdev = instance->cdev;
u32 min_power; u32 min_power;
if (instance->trip != trip_max_desired_temperature) if (instance->trip != params->trip_max_desired_temperature)
continue; continue;
if (!cdev_is_power_actor(cdev)) if (!cdev_is_power_actor(cdev))
...@@ -116,24 +112,22 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz) ...@@ -116,24 +112,22 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz)
* estimate_pid_constants() - Estimate the constants for the PID controller * estimate_pid_constants() - Estimate the constants for the PID controller
* @tz: thermal zone for which to estimate the constants * @tz: thermal zone for which to estimate the constants
* @sustainable_power: sustainable power for the thermal zone * @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 * @control_temp: target temperature for the power allocator governor
* *
* This function is used to update the estimation of the PID * This function is used to update the estimation of the PID
* controller constants in struct thermal_zone_parameters. * controller constants in struct thermal_zone_parameters.
*/ */
static void estimate_pid_constants(struct thermal_zone_device *tz, 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) int control_temp)
{ {
struct thermal_trip trip;
u32 temperature_threshold = control_temp; u32 temperature_threshold = control_temp;
int ret;
s32 k_i; s32 k_i;
ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip); if (trip_switch_on)
if (!ret) temperature_threshold -= trip_switch_on->temperature;
temperature_threshold -= trip.temperature;
/* /*
* estimate_pid_constants() tries to find appropriate default * estimate_pid_constants() tries to find appropriate default
...@@ -386,7 +380,7 @@ static int allocate_power(struct thermal_zone_device *tz, ...@@ -386,7 +380,7 @@ static int allocate_power(struct thermal_zone_device *tz,
struct thermal_instance *instance; struct thermal_instance *instance;
struct power_allocator_params *params = tz->governor_data; struct power_allocator_params *params = tz->governor_data;
const struct thermal_trip *trip_max_desired_temperature = 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 *req_power, *max_power, *granted_power, *extra_actor_power;
u32 *weighted_req_power; u32 *weighted_req_power;
u32 total_req_power, max_allocatable_power, total_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, ...@@ -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 * @tz: thermal zone to operate on
* @params: pointer to private data for this governor * @params: pointer to private data for this governor
* *
...@@ -513,46 +507,36 @@ static int allocate_power(struct thermal_zone_device *tz, ...@@ -513,46 +507,36 @@ static int allocate_power(struct thermal_zone_device *tz,
static void get_governor_trips(struct thermal_zone_device *tz, static void get_governor_trips(struct thermal_zone_device *tz,
struct power_allocator_params *params) struct power_allocator_params *params)
{ {
int i, last_active, last_passive; const struct thermal_trip *first_passive = NULL;
bool found_first_passive; const struct thermal_trip *last_passive = NULL;
const struct thermal_trip *last_active = NULL;
found_first_passive = false; const struct thermal_trip *trip;
last_active = INVALID_TRIP;
last_passive = INVALID_TRIP; for_each_trip(tz, trip) {
switch (trip->type) {
for (i = 0; i < tz->num_trips; i++) { case THERMAL_TRIP_PASSIVE:
struct thermal_trip trip; if (!first_passive) {
int ret; first_passive = trip;
break;
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;
} }
} else if (trip.type == THERMAL_TRIP_ACTIVE) { last_passive = trip;
last_active = i; break;
} else { case THERMAL_TRIP_ACTIVE:
last_active = trip;
break;
default:
break; break;
} }
} }
if (last_passive != INVALID_TRIP) { if (last_passive) {
params->trip_switch_on = first_passive;
params->trip_max_desired_temperature = last_passive; params->trip_max_desired_temperature = last_passive;
} else if (found_first_passive) { } else if (first_passive) {
params->trip_max_desired_temperature = params->trip_switch_on; params->trip_switch_on = NULL;
params->trip_switch_on = INVALID_TRIP; params->trip_max_desired_temperature = first_passive;
} else { } else {
params->trip_switch_on = INVALID_TRIP; params->trip_switch_on = NULL;
params->trip_max_desired_temperature = last_active; params->trip_max_desired_temperature = last_active;
} }
} }
...@@ -567,14 +551,12 @@ static void allow_maximum_power(struct thermal_zone_device *tz, bool update) ...@@ -567,14 +551,12 @@ static void allow_maximum_power(struct thermal_zone_device *tz, bool update)
{ {
struct thermal_instance *instance; struct thermal_instance *instance;
struct power_allocator_params *params = tz->governor_data; 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; u32 req_power;
list_for_each_entry(instance, &tz->thermal_instances, tz_node) { list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
struct thermal_cooling_device *cdev = instance->cdev; 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))) (!cdev_is_power_actor(instance->cdev)))
continue; continue;
...@@ -636,7 +618,6 @@ static int power_allocator_bind(struct thermal_zone_device *tz) ...@@ -636,7 +618,6 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
{ {
int ret; int ret;
struct power_allocator_params *params; struct power_allocator_params *params;
struct thermal_trip trip;
ret = check_power_actors(tz); ret = check_power_actors(tz);
if (ret) if (ret)
...@@ -661,13 +642,11 @@ static int power_allocator_bind(struct thermal_zone_device *tz) ...@@ -661,13 +642,11 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
get_governor_trips(tz, params); get_governor_trips(tz, params);
if (tz->num_trips > 0) { if (params->trip_max_desired_temperature) {
ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, int temp = params->trip_max_desired_temperature->temperature;
&trip);
if (!ret) estimate_pid_constants(tz, tz->tzp->sustainable_power,
estimate_pid_constants(tz, tz->tzp->sustainable_power, params->trip_switch_on, temp);
params->trip_switch_on,
trip.temperature);
} }
reset_pid_controller(params); reset_pid_controller(params);
...@@ -697,11 +676,10 @@ static void power_allocator_unbind(struct thermal_zone_device *tz) ...@@ -697,11 +676,10 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
tz->governor_data = NULL; 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, int trip_index)
{ {
struct power_allocator_params *params = tz->governor_data; struct power_allocator_params *params = tz->governor_data;
struct thermal_trip trip; const struct thermal_trip *trip = &tz->trips[trip_index];
int ret;
bool update; bool update;
lockdep_assert_held(&tz->lock); lockdep_assert_held(&tz->lock);
...@@ -710,12 +688,12 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id) ...@@ -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 * We get called for every trip point but we only need to do
* our calculations once * our calculations once
*/ */
if (trip_id != params->trip_max_desired_temperature) if (trip != params->trip_max_desired_temperature)
return 0; return 0;
ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip); trip = params->trip_switch_on;
if (!ret && (tz->temperature < trip.temperature)) { if (trip && tz->temperature < trip->temperature) {
update = (tz->last_temperature >= trip.temperature); update = tz->last_temperature >= trip->temperature;
tz->passive = 0; tz->passive = 0;
reset_pid_controller(params); reset_pid_controller(params);
allow_maximum_power(tz, update); allow_maximum_power(tz, update);
...@@ -724,14 +702,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id) ...@@ -724,14 +702,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
tz->passive = 1; tz->passive = 1;
ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip); return allocate_power(tz, params->trip_max_desired_temperature->temperature);
if (ret) {
dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n",
ret);
return ret;
}
return allocate_power(tz, trip.temperature);
} }
static struct thermal_governor thermal_gov_power_allocator = { static struct thermal_governor thermal_gov_power_allocator = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment