Commit d3ecaf17 authored by Daniel Lezcano's avatar Daniel Lezcano
Browse files

thermal/drivers/intel: Use generic thermal_zone_get_trip() function



The thermal framework gives the possibility to register the trip
points with the thermal zone. When that is done, no get_trip_* ops are
needed and they can be removed.

Convert ops content logic into generic trip points and register them with the
thermal zone.

Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: default avatarSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://lore.kernel.org/r/20221003092602.1323944-30-daniel.lezcano@linaro.org
parent 0d2d586a
Loading
Loading
Loading
Loading
+67 −53
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ struct zone_device {
	u32				msr_pkg_therm_high;
	struct delayed_work		work;
	struct thermal_zone_device	*tzone;
	struct thermal_trip		*trips;
	struct cpumask			cpumask;
};

@@ -138,40 +139,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
	return -EINVAL;
}

static int sys_get_trip_temp(struct thermal_zone_device *tzd,
			     int trip, int *temp)
{
	struct zone_device *zonedev = tzd->devdata;
	unsigned long thres_reg_value;
	u32 mask, shift, eax, edx;
	int ret;

	if (trip >= MAX_NUMBER_OF_TRIPS)
		return -EINVAL;

	if (trip) {
		mask = THERM_MASK_THRESHOLD1;
		shift = THERM_SHIFT_THRESHOLD1;
	} else {
		mask = THERM_MASK_THRESHOLD0;
		shift = THERM_SHIFT_THRESHOLD0;
	}

	ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
			   &eax, &edx);
	if (ret < 0)
		return ret;

	thres_reg_value = (eax & mask) >> shift;
	if (thres_reg_value)
		*temp = zonedev->tj_max - thres_reg_value * 1000;
	else
		*temp = THERMAL_TEMP_INVALID;
	pr_debug("sys_get_trip_temp %d\n", *temp);

	return 0;
}

static int
sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
{
@@ -212,18 +179,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
			l, h);
}

static int sys_get_trip_type(struct thermal_zone_device *thermal, int trip,
			     enum thermal_trip_type *type)
{
	*type = THERMAL_TRIP_PASSIVE;
	return 0;
}

/* Thermal zone callback registry */
static struct thermal_zone_device_ops tzone_ops = {
	.get_temp = sys_get_curr_temp,
	.get_trip_temp = sys_get_trip_temp,
	.get_trip_type = sys_get_trip_type,
	.set_trip_temp = sys_set_trip_temp,
};

@@ -323,6 +281,48 @@ 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)
{
	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) {
			mask = THERM_MASK_THRESHOLD1;
			shift = THERM_SHIFT_THRESHOLD1;
		} else {
			mask = THERM_MASK_THRESHOLD0;
			shift = THERM_SHIFT_THRESHOLD0;
		}

		ret = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
				   &eax, &edx);
		if (ret < 0) {
			kfree(trips);
			return ERR_PTR(ret);
		}

		thres_reg_value = (eax & mask) >> shift;

		trips[i].temperature = thres_reg_value ?
			tj_max - thres_reg_value * 1000 : THERMAL_TEMP_INVALID;

		trips[i].type = THERMAL_TRIP_PASSIVE;

		pr_debug("%s: cpu=%d, trip=%d, temp=%d\n",
			 __func__, cpu, i, trips[i].temperature);
	}

	return trips;
}

static int pkg_temp_thermal_device_add(unsigned int cpu)
{
	int id = topology_logical_die_id(cpu);
@@ -348,24 +348,27 @@ 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);
		goto out_kfree_zonedev;
	}

	INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn);
	zonedev->cpu = cpu;
	zonedev->tj_max = tj_max;
	zonedev->tzone = thermal_zone_device_register("x86_pkg_temp",
			thres_count,
	zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp",
			zonedev->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);
		kfree(zonedev);
		return err;
		goto out_kfree_trips;
	}
	err = thermal_zone_device_enable(zonedev->tzone);
	if (err) {
		thermal_zone_device_unregister(zonedev->tzone);
		kfree(zonedev);
		return err;
	}
	if (err)
		goto out_unregister_tz;

	/* Store MSR value for package thermal interrupt, to restore at exit */
	rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
	      zonedev->msr_pkg_therm_high);
@@ -374,7 +377,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
	raw_spin_lock_irq(&pkg_temp_lock);
	zones[id] = zonedev;
	raw_spin_unlock_irq(&pkg_temp_lock);

	return 0;

out_unregister_tz:
	thermal_zone_device_unregister(zonedev->tzone);
out_kfree_trips:
	kfree(zonedev->trips);
out_kfree_zonedev:
	kfree(zonedev);
	return err;
}

static int pkg_thermal_cpu_offline(unsigned int cpu)
@@ -458,8 +470,10 @@ 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)
	if (lastcpu) {
		kfree(zonedev->trips);
		kfree(zonedev);
	}
	return 0;
}