Skip to content

Commit

Permalink
Merge back earlier thermal control material for v6.10.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael J. Wysocki committed Apr 19, 2024
2 parents b552f63 + 0dbf608 commit 5c897a9
Show file tree
Hide file tree
Showing 16 changed files with 417 additions and 231 deletions.
7 changes: 5 additions & 2 deletions drivers/thermal/gov_fair_share.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

static int get_trip_level(struct thermal_zone_device *tz)
{
const struct thermal_trip *trip, *level_trip = NULL;
const struct thermal_trip *level_trip = NULL;
const struct thermal_trip_desc *td;
int trip_level = -1;

for_each_trip(tz, trip) {
for_each_trip_desc(tz, td) {
const struct thermal_trip *trip = &td->trip;

if (trip->temperature >= tz->temperature)
continue;

Expand Down
6 changes: 4 additions & 2 deletions drivers/thermal/gov_power_allocator.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,9 +496,11 @@ static void get_governor_trips(struct thermal_zone_device *tz,
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;
const struct thermal_trip_desc *td;

for_each_trip_desc(tz, td) {
const struct thermal_trip *trip = &td->trip;

for_each_trip(tz, trip) {
switch (trip->type) {
case THERMAL_TRIP_PASSIVE:
if (!first_passive) {
Expand Down
41 changes: 16 additions & 25 deletions drivers/thermal/gov_step_wise.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,40 +32,33 @@ static unsigned long get_target_state(struct thermal_instance *instance,
{
struct thermal_cooling_device *cdev = instance->cdev;
unsigned long cur_state;
unsigned long next_target;

/*
* We keep this instance the way it is by default.
* Otherwise, we use the current state of the
* cdev in use to determine the next_target.
*/
cdev->ops->get_cur_state(cdev, &cur_state);
next_target = instance->target;
dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);

if (!instance->initialized) {
if (throttle) {
next_target = clamp((cur_state + 1), instance->lower, instance->upper);
} else {
next_target = THERMAL_NO_TARGET;
}
if (throttle)
return clamp(cur_state + 1, instance->lower, instance->upper);

return next_target;
return THERMAL_NO_TARGET;
}

if (throttle) {
if (trend == THERMAL_TREND_RAISING)
next_target = clamp((cur_state + 1), instance->lower, instance->upper);
} else {
if (trend == THERMAL_TREND_DROPPING) {
if (cur_state <= instance->lower)
next_target = THERMAL_NO_TARGET;
else
next_target = clamp((cur_state - 1), instance->lower, instance->upper);
}
return clamp(cur_state + 1, instance->lower, instance->upper);
} else if (trend == THERMAL_TREND_DROPPING) {
if (cur_state <= instance->lower)
return THERMAL_NO_TARGET;

return clamp(cur_state - 1, instance->lower, instance->upper);
}

return next_target;
return instance->target;
}

static void thermal_zone_trip_update(struct thermal_zone_device *tz,
Expand Down Expand Up @@ -99,15 +92,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
if (instance->initialized && old_target == instance->target)
continue;

if (old_target == THERMAL_NO_TARGET &&
instance->target != THERMAL_NO_TARGET) {
/* Activate a passive thermal instance */
if (trip->type == THERMAL_TRIP_PASSIVE)
if (trip->type == THERMAL_TRIP_PASSIVE) {
/* If needed, update the status of passive polling. */
if (old_target == THERMAL_NO_TARGET &&
instance->target != THERMAL_NO_TARGET)
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)
else if (old_target != THERMAL_NO_TARGET &&
instance->target == THERMAL_NO_TARGET)
tz->passive--;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ static int acpi_parse_psvt(acpi_handle handle, int *psvt_count, struct psvt **ps

if (knob->type == ACPI_TYPE_STRING) {
memset(&psvt->limit, 0, sizeof(u64));
strncpy(psvt->limit.string, psvt_ptr->limit.str_ptr, knob->string.length);
strscpy(psvt->limit.string, psvt_ptr->limit.str_ptr, ACPI_LIMIT_STR_MAX_LEN);
} else {
psvt->limit.integer = psvt_ptr->limit.integer;
}
Expand Down Expand Up @@ -468,7 +468,7 @@ static int fill_psvt(char __user *ubuf)
psvt_user[i].unlimit_coeff = psvts[i].unlimit_coeff;
psvt_user[i].control_knob_type = psvts[i].control_knob_type;
if (psvt_user[i].control_knob_type == ACPI_TYPE_STRING)
strncpy(psvt_user[i].limit.string, psvts[i].limit.string,
strscpy(psvt_user[i].limit.string, psvts[i].limit.string,
ACPI_LIMIT_STR_MAX_LEN);
else
psvt_user[i].limit.integer = psvts[i].limit.integer;
Expand Down
97 changes: 89 additions & 8 deletions drivers/thermal/intel/intel_hfi.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ struct hfi_cpu_info {
static DEFINE_PER_CPU(struct hfi_cpu_info, hfi_cpu_info) = { .index = -1 };

static int max_hfi_instances;
static int hfi_clients_nr;
static struct hfi_instance *hfi_instances;

static struct hfi_features hfi_features;
Expand Down Expand Up @@ -477,8 +478,11 @@ void intel_hfi_online(unsigned int cpu)
enable:
cpumask_set_cpu(cpu, hfi_instance->cpus);

/* Enable this HFI instance if this is its first online CPU. */
if (cpumask_weight(hfi_instance->cpus) == 1) {
/*
* Enable this HFI instance if this is its first online CPU and
* there are user-space clients of thermal events.
*/
if (cpumask_weight(hfi_instance->cpus) == 1 && hfi_clients_nr > 0) {
hfi_set_hw_table(hfi_instance);
hfi_enable();
}
Expand Down Expand Up @@ -573,18 +577,33 @@ static __init int hfi_parse_features(void)
return 0;
}

static void hfi_do_enable(void)
/*
* If concurrency is not prevented by other means, the HFI enable/disable
* routines must be called under hfi_instance_lock."
*/
static void hfi_enable_instance(void *ptr)
{
hfi_set_hw_table(ptr);
hfi_enable();
}

static void hfi_disable_instance(void *ptr)
{
hfi_disable();
}

static void hfi_syscore_resume(void)
{
/* This code runs only on the boot CPU. */
struct hfi_cpu_info *info = &per_cpu(hfi_cpu_info, 0);
struct hfi_instance *hfi_instance = info->hfi_instance;

/* No locking needed. There is no concurrency with CPU online. */
hfi_set_hw_table(hfi_instance);
hfi_enable();
if (hfi_clients_nr > 0)
hfi_enable_instance(hfi_instance);
}

static int hfi_do_disable(void)
static int hfi_syscore_suspend(void)
{
/* No locking needed. There is no concurrency with CPU offline. */
hfi_disable();
Expand All @@ -593,8 +612,58 @@ static int hfi_do_disable(void)
}

static struct syscore_ops hfi_pm_ops = {
.resume = hfi_do_enable,
.suspend = hfi_do_disable,
.resume = hfi_syscore_resume,
.suspend = hfi_syscore_suspend,
};

static int hfi_thermal_notify(struct notifier_block *nb, unsigned long state,
void *_notify)
{
struct thermal_genl_notify *notify = _notify;
struct hfi_instance *hfi_instance;
smp_call_func_t func = NULL;
unsigned int cpu;
int i;

if (notify->mcgrp != THERMAL_GENL_EVENT_GROUP)
return NOTIFY_DONE;

if (state != THERMAL_NOTIFY_BIND && state != THERMAL_NOTIFY_UNBIND)
return NOTIFY_DONE;

mutex_lock(&hfi_instance_lock);

switch (state) {
case THERMAL_NOTIFY_BIND:
if (++hfi_clients_nr == 1)
func = hfi_enable_instance;
break;
case THERMAL_NOTIFY_UNBIND:
if (--hfi_clients_nr == 0)
func = hfi_disable_instance;
break;
}

if (!func)
goto out;

for (i = 0; i < max_hfi_instances; i++) {
hfi_instance = &hfi_instances[i];
if (cpumask_empty(hfi_instance->cpus))
continue;

cpu = cpumask_any(hfi_instance->cpus);
smp_call_function_single(cpu, func, hfi_instance, true);
}

out:
mutex_unlock(&hfi_instance_lock);

return NOTIFY_OK;
}

static struct notifier_block hfi_thermal_nb = {
.notifier_call = hfi_thermal_notify,
};

void __init intel_hfi_init(void)
Expand Down Expand Up @@ -628,10 +697,22 @@ void __init intel_hfi_init(void)
if (!hfi_updates_wq)
goto err_nomem;

/*
* Both thermal core and Intel HFI can not be build as modules.
* As kernel build-in drivers they are initialized before user-space
* starts, hence we can not miss BIND/UNBIND events when applications
* add/remove thermal multicast group to/from a netlink socket.
*/
if (thermal_genl_register_notifier(&hfi_thermal_nb))
goto err_nl_notif;

register_syscore_ops(&hfi_pm_ops);

return;

err_nl_notif:
destroy_workqueue(hfi_updates_wq);

err_nomem:
for (j = 0; j < i; ++j) {
hfi_instance = &hfi_instances[j];
Expand Down
Loading

0 comments on commit 5c897a9

Please sign in to comment.