1

thermal: intel: Discard trip tables after zone registration

Because the thermal core creates and uses its own copy of the trips
table passed to thermal_zone_device_register_with_trips(), it is not
necessary to hold on to a local copy of it any more after the given
thermal zone has been registered.

Accordingly, modify Intel thermal drivers to discard the trips tables
passed to thermal_zone_device_register_with_trips() after thermal zone
registration, for example by storing them in local variables which are
automatically discarded when the zone registration is complete.

Also make some additional code simplifications unlocked by the above
changes.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
This commit is contained in:
Rafael J. Wysocki 2024-02-05 22:16:59 +01:00
parent 9686f04a7b
commit fcbf878000
8 changed files with 51 additions and 73 deletions

View File

@ -179,8 +179,6 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
for (i = 0; i < trip_cnt; ++i)
zone_trips[i].hysteresis = hyst;
int34x_zone->trips = zone_trips;
int34x_zone->lpat_table = acpi_lpat_get_conversion_table(adev->handle);
int34x_zone->zone = thermal_zone_device_register_with_trips(
@ -190,6 +188,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
int34x_zone->ops,
&int340x_thermal_params,
0, 0);
kfree(zone_trips);
if (IS_ERR(int34x_zone->zone)) {
ret = PTR_ERR(int34x_zone->zone);
goto err_thermal_zone;
@ -203,7 +203,6 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
err_enable:
thermal_zone_device_unregister(int34x_zone->zone);
err_thermal_zone:
kfree(int34x_zone->trips);
acpi_lpat_free_conversion_table(int34x_zone->lpat_table);
err_trips_alloc:
kfree(int34x_zone->ops);
@ -217,7 +216,6 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone *int34x_zone)
{
thermal_zone_device_unregister(int34x_zone->zone);
acpi_lpat_free_conversion_table(int34x_zone->lpat_table);
kfree(int34x_zone->trips);
kfree(int34x_zone->ops);
kfree(int34x_zone);
}

View File

