Merge branch 'thermal-core'

Merge updates related to the thermal core for 6.11-rc1:

 - Redesign the .set_trip_temp() thermal zone callback to take a trip
   pointer instead of a trip ID and update its users (Rafael Wysocki).

 - Avoid using invalid combinations of polling_delay and passive_delay
   thermal zone parameters (Rafael Wysocki).

 - Update a cooling device registration function to take a const
   argument (Krzysztof Kozlowski).

 - Make the uniphier thermal driver use thermal_zone_for_each_trip() for
   walking trip points (Rafael Wysocki).

* thermal-core:
  thermal: core: Add sanity checks for polling_delay and passive_delay
  thermal: trip: Fold __thermal_zone_get_trip() into its caller
  thermal: trip: Pass trip pointer to .set_trip_temp() thermal zone callback
  thermal: imx: Drop critical trip check from imx_set_trip_temp()
  thermal: trip: Add conversion macros for thermal trip priv field
  thermal: helpers: Introduce thermal_trip_is_bound_to_cdev()
  thermal: core: Change passive_delay and polling_delay data type
  thermal: core: constify 'type' in devm_thermal_of_cooling_device_register()
  thermal: uniphier: Use thermal_zone_for_each_trip() for walking trip points
This commit is contained in:
Rafael J. Wysocki 2024-07-15 20:43:21 +02:00
commit ab33da3a22
15 changed files with 148 additions and 112 deletions

View File

@ -638,7 +638,7 @@ out:
}
static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
int trip, int temp)
const struct thermal_trip *trip, int temp)
{
struct iwl_mvm *mvm = thermal_zone_device_priv(device);
int ret;

View File

@ -331,25 +331,16 @@ static int imx_change_mode(struct thermal_zone_device *tz,
return 0;
}
static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip_id,
int temp)
static int imx_set_trip_temp(struct thermal_zone_device *tz,
const struct thermal_trip *trip, int temp)
{
struct imx_thermal_data *data = thermal_zone_device_priv(tz);
struct thermal_trip trip;
int ret;
ret = pm_runtime_resume_and_get(data->dev);
if (ret < 0)
return ret;
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
if (ret)
return ret;
/* do not allow changing critical threshold */
if (trip.type == THERMAL_TRIP_CRITICAL)
return -EPERM;
/* do not allow passive to be set higher than critical */
if (temp < 0 || temp > trips[IMX_TRIP_CRITICAL].temperature)
return -EINVAL;

View File

@ -39,13 +39,14 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone,
}
static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone,
int trip, int temp)
const struct thermal_trip *trip, int temp)
{
struct int34x_thermal_zone *d = thermal_zone_device_priv(zone);
char name[] = {'P', 'A', 'T', '0' + trip, '\0'};
unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv);
char name[] = {'P', 'A', 'T', '0' + trip_index, '\0'};
acpi_status status;
if (trip > 9)
if (trip_index > 9)
return -EINVAL;
status = acpi_execute_simple_method(d->adev->handle, name,
@ -62,16 +63,6 @@ static void int340x_thermal_critical(struct thermal_zone_device *zone)
thermal_zone_device_type(zone));
}
static inline void *int_to_trip_priv(int i)
{
return (void *)(long)i;
}
static inline int trip_priv_to_int(const struct thermal_trip *trip)
{
return (long)trip->priv;
}
static int int340x_thermal_read_trips(struct acpi_device *zone_adev,
struct thermal_trip *zone_trips,
int trip_cnt)
@ -106,7 +97,7 @@ static int int340x_thermal_read_trips(struct acpi_device *zone_adev,
break;
zone_trips[trip_cnt].type = THERMAL_TRIP_ACTIVE;
zone_trips[trip_cnt].priv = int_to_trip_priv(i);
zone_trips[trip_cnt].priv = THERMAL_INT_TO_TRIP_PRIV(i);
trip_cnt++;
}
@ -154,6 +145,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
zone_trips[i].type = THERMAL_TRIP_PASSIVE;
zone_trips[i].temperature = THERMAL_TEMP_INVALID;
zone_trips[i].flags |= THERMAL_TRIP_FLAG_RW_TEMP;
zone_trips[i].priv = THERMAL_INT_TO_TRIP_PRIV(i);
}
trip_cnt = int340x_thermal_read_trips(adev, zone_trips, trip_cnt);
@ -224,7 +216,7 @@ static int int340x_update_one_trip(struct thermal_trip *trip, void *arg)
break;
case THERMAL_TRIP_ACTIVE:
err = thermal_acpi_active_trip_temp(zone_adev,
trip_priv_to_int(trip),
THERMAL_TRIP_PRIV_TO_INT(trip->priv),
&temp);
break;
default:

