diff options
Diffstat (limited to 'drivers/thermal/gov_power_allocator.c')
| -rw-r--r-- | drivers/thermal/gov_power_allocator.c | 577 |
1 files changed, 313 insertions, 264 deletions
diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index 13e375751d22..0d9f636c80f4 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -8,17 +8,14 @@ #define pr_fmt(fmt) "Power allocator: " fmt -#include <linux/rculist.h> #include <linux/slab.h> #include <linux/thermal.h> #define CREATE_TRACE_POINTS -#include <trace/events/thermal_power_allocator.h> +#include "thermal_trace_ipa.h" #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) @@ -50,31 +47,61 @@ static inline s64 div_frac(s64 x, s64 y) } /** + * struct power_actor - internal power information for power actor + * @req_power: requested power value (not weighted) + * @max_power: max allocatable power for this actor + * @granted_power: granted power for this actor + * @extra_actor_power: extra power that this actor can receive + * @weighted_req_power: weighted requested power as input to IPA + */ +struct power_actor { + u32 req_power; + u32 max_power; + u32 granted_power; + u32 extra_actor_power; + u32 weighted_req_power; +}; + +/** * struct power_allocator_params - parameters for the power allocator governor * @allocated_tzp: whether we have allocated tzp for this thermal zone and * it needs to be freed on unbind + * @update_cdevs: whether or not update cdevs on the next run * @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_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 + * @trip_switch_on should be NULL. + * @trip_max: last passive trip point of the thermal zone. The + * temperature we are controlling for. + * @total_weight: Sum of all thermal instances weights + * @num_actors: number of cooling devices supporting IPA callbacks + * @buffer_size: internal buffer size, to avoid runtime re-calculation + * @power: buffer for all power actors internal power information */ struct power_allocator_params { bool allocated_tzp; + bool update_cdevs; 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; + int total_weight; + unsigned int num_actors; + unsigned int buffer_size; + struct power_actor *power; }; +static bool power_actor_is_valid(struct thermal_instance *instance) +{ + return cdev_is_power_actor(instance->cdev); +} + /** * estimate_sustainable_power() - Estimate the sustainable power of a thermal zone * @tz: thermal zone we are operating in @@ -88,20 +115,18 @@ struct power_allocator_params { */ 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_desc *td = trip_to_trip_desc(params->trip_max); + struct thermal_cooling_device *cdev; + struct thermal_instance *instance; + u32 sustainable_power = 0; + u32 min_power; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - struct thermal_cooling_device *cdev = instance->cdev; - u32 min_power; - - if (instance->trip != params->trip_max_desired_temperature) - continue; - - if (!cdev_is_power_actor(cdev)) + list_for_each_entry(instance, &td->thermal_instances, trip_node) { + if (!power_actor_is_valid(instance)) continue; + cdev = instance->cdev; if (cdev->ops->state2power(cdev, instance->upper, &min_power)) continue; @@ -115,26 +140,23 @@ 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) { - int ret; - int switch_on_temp; - u32 temperature_threshold; + u32 temperature_threshold = control_temp; s32 k_i; - ret = tz->ops->get_trip_temp(tz, trip_switch_on, &switch_on_temp); - if (ret) - switch_on_temp = 0; + if (trip_switch_on) + temperature_threshold -= trip_switch_on->temperature; - temperature_threshold = control_temp - switch_on_temp; /* * estimate_pid_constants() tries to find appropriate default * values for thermal zones that don't provide them. If a @@ -218,10 +240,10 @@ static u32 pid_controller(struct thermal_zone_device *tz, int control_temp, u32 max_allocatable_power) { + struct power_allocator_params *params = tz->governor_data; s64 p, i, d, power_range; s32 err, max_power_frac; u32 sustainable_power; - struct power_allocator_params *params = tz->governor_data; max_power_frac = int_to_frac(max_allocatable_power); @@ -300,24 +322,18 @@ power_actor_set_power(struct thermal_cooling_device *cdev, return ret; instance->target = clamp_val(state, instance->lower, instance->upper); - mutex_lock(&cdev->lock); - __thermal_cdev_update(cdev); - mutex_unlock(&cdev->lock); + + thermal_cdev_update_nocheck(cdev); return 0; } /** * divvy_up_power() - divvy the allocated power between the actors - * @req_power: each actor's requested power - * @max_power: each actor's maximum available power - * @num_actors: size of the @req_power, @max_power and @granted_power's array - * @total_req_power: sum of @req_power + * @power: buffer for all power actors internal power information + * @num_actors: number of power actors in this thermal zone + * @total_req_power: sum of all weighted requested power for all actors * @power_range: total allocated power - * @granted_power: output array: each actor's granted power - * @extra_actor_power: an appropriately sized array to be used in the - * function as temporary storage of the extra power given - * to the actors * * This function divides the total allocated power (@power_range) * fairly between the actors. It first tries to give each actor a @@ -330,41 +346,45 @@ power_actor_set_power(struct thermal_cooling_device *cdev, * If any actor received more than their maximum power, then that * surplus is re-divvied among the actors based on how far they are * from their respective maximums. - * - * Granted power for each actor is written to @granted_power, which - * should've been allocated by the calling function. */ -static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors, - u32 total_req_power, u32 power_range, - u32 *granted_power, u32 *extra_actor_power) +static void divvy_up_power(struct power_actor *power, int num_actors, + u32 total_req_power, u32 power_range) { - u32 extra_power, capped_extra_power; + u32 capped_extra_power = 0; + u32 extra_power = 0; int i; - /* - * Prevent division by 0 if none of the actors request power. - */ - if (!total_req_power) - total_req_power = 1; + if (!total_req_power) { + /* + * Nobody requested anything, just give everybody + * the maximum power + */ + for (i = 0; i < num_actors; i++) { + struct power_actor *pa = &power[i]; + + pa->granted_power = pa->max_power; + } + + return; + } - capped_extra_power = 0; - extra_power = 0; for (i = 0; i < num_actors; i++) { - u64 req_range = (u64)req_power[i] * power_range; + struct power_actor *pa = &power[i]; + u64 req_range = (u64)pa->weighted_req_power * power_range; - granted_power[i] = DIV_ROUND_CLOSEST_ULL(req_range, - total_req_power); + pa->granted_power = DIV_ROUND_CLOSEST_ULL(req_range, + total_req_power); - if (granted_power[i] > max_power[i]) { - extra_power += granted_power[i] - max_power[i]; - granted_power[i] = max_power[i]; + if (pa->granted_power > pa->max_power) { + extra_power += pa->granted_power - pa->max_power; + pa->granted_power = pa->max_power; } - extra_actor_power[i] = max_power[i] - granted_power[i]; - capped_extra_power += extra_actor_power[i]; + pa->extra_actor_power = pa->max_power - pa->granted_power; + capped_extra_power += pa->extra_actor_power; } - if (!extra_power) + if (!extra_power || !capped_extra_power) return; /* @@ -372,138 +392,98 @@ static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors, * how far they are from the max */ extra_power = min(extra_power, capped_extra_power); - if (capped_extra_power > 0) - for (i = 0; i < num_actors; i++) { - u64 extra_range = (u64)extra_actor_power[i] * extra_power; - granted_power[i] += DIV_ROUND_CLOSEST_ULL(extra_range, - capped_extra_power); - } -} - -static int allocate_power(struct thermal_zone_device *tz, - int control_temp) -{ - struct thermal_instance *instance; - struct power_allocator_params *params = tz->governor_data; - 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; - u32 total_granted_power, power_range; - int i, num_actors, total_weight, ret = 0; - int trip_max_desired_temperature = params->trip_max_desired_temperature; - - mutex_lock(&tz->lock); - - num_actors = 0; - total_weight = 0; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if ((instance->trip == trip_max_desired_temperature) && - cdev_is_power_actor(instance->cdev)) { - num_actors++; - total_weight += instance->weight; - } - } - if (!num_actors) { - ret = -ENODEV; - goto unlock; - } + for (i = 0; i < num_actors; i++) { + struct power_actor *pa = &power[i]; + u64 extra_range = pa->extra_actor_power; - /* - * We need to allocate five arrays of the same size: - * req_power, max_power, granted_power, extra_actor_power and - * weighted_req_power. They are going to be needed until this - * function returns. Allocate them all in one go to simplify - * the allocation and deallocation logic. - */ - BUILD_BUG_ON(sizeof(*req_power) != sizeof(*max_power)); - BUILD_BUG_ON(sizeof(*req_power) != sizeof(*granted_power)); - BUILD_BUG_ON(sizeof(*req_power) != sizeof(*extra_actor_power)); - BUILD_BUG_ON(sizeof(*req_power) != sizeof(*weighted_req_power)); - req_power = kcalloc(num_actors * 5, sizeof(*req_power), GFP_KERNEL); - if (!req_power) { - ret = -ENOMEM; - goto unlock; + extra_range *= extra_power; + pa->granted_power += DIV_ROUND_CLOSEST_ULL(extra_range, + capped_extra_power); } +} - max_power = &req_power[num_actors]; - granted_power = &req_power[2 * num_actors]; - extra_actor_power = &req_power[3 * num_actors]; - weighted_req_power = &req_power[4 * num_actors]; +static void allocate_power(struct thermal_zone_device *tz, int control_temp) +{ + struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); + unsigned int num_actors = params->num_actors; + struct power_actor *power = params->power; + struct thermal_cooling_device *cdev; + struct thermal_instance *instance; + u32 total_weighted_req_power = 0; + u32 max_allocatable_power = 0; + u32 total_granted_power = 0; + u32 total_req_power = 0; + u32 power_range, weight; + int i = 0, ret; + + if (!num_actors) + return; - i = 0; - total_weighted_req_power = 0; - total_req_power = 0; - max_allocatable_power = 0; + /* Clean all buffers for new power estimations */ + memset(power, 0, params->buffer_size); - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - int weight; - struct thermal_cooling_device *cdev = instance->cdev; + list_for_each_entry(instance, &td->thermal_instances, trip_node) { + struct power_actor *pa = &power[i]; - if (instance->trip != trip_max_desired_temperature) + if (!power_actor_is_valid(instance)) continue; - if (!cdev_is_power_actor(cdev)) - continue; + cdev = instance->cdev; - if (cdev->ops->get_requested_power(cdev, &req_power[i])) + ret = cdev->ops->get_requested_power(cdev, &pa->req_power); + if (ret) continue; - if (!total_weight) + if (!params->total_weight) weight = 1 << FRAC_BITS; else weight = instance->weight; - weighted_req_power[i] = frac_to_int(weight * req_power[i]); + pa->weighted_req_power = frac_to_int(weight * pa->req_power); - if (cdev->ops->state2power(cdev, instance->lower, - &max_power[i])) + ret = cdev->ops->state2power(cdev, instance->lower, + &pa->max_power); + if (ret) continue; - total_req_power += req_power[i]; - max_allocatable_power += max_power[i]; - total_weighted_req_power += weighted_req_power[i]; + total_req_power += pa->req_power; + max_allocatable_power += pa->max_power; + total_weighted_req_power += pa->weighted_req_power; i++; } power_range = pid_controller(tz, control_temp, max_allocatable_power); - divvy_up_power(weighted_req_power, max_power, num_actors, - total_weighted_req_power, power_range, granted_power, - extra_actor_power); + divvy_up_power(power, num_actors, total_weighted_req_power, + power_range); - total_granted_power = 0; i = 0; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip_max_desired_temperature) - continue; + list_for_each_entry(instance, &td->thermal_instances, trip_node) { + struct power_actor *pa = &power[i]; - if (!cdev_is_power_actor(instance->cdev)) + if (!power_actor_is_valid(instance)) continue; power_actor_set_power(instance->cdev, instance, - granted_power[i]); - total_granted_power += granted_power[i]; + pa->granted_power); + total_granted_power += pa->granted_power; + trace_thermal_power_actor(tz, i, pa->req_power, + pa->granted_power); i++; } - trace_thermal_power_allocator(tz, req_power, total_req_power, - granted_power, total_granted_power, + trace_thermal_power_allocator(tz, total_req_power, total_granted_power, num_actors, power_range, max_allocatable_power, tz->temperature, control_temp - tz->temperature); - - kfree(req_power); -unlock: - mutex_unlock(&tz->lock); - - return ret; } /** - * 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 * @@ -520,47 +500,39 @@ unlock: 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; - - found_first_passive = false; - last_active = INVALID_TRIP; - last_passive = INVALID_TRIP; - - for (i = 0; i < tz->trips; i++) { - enum thermal_trip_type type; - int ret; - - ret = tz->ops->get_trip_type(tz, i, &type); - if (ret) { - dev_warn(&tz->device, - "Failed to get trip point %d type: %d\n", i, - ret); - continue; - } - - if (type == THERMAL_TRIP_PASSIVE) { - if (!found_first_passive) { - params->trip_switch_on = i; - found_first_passive = true; - } else { - last_passive = i; + 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_desc *td; + + for_each_trip_desc(tz, td) { + const struct thermal_trip *trip = &td->trip; + + switch (trip->type) { + case THERMAL_TRIP_PASSIVE: + if (!first_passive) { + first_passive = trip; + break; } - } else if (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) { - 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; + if (last_passive) { + params->trip_switch_on = first_passive; + params->trip_max = last_passive; + } else if (first_passive) { + params->trip_switch_on = NULL; + params->trip_max = first_passive; } else { - params->trip_switch_on = INVALID_TRIP; - params->trip_max_desired_temperature = last_active; + params->trip_switch_on = NULL; + params->trip_max = last_active; } } @@ -570,65 +542,148 @@ static void reset_pid_controller(struct power_allocator_params *params) params->prev_err = 0; } -static void allow_maximum_power(struct thermal_zone_device *tz, bool update) +static void allow_maximum_power(struct thermal_zone_device *tz) { - struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); + struct thermal_cooling_device *cdev; + struct thermal_instance *instance; u32 req_power; - mutex_lock(&tz->lock); - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - struct thermal_cooling_device *cdev = instance->cdev; - - if ((instance->trip != params->trip_max_desired_temperature) || - (!cdev_is_power_actor(instance->cdev))) + list_for_each_entry(instance, &td->thermal_instances, trip_node) { + if (!power_actor_is_valid(instance)) continue; - instance->target = 0; - mutex_lock(&instance->cdev->lock); - /* - * Call for updating the cooling devices local stats and avoid - * periods of dozen of seconds when those have not been - * maintained. - */ - cdev->ops->get_requested_power(cdev, &req_power); + cdev = instance->cdev; - if (update) - __thermal_cdev_update(instance->cdev); - - mutex_unlock(&instance->cdev->lock); + instance->target = 0; + scoped_guard(cooling_dev, cdev) { + /* + * Call for updating the cooling devices local stats and + * avoid periods of dozen of seconds when those have not + * been maintained. + */ + cdev->ops->get_requested_power(cdev, &req_power); + + if (params->update_cdevs) + __thermal_cdev_update(cdev); + } } - mutex_unlock(&tz->lock); } /** * check_power_actors() - Check all cooling devices and warn when they are * not power actors * @tz: thermal zone to operate on + * @params: power allocator private data * * Check all cooling devices in the @tz and warn every time they are missing * power actor API. The warning should help to investigate the issue, which * could be e.g. lack of Energy Model for a given device. * - * Return: 0 on success, -EINVAL if any cooling device does not implement - * the power actor API. + * If all of the cooling devices currently attached to @tz implement the power + * actor API, return the number of them (which may be 0, because some cooling + * devices may be attached later). Otherwise, return -EINVAL. */ -static int check_power_actors(struct thermal_zone_device *tz) +static int check_power_actors(struct thermal_zone_device *tz, + struct power_allocator_params *params) { + const struct thermal_trip_desc *td; struct thermal_instance *instance; int ret = 0; - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + if (!params->trip_max) + return 0; + + td = trip_to_trip_desc(params->trip_max); + + list_for_each_entry(instance, &td->thermal_instances, trip_node) { if (!cdev_is_power_actor(instance->cdev)) { dev_warn(&tz->device, "power_allocator: %s is not a power actor\n", instance->cdev->type); - ret = -EINVAL; + return -EINVAL; } + ret++; } return ret; } +static int allocate_actors_buffer(struct power_allocator_params *params, + int num_actors) +{ + int ret; + + kfree(params->power); + + /* There might be no cooling devices yet. */ + if (!num_actors) { + ret = 0; + goto clean_state; + } + + params->power = kcalloc(num_actors, sizeof(struct power_actor), + GFP_KERNEL); + if (!params->power) { + ret = -ENOMEM; + goto clean_state; + } + + params->num_actors = num_actors; + params->buffer_size = num_actors * sizeof(struct power_actor); + + return 0; + +clean_state: + params->num_actors = 0; + params->buffer_size = 0; + params->power = NULL; + return ret; +} + +static void power_allocator_update_weight(struct power_allocator_params *params) +{ + const struct thermal_trip_desc *td; + struct thermal_instance *instance; + + if (!params->trip_max) + return; + + td = trip_to_trip_desc(params->trip_max); + + params->total_weight = 0; + list_for_each_entry(instance, &td->thermal_instances, trip_node) + if (power_actor_is_valid(instance)) + params->total_weight += instance->weight; +} + +static void power_allocator_update_tz(struct thermal_zone_device *tz, + enum thermal_notify_event reason) +{ + struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); + struct thermal_instance *instance; + int num_actors = 0; + + switch (reason) { + case THERMAL_TZ_BIND_CDEV: + case THERMAL_TZ_UNBIND_CDEV: + list_for_each_entry(instance, &td->thermal_instances, trip_node) + if (power_actor_is_valid(instance)) + num_actors++; + + if (num_actors != params->num_actors) + allocate_actors_buffer(params, num_actors); + + fallthrough; + case THERMAL_INSTANCE_WEIGHT_CHANGED: + power_allocator_update_weight(params); + break; + default: + break; + } +} + /** * power_allocator_bind() - bind the power_allocator governor to a thermal zone * @tz: thermal zone to bind it to @@ -641,18 +696,29 @@ static int check_power_actors(struct thermal_zone_device *tz) */ static int power_allocator_bind(struct thermal_zone_device *tz) { - int ret; struct power_allocator_params *params; - int control_temp; - - ret = check_power_actors(tz); - if (ret) - return ret; + int ret; params = kzalloc(sizeof(*params), GFP_KERNEL); if (!params) return -ENOMEM; + get_governor_trips(tz, params); + + ret = check_power_actors(tz, params); + if (ret < 0) { + dev_warn(&tz->device, "power_allocator: binding failed\n"); + kfree(params); + return ret; + } + + ret = allocate_actors_buffer(params, ret); + if (ret) { + dev_warn(&tz->device, "power_allocator: allocation failed\n"); + kfree(params); + return ret; + } + if (!tz->tzp) { tz->tzp = kzalloc(sizeof(*tz->tzp), GFP_KERNEL); if (!tz->tzp) { @@ -665,26 +731,24 @@ static int power_allocator_bind(struct thermal_zone_device *tz) if (!tz->tzp->sustainable_power) dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n"); + else + params->sustainable_power = tz->tzp->sustainable_power; - get_governor_trips(tz, params); - - if (tz->trips > 0) { - ret = tz->ops->get_trip_temp(tz, - params->trip_max_desired_temperature, - &control_temp); - if (!ret) - estimate_pid_constants(tz, tz->tzp->sustainable_power, - params->trip_switch_on, - control_temp); - } + if (params->trip_max) + estimate_pid_constants(tz, tz->tzp->sustainable_power, + params->trip_switch_on, + params->trip_max->temperature); reset_pid_controller(params); tz->governor_data = params; + power_allocator_update_weight(params); + return 0; free_params: + kfree(params->power); kfree(params); return ret; @@ -701,52 +765,37 @@ static void power_allocator_unbind(struct thermal_zone_device *tz) tz->tzp = NULL; } + kfree(params->power); kfree(tz->governor_data); tz->governor_data = NULL; } -static int power_allocator_throttle(struct thermal_zone_device *tz, int trip) +static void power_allocator_manage(struct thermal_zone_device *tz) { - int ret; - int switch_on_temp, control_temp; struct power_allocator_params *params = tz->governor_data; - bool update; + const struct thermal_trip *trip = params->trip_switch_on; - /* - * We get called for every trip point but we only need to do - * our calculations once - */ - if (trip != params->trip_max_desired_temperature) - return 0; + lockdep_assert_held(&tz->lock); - ret = tz->ops->get_trip_temp(tz, params->trip_switch_on, - &switch_on_temp); - if (!ret && (tz->temperature < switch_on_temp)) { - update = (tz->last_temperature >= switch_on_temp); - tz->passive = 0; + if (trip && tz->temperature < trip->temperature) { reset_pid_controller(params); - allow_maximum_power(tz, update); - return 0; + allow_maximum_power(tz); + params->update_cdevs = false; + return; } - tz->passive = 1; - - ret = tz->ops->get_trip_temp(tz, params->trip_max_desired_temperature, - &control_temp); - if (ret) { - dev_warn(&tz->device, - "Failed to get the maximum desired temperature: %d\n", - ret); - return ret; - } + if (!params->trip_max) + return; - return allocate_power(tz, control_temp); + allocate_power(tz, params->trip_max->temperature); + params->update_cdevs = true; } static struct thermal_governor thermal_gov_power_allocator = { .name = "power_allocator", .bind_to_tz = power_allocator_bind, .unbind_from_tz = power_allocator_unbind, - .throttle = power_allocator_throttle, + .manage = power_allocator_manage, + .update_tz = power_allocator_update_tz, }; THERMAL_GOVERNOR_DECLARE(thermal_gov_power_allocator); |