@ -20,7 +20,6 @@ struct active_trip {
struct int34x_thermal_zone {
struct acpi_device *adev;
struct thermal_trip *trips;
int aux_trip_nr;
struct thermal_zone_device *zone;
struct thermal_zone_device_ops *ops;

View File

@ -233,10 +233,6 @@ static int get_trip_temp(struct proc_thermal_pci *pci_info)
return temp;
}
static struct thermal_trip psv_trip = {
.type = THERMAL_TRIP_PASSIVE,
};
static struct thermal_zone_device_ops tzone_ops = {
.get_temp = sys_get_curr_temp,
.set_trip_temp = sys_set_trip_temp,
@ -251,6 +247,9 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
{
struct proc_thermal_device *proc_priv;
struct proc_thermal_pci *pci_info;
struct thermal_trip psv_trip = {
.type = THERMAL_TRIP_PASSIVE,
};
int irq_flag = 0, irq, ret;
bool msi_irq = false;

View File

@ -84,7 +84,6 @@ struct pch_thermal_device {
void __iomem *hw_base;
struct pci_dev *pdev;
struct thermal_zone_device *tzd;
struct thermal_trip trips[PCH_MAX_TRIPS];
bool bios_enabled;
};
@ -94,7 +93,8 @@ struct pch_thermal_device {
* passive trip temperature using _PSV method. There is no specific
* passive temperature setting in MMIO interface of this PCI device.
*/
static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, int trip)
static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd,
struct thermal_trip *trip)
{
struct acpi_device *adev;
int temp;
@ -106,12 +106,13 @@ static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, int trip)
if (thermal_acpi_passive_trip_temp(adev, &temp) || temp <= 0)
return 0;
ptd->trips[trip].type = THERMAL_TRIP_PASSIVE;
ptd->trips[trip].temperature = temp;
trip->type = THERMAL_TRIP_PASSIVE;
trip->temperature = temp;
return 1;
}
#else
static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, int trip)
static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd,
struct thermal_trip *trip)
{
return 0;
}
@ -159,6 +160,7 @@ static const char *board_names[] = {
static int intel_pch_thermal_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct thermal_trip ptd_trips[PCH_MAX_TRIPS] = { 0 };
enum pch_board_ids board_id = id->driver_data;
struct pch_thermal_device *ptd;
int nr_trips = 0;
@ -220,21 +222,21 @@ read_trips:
trip_temp = readw(ptd->hw_base + WPT_CTT);
trip_temp &= 0x1FF;
if (trip_temp) {
ptd->trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp);
ptd->trips[nr_trips++].type = THERMAL_TRIP_CRITICAL;
ptd_trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp);
ptd_trips[nr_trips++].type = THERMAL_TRIP_CRITICAL;
}
trip_temp = readw(ptd->hw_base + WPT_PHL);
trip_temp &= 0x1FF;
if (trip_temp) {
ptd->trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp);
ptd->trips[nr_trips++].type = THERMAL_TRIP_HOT;
ptd_trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp);
ptd_trips[nr_trips++].type = THERMAL_TRIP_HOT;
}
nr_trips += pch_wpt_add_acpi_psv_trip(ptd, nr_trips);
nr_trips += pch_wpt_add_acpi_psv_trip(ptd, &ptd_trips[nr_trips]);
ptd->tzd = thermal_zone_device_register_with_trips(board_names[board_id],
ptd->trips, nr_trips,
ptd_trips, nr_trips,
0, ptd, &tzd_ops,
NULL, 0, 0);
if (IS_ERR(ptd->tzd)) {

View File

@ -105,7 +105,6 @@ struct soc_sensor_entry {
u32 store_ptps;
u32 store_dts_enable;
struct thermal_zone_device *tzone;
struct thermal_trip trips[QRK_MAX_DTS_TRIPS];
};
static struct soc_sensor_entry *soc_dts;
@ -320,6 +319,7 @@ static void free_soc_dts(struct soc_sensor_entry *aux_entry)
static struct soc_sensor_entry *alloc_soc_dts(void)
{
struct thermal_trip trips[QRK_MAX_DTS_TRIPS] = { 0 };
struct soc_sensor_entry *aux_entry;
int err;
u32 out;
@ -362,14 +362,14 @@ static struct soc_sensor_entry *alloc_soc_dts(void)
goto err_ret;
}
aux_entry->trips[QRK_DTS_ID_TP_CRITICAL].temperature = get_trip_temp(QRK_DTS_ID_TP_CRITICAL);
aux_entry->trips[QRK_DTS_ID_TP_CRITICAL].type = THERMAL_TRIP_CRITICAL;
trips[QRK_DTS_ID_TP_CRITICAL].temperature = get_trip_temp(QRK_DTS_ID_TP_CRITICAL);
trips[QRK_DTS_ID_TP_CRITICAL].type = THERMAL_TRIP_CRITICAL;
aux_entry->trips[QRK_DTS_ID_TP_HOT].temperature = get_trip_temp(QRK_DTS_ID_TP_HOT);
aux_entry->trips[QRK_DTS_ID_TP_HOT].type = THERMAL_TRIP_HOT;
trips[QRK_DTS_ID_TP_HOT].temperature = get_trip_temp(QRK_DTS_ID_TP_HOT);
trips[QRK_DTS_ID_TP_HOT].type = THERMAL_TRIP_HOT;
aux_entry->tzone = thermal_zone_device_register_with_trips("quark_dts",
aux_entry->trips,
trips,
QRK_MAX_DTS_TRIPS,
wr_mask,
aux_entry, &tzone_ops,

View File

@ -129,22 +129,6 @@ err_restore_ptps:
return status;
}
static int configure_trip(struct intel_soc_dts_sensor_entry *dts,
int thres_index, enum thermal_trip_type trip_type,
int temp)
{
int ret;
ret = update_trip_temp(dts->sensors, thres_index, temp);
if (ret)
return ret;
dts->trips[thres_index].temperature = temp;
dts->trips[thres_index].type = trip_type;
return 0;
}
static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
int temp)
{
@ -218,6 +202,7 @@ static void remove_dts_thermal_zone(struct intel_soc_dts_sensor_entry *dts)
}
static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
struct thermal_trip *trips,
bool critical_trip)
{
int writable_trip_cnt = SOC_MAX_DTS_TRIPS;
@ -254,7 +239,7 @@ static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts,
}
dts->trip_mask = trip_mask;
snprintf(name, sizeof(name), "soc_dts%d", id);
dts->tzone = thermal_zone_device_register_with_trips(name, dts->trips,
dts->tzone = thermal_zone_device_register_with_trips(name, trips,
SOC_MAX_DTS_TRIPS,
trip_mask,
dts, &tzone_ops,
@ -315,14 +300,15 @@ EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_interrupt_handler);
static void dts_trips_reset(struct intel_soc_dts_sensors *sensors, int dts_index)
{
configure_trip(&sensors->soc_dts[dts_index], 0, 0, 0);
configure_trip(&sensors->soc_dts[dts_index], 1, 0, 0);
update_trip_temp(sensors, 0, 0);
update_trip_temp(sensors, 1, 0);
}
struct intel_soc_dts_sensors *
intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type,
bool critical_trip, int crit_offset)
{
struct thermal_trip trips[SOC_MAX_DTS_SENSORS][SOC_MAX_DTS_TRIPS] = { 0 };
struct intel_soc_dts_sensors *sensors;
int tj_max;
int ret;
@ -350,11 +336,13 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type,
sensors->soc_dts[i].sensors = sensors;
ret = configure_trip(&sensors->soc_dts[i], 0,
THERMAL_TRIP_PASSIVE, 0);
ret = update_trip_temp(sensors, 0, 0);
if (ret)
goto err_reset_trips;
trips[i][0].type = THERMAL_TRIP_PASSIVE;
trips[i][0].temperature = 0;
if (critical_trip) {
trip_type = THERMAL_TRIP_CRITICAL;
temp = sensors->tj_max - crit_offset;
@ -362,13 +350,17 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type,
trip_type = THERMAL_TRIP_PASSIVE;
temp = 0;
}
ret = configure_trip(&sensors->soc_dts[i], 1, trip_type, temp);
ret = update_trip_temp(sensors, 1, temp);
if (ret)
goto err_reset_trips;
trips[i][1].type = trip_type;
trips[i][1].temperature = temp;
}
for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) {
ret = add_dts_thermal_zone(i, &sensors->soc_dts[i], critical_trip);
ret = add_dts_thermal_zone(i, &sensors->soc_dts[i], trips[i],
critical_trip);
if (ret)
goto err_remove_zone;
}