View File

@ -194,7 +194,8 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
return 0;
}
static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
static int sys_set_trip_temp(struct thermal_zone_device *tzd,
const struct thermal_trip *trip, int temp)
{
struct proc_thermal_pci *pci_info = thermal_zone_device_priv(tzd);
int tjmax, _temp;

View File

@ -195,7 +195,7 @@ static int get_trip_temp(int trip)
}
static int update_trip_temp(struct soc_sensor_entry *aux_entry,
int trip, int temp)
int trip_index, int temp)
{
u32 out;
u32 temp_out;
@ -230,9 +230,9 @@ static int update_trip_temp(struct soc_sensor_entry *aux_entry,
*/
temp_out = temp + QRK_DTS_TEMP_BASE;
out = (store_ptps & ~(QRK_DTS_MASK_TP_THRES <<
(trip * QRK_DTS_SHIFT_TP)));
(trip_index * QRK_DTS_SHIFT_TP)));
out |= (temp_out & QRK_DTS_MASK_TP_THRES) <<
(trip * QRK_DTS_SHIFT_TP);
(trip_index * QRK_DTS_SHIFT_TP);
ret = iosf_mbi_write(QRK_MBI_UNIT_RMU, MBI_REG_WRITE,
QRK_DTS_REG_OFFSET_PTPS, out);
@ -242,10 +242,26 @@ failed:
return ret;
}
static inline int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
int temp)
static inline int sys_set_trip_temp(struct thermal_zone_device *tzd,
const struct thermal_trip *trip,
int temp)
{
return update_trip_temp(thermal_zone_device_priv(tzd), trip, temp);
unsigned int trip_index;
switch (trip->type) {
case THERMAL_TRIP_HOT:
trip_index = QRK_DTS_ID_TP_HOT;
break;
case THERMAL_TRIP_CRITICAL:
trip_index = QRK_DTS_ID_TP_CRITICAL;
break;
default:
return -EINVAL;
}
return update_trip_temp(thermal_zone_device_priv(tzd), trip_index, temp);
}
static int sys_get_curr_temp(struct thermal_zone_device *tzd,

View File

@ -129,18 +129,20 @@ err_restore_ptps:
return status;
}
static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
static int sys_set_trip_temp(struct thermal_zone_device *tzd,
const struct thermal_trip *trip,
int temp)
{
struct intel_soc_dts_sensor_entry *dts = thermal_zone_device_priv(tzd);
struct intel_soc_dts_sensors *sensors = dts->sensors;
unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv);
int status;
if (temp > sensors->tj_max)
return -EINVAL;
mutex_lock(&sensors->dts_update_lock);
status = update_trip_temp(sensors, trip, temp);
status = update_trip_temp(sensors, trip_index, temp);
mutex_unlock(&sensors->dts_update_lock);
return status;
@ -293,11 +295,12 @@ static void dts_trips_reset(struct intel_soc_dts_sensors *sensors, int dts_index
}
static void set_trip(struct thermal_trip *trip, enum thermal_trip_type type,
u8 flags, int temp)
u8 flags, int temp, unsigned int index)
{
trip->type = type;
trip->flags = flags;
trip->temperature = temp;
trip->priv = THERMAL_INT_TO_TRIP_PRIV(index);
}
struct intel_soc_dts_sensors *
@ -332,7 +335,7 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type,
sensors->soc_dts[i].sensors = sensors;
set_trip(&trips[i][0], THERMAL_TRIP_PASSIVE,
THERMAL_TRIP_FLAG_RW_TEMP, 0);
THERMAL_TRIP_FLAG_RW_TEMP, 0, 0);
ret = update_trip_temp(sensors, 0, 0);
if (ret)
@ -340,10 +343,10 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type,
if (critical_trip) {
temp = sensors->tj_max - crit_offset;
set_trip(&trips[i][1], THERMAL_TRIP_CRITICAL, 0, temp);
set_trip(&trips[i][1], THERMAL_TRIP_CRITICAL, 0, temp, 1);
} else {
set_trip(&trips[i][1], THERMAL_TRIP_PASSIVE,
THERMAL_TRIP_FLAG_RW_TEMP, 0);
THERMAL_TRIP_FLAG_RW_TEMP, 0, 1);
temp = 0;
}

View File

@ -119,9 +119,11 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
}
static int
sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
sys_set_trip_temp(struct thermal_zone_device *tzd,
const struct thermal_trip *trip, int temp)
{
struct zone_device *zonedev = thermal_zone_device_priv(tzd);
unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv);
u32 l, h, mask, shift, intr;
int tj_max, val, ret;
@ -132,7 +134,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
val = (tj_max - temp)/1000;
if (trip >= MAX_NUMBER_OF_TRIPS || val < 0 || val > 0x7f)
if (trip_index >= MAX_NUMBER_OF_TRIPS || val < 0 || val > 0x7f)
return -EINVAL;
ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
@ -140,7 +142,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
if (ret < 0)
return ret;
if (trip) {
if (trip_index) {
mask = THERM_MASK_THRESHOLD1;
shift = THERM_SHIFT_THRESHOLD1;
intr = THERM_INT_THRESHOLD1_ENABLE;
@ -296,6 +298,7 @@ static int pkg_temp_thermal_trips_init(int cpu, int tj_max,
trips[i].type = THERMAL_TRIP_PASSIVE;
trips[i].flags |= THERMAL_TRIP_FLAG_RW_TEMP;
trips[i].priv = THERMAL_INT_TO_TRIP_PRIV(i);
pr_debug("%s: cpu=%d, trip=%d, temp=%d\n",
__func__, cpu, i, trips[i].temperature);

View File

@ -261,17 +261,13 @@ skip:
return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg);
}
static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp)
static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz,
const struct thermal_trip *trip, int temp)
{
struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz);
struct thermal_trip trip;
int ret;
ret = __thermal_zone_get_trip(chip->tz_dev, trip_id, &trip);
if (ret)
return ret;
if (trip.type != THERMAL_TRIP_CRITICAL)
if (trip->type != THERMAL_TRIP_CRITICAL)
return 0;
mutex_lock(&chip->lock);

View File