View File

@ -29,7 +29,6 @@ struct intel_soc_dts_sensor_entry {
int id;
u32 store_status;
u32 trip_mask;
struct thermal_trip trips[SOC_MAX_DTS_TRIPS];
struct thermal_zone_device *tzone;
struct intel_soc_dts_sensors *sensors;
};

View File

@ -53,7 +53,6 @@ struct zone_device {
u32 msr_pkg_therm_high;
struct delayed_work work;
struct thermal_zone_device *tzone;
struct thermal_trip *trips;
struct cpumask cpumask;
};
@ -268,17 +267,13 @@ static int pkg_thermal_notify(u64 msr_val)
return 0;
}
static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int num_trips)
static int pkg_temp_thermal_trips_init(int cpu, int tj_max,
struct thermal_trip *trips, int num_trips)
{
struct thermal_trip *trips;
unsigned long thres_reg_value;
u32 mask, shift, eax, edx;
int ret, i;
trips = kzalloc(sizeof(*trips) * num_trips, GFP_KERNEL);
if (!trips)
return ERR_PTR(-ENOMEM);
for (i = 0; i < num_trips; i++) {
if (i) {
@ -291,10 +286,8 @@ static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int
ret = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
&eax, &edx);
if (ret < 0) {
kfree(trips);
return ERR_PTR(ret);
}
if (ret < 0)
return ret;
thres_reg_value = (eax & mask) >> shift;
@ -307,11 +300,12 @@ static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int
__func__, cpu, i, trips[i].temperature);
}
return trips;
return 0;
}
static int pkg_temp_thermal_device_add(unsigned int cpu)
{
struct thermal_trip trips[MAX_NUMBER_OF_TRIPS] = { 0 };
int id = topology_logical_die_id(cpu);
u32 eax, ebx, ecx, edx;
struct zone_device *zonedev;
@ -336,21 +330,19 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
if (!zonedev)
return -ENOMEM;
zonedev->trips = pkg_temp_thermal_trips_init(cpu, tj_max, thres_count);
if (IS_ERR(zonedev->trips)) {
err = PTR_ERR(zonedev->trips);
err = pkg_temp_thermal_trips_init(cpu, tj_max, trips, thres_count);
if (err)
goto out_kfree_zonedev;
}
INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn);
zonedev->cpu = cpu;
zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp",
zonedev->trips, thres_count,
trips, thres_count,
(thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01,
zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0);
if (IS_ERR(zonedev->tzone)) {
err = PTR_ERR(zonedev->tzone);
goto out_kfree_trips;
goto out_kfree_zonedev;
}
err = thermal_zone_device_enable(zonedev->tzone);
if (err)
@ -369,8 +361,6 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
out_unregister_tz:
thermal_zone_device_unregister(zonedev->tzone);
out_kfree_trips:
kfree(zonedev->trips);
out_kfree_zonedev:
kfree(zonedev);
return err;
@ -457,10 +447,9 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
raw_spin_unlock_irq(&pkg_temp_lock);
/* Final cleanup if this is the last cpu */
if (lastcpu) {
kfree(zonedev->trips);
if (lastcpu)
kfree(zonedev);
}
return 0;
}