@ -582,23 +582,18 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
return temp;
}
static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp)
static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz,
const struct thermal_trip *trip, int temp)
{
struct tegra_thermctl_zone *zone = thermal_zone_device_priv(tz);
struct tegra_soctherm *ts = zone->ts;
struct thermal_trip trip;
const struct tegra_tsensor_group *sg = zone->sg;
struct device *dev = zone->dev;
int ret;
if (!tz)
return -EINVAL;
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
if (ret)
return ret;
if (trip.type == THERMAL_TRIP_CRITICAL) {
if (trip->type == THERMAL_TRIP_CRITICAL) {
/*
* If thermtrips property is set in DT,
* doesn't need to program critical type trip to HW,
@ -609,7 +604,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
else
return 0;
} else if (trip.type == THERMAL_TRIP_HOT) {
} else if (trip->type == THERMAL_TRIP_HOT) {
int i;
for (i = 0; i < THROTTLE_SIZE; i++) {
@ -620,7 +615,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
continue;
cdev = ts->throt_cfgs[i].cdev;
if (get_thermal_instance(tz, cdev, trip_id))
if (thermal_trip_is_bound_to_cdev(tz, trip, cdev))
stc = find_throttle_cfg_by_name(ts, cdev->type);
else
continue;

View File

@ -1130,7 +1130,7 @@ static void thermal_cooling_device_release(struct device *dev, void *res)
struct thermal_cooling_device *
devm_thermal_of_cooling_device_register(struct device *dev,
struct device_node *np,
char *type, void *devdata,
const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
{
struct thermal_cooling_device **ptr, *tcd;
@ -1357,7 +1357,8 @@ thermal_zone_device_register_with_trips(const char *type,
int num_trips, void *devdata,
const struct thermal_zone_device_ops *ops,
const struct thermal_zone_params *tzp,
int passive_delay, int polling_delay)
unsigned int passive_delay,
unsigned int polling_delay)
{
const struct thermal_trip *trip = trips;
struct thermal_zone_device *tz;
@ -1390,6 +1391,14 @@ thermal_zone_device_register_with_trips(const char *type,
if (num_trips > 0 && !trips)
return ERR_PTR(-EINVAL);
if (polling_delay) {
if (passive_delay > polling_delay)
return ERR_PTR(-EINVAL);
if (!passive_delay)
passive_delay = polling_delay;
}
if (!thermal_class)
return ERR_PTR(-ENODEV);

View File

@ -39,30 +39,53 @@ int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip
return trend;
}
struct thermal_instance *
get_thermal_instance(struct thermal_zone_device *tz,
struct thermal_cooling_device *cdev, int trip_index)
static struct thermal_instance *get_instance(struct thermal_zone_device *tz,
struct thermal_cooling_device *cdev,
const struct thermal_trip *trip)
{
struct thermal_instance *pos = NULL;
struct thermal_instance *target_instance = NULL;
const struct thermal_trip *trip;
struct thermal_instance *ti;
list_for_each_entry(ti, &tz->thermal_instances, tz_node) {
if (ti->trip == trip && ti->cdev == cdev)
return ti;
}
return NULL;
}
bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz,
const struct thermal_trip *trip,
struct thermal_cooling_device *cdev)
{
bool ret;
mutex_lock(&tz->lock);
mutex_lock(&cdev->lock);
trip = &tz->trips[trip_index].trip;
list_for_each_entry(pos, &tz->thermal_instances, tz_node) {
if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
target_instance = pos;
break;
}
}
ret = !!get_instance(tz, cdev, trip);
mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock);
return target_instance;
return ret;
}
EXPORT_SYMBOL_GPL(thermal_trip_is_bound_to_cdev);
struct thermal_instance *
get_thermal_instance(struct thermal_zone_device *tz,
struct thermal_cooling_device *cdev, int trip_index)
{
struct thermal_instance *ti;
mutex_lock(&tz->lock);
mutex_lock(&cdev->lock);
ti = get_instance(tz, cdev, &tz->trips[trip_index].trip);
mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock);
return ti;
}
EXPORT_SYMBOL(get_thermal_instance);

View File

@ -113,7 +113,7 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
if (temp != trip->temperature) {
if (tz->ops.set_trip_temp) {
ret = tz->ops.set_trip_temp(tz, trip_id, temp);
ret = tz->ops.set_trip_temp(tz, trip, temp);
if (ret)
goto unlock;
}

View File

@ -114,27 +114,17 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
dev_err(&tz->device, "Failed to set trips: %d\n", ret);
}
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
struct thermal_trip *trip)
{
if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip)
return -EINVAL;
*trip = tz->trips[trip_id].trip;
return 0;
}
EXPORT_SYMBOL_GPL(__thermal_zone_get_trip);
int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
struct thermal_trip *trip)
{
int ret;
if (!tz || !trip || trip_id < 0 || trip_id >= tz->num_trips)
return -EINVAL;
mutex_lock(&tz->lock);
ret = __thermal_zone_get_trip(tz, trip_id, trip);
*trip = tz->trips[trip_id].trip;
mutex_unlock(&tz->lock);
return ret;
return 0;
}
EXPORT_SYMBOL_GPL(thermal_zone_get_trip);

View File

@ -239,13 +239,34 @@ static irqreturn_t uniphier_tm_alarm_irq_thread(int irq, void *_tdev)
return IRQ_HANDLED;
}
struct trip_walk_data {
struct uniphier_tm_dev *tdev;
int crit_temp;
int index;
};
static int uniphier_tm_trip_walk_cb(struct thermal_trip *trip, void *arg)
{
struct trip_walk_data *twd = arg;
if (trip->type == THERMAL_TRIP_CRITICAL &&
trip->temperature < twd->crit_temp)
twd->crit_temp = trip->temperature;
uniphier_tm_set_alert(twd->tdev, twd->index, trip->temperature);
twd->tdev->alert_en[twd->index++] = true;
return 0;
}
static int uniphier_tm_probe(struct platform_device *pdev)
{
struct trip_walk_data twd = { .crit_temp = INT_MAX, .index = 0 };
struct device *dev = &pdev->dev;
struct regmap *regmap;
struct device_node *parent;
struct uniphier_tm_dev *tdev;
int i, ret, irq, crit_temp = INT_MAX;
int ret, irq;
tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL);
if (!tdev)
@ -293,20 +314,10 @@ static int uniphier_tm_probe(struct platform_device *pdev)
}
/* set alert temperatures */
for (i = 0; i < thermal_zone_get_num_trips(tdev->tz_dev); i++) {
struct thermal_trip trip;
twd.tdev = tdev;
thermal_zone_for_each_trip(tdev->tz_dev, uniphier_tm_trip_walk_cb, &twd);
ret = thermal_zone_get_trip(tdev->tz_dev, i, &trip);
if (ret)
return ret;
if (trip.type == THERMAL_TRIP_CRITICAL &&
trip.temperature < crit_temp)
crit_temp = trip.temperature;
uniphier_tm_set_alert(tdev, i, trip.temperature);
tdev->alert_en[i] = true;
}
if (crit_temp > CRITICAL_TEMP_LIMIT) {
if (twd.crit_temp > CRITICAL_TEMP_LIMIT) {
dev_err(dev, "critical trip is over limit(>%d), or not set\n",
CRITICAL_TEMP_LIMIT);
return -EINVAL;

View File

@ -79,6 +79,9 @@ struct thermal_trip {
#define THERMAL_TRIP_FLAG_RW (THERMAL_TRIP_FLAG_RW_TEMP | \
THERMAL_TRIP_FLAG_RW_HYST)
#define THERMAL_TRIP_PRIV_TO_INT(_val_) (uintptr_t)(_val_)
#define THERMAL_INT_TO_TRIP_PRIV(_val_) (void *)(uintptr_t)(_val_)
struct thermal_zone_device;
struct thermal_zone_device_ops {
@ -90,7 +93,8 @@ struct thermal_zone_device_ops {
int (*set_trips) (struct thermal_zone_device *, int, int);
int (*change_mode) (struct thermal_zone_device *,
enum thermal_device_mode);
int (*set_trip_temp) (struct thermal_zone_device *, int, int);
int (*set_trip_temp) (struct thermal_zone_device *,
const struct thermal_trip *, int);
int (*get_crit_temp) (struct thermal_zone_device *, int *);
int (*set_emul_temp) (struct thermal_zone_device *, int);
int (*get_trend) (struct thermal_zone_device *,
@ -198,8 +202,6 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev,
}
#endif
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
struct thermal_trip *trip);
int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
struct thermal_trip *trip);
int for_each_thermal_trip(struct thermal_zone_device *tz,
@ -221,7 +223,8 @@ struct thermal_zone_device *thermal_zone_device_register_with_trips(
int num_trips, void *devdata,
const struct thermal_zone_device_ops *ops,
const struct thermal_zone_params *tzp,
int passive_delay, int polling_delay);
unsigned int passive_delay,
unsigned int polling_delay);
struct thermal_zone_device *thermal_tripless_zone_device_register(
const char *type,
@ -261,7 +264,7 @@ thermal_of_cooling_device_register(struct device_node *np, const char *, void *,
struct thermal_cooling_device *
devm_thermal_of_cooling_device_register(struct device *dev,
struct device_node *np,
char *type, void *devdata,
const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops);
void thermal_cooling_device_update(struct thermal_cooling_device *);
void thermal_cooling_device_unregister(struct thermal_cooling_device *);
@ -269,6 +272,9 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
int thermal_zone_get_slope(struct thermal_zone_device *tz);
int thermal_zone_get_offset(struct thermal_zone_device *tz);
bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz,
const struct thermal_trip *trip,
struct thermal_cooling_device *cdev);
int thermal_zone_device_enable(struct thermal_zone_device *tz);
int thermal_zone_device_disable(struct thermal_zone_device *tz);
@ -305,7 +311,7 @@ thermal_of_cooling_device_register(struct device_node *np,
static inline struct thermal_cooling_device *
devm_thermal_of_cooling_device_register(struct device *dev,
struct device_node *np,
char *type, void *devdata,
const char *type, void *devdata,
const struct thermal_cooling_device_ops *ops)
{
return ERR_PTR(-ENODEV);