Skip to content

Commit

Permalink
Merge branch 'thermal-core'
Browse files Browse the repository at this point in the history
Merge thermal core updates for 6.12 which, among other things, rework
the thermal driver interface for binding cooling devices to thermal
zones and add a thermal core testing module:

 - Update some thermal drivers to eliminate thermal_zone_get_trip()
   calls from them and get rid of that function (Rafael Wysocki).

 - Update the thermal sysfs code to store trip point attributes in trip
   descriptors and get to trip points via attribute pointers (Rafael
   Wysocki).

 - Move the computation of the low and high boundaries for
   thermal_zone_set_trips() to __thermal_zone_device_update() (Daniel
   Lezcano).

 - Introduce a debugfs-based facility for thermal core testing (Rafael
   Wysocki).

 - Replace the thermal zone .bind() and .unbind() callbacks for binding
   cooling devices to thermal zones with one .should_bind() callback
   used for deciding whether or not a given cooling devices should be
   bound to a given trip point in a given thermal zone (Rafael Wysocki).

 - Eliminate code that has no more users after the other changes, drop
   some redundant checks from the thermal core and clean it up (Rafael
   Wysocki).

 - Fix rounding of delay jiffies in the thermal core (Rafael Wysocki).

* thermal-core: (31 commits)
  thermal: core: Drop tz field from struct thermal_instance
  thermal: core: Drop redundant checks from thermal_bind_cdev_to_trip()
  thermal: core: Rename cdev-to-thermal-zone bind/unbind functions
  thermal: core: Fix rounding of delay jiffies
  thermal: core: Clean up trip bind/unbind functions
  thermal: core: Drop unused bind/unbind functions and callbacks
  thermal/of: Use the .should_bind() thermal zone callback
  thermal: imx: Use the .should_bind() thermal zone callback
  mlxsw: core_thermal: Use the .should_bind() thermal zone callback
  platform/x86: acerhdf: Use the .should_bind() thermal zone callback
  thermal: core: Unexport thermal_bind_cdev_to_trip() and thermal_unbind_cdev_from_trip()
  thermal: ACPI: Use the .should_bind() thermal zone callback
  thermal: core: Introduce .should_bind() thermal zone callback
  thermal: core: Move thermal zone locking out of bind/unbind functions
  thermal: sysfs: Use the dev argument in instance-related show/store
  thermal: core: Drop redundant thermal instance checks
  thermal: core: Rearrange checks in thermal_bind_cdev_to_trip()
  thermal: core: Fold two functions into their respective callers
  thermal: Introduce a debugfs-based testing facility
  thermal/core: Compute low and high boundaries in thermal_zone_device_update()
  ...
  • Loading branch information
Rafael J. Wysocki committed Aug 29, 2024
2 parents c0a1ef9 + e965465 commit f5c0597
Show file tree
Hide file tree
Showing 24 changed files with 1,076 additions and 819 deletions.
68 changes: 4 additions & 64 deletions Documentation/driver-api/thermal/sysfs-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ temperature) and throttle appropriate devices.
ops:
thermal zone device call-backs.

.bind:
bind the thermal zone device with a thermal cooling device.
.unbind:
unbind the thermal zone device with a thermal cooling device.
.should_bind:
check whether or not a given cooling device should be bound to
a given trip point in this thermal zone.
.get_temp:
get the current temperature of the thermal zone.
.set_trips:
Expand Down Expand Up @@ -246,56 +245,6 @@ temperature) and throttle appropriate devices.
It deletes the corresponding entry from /sys/class/thermal folder and
unbinds itself from all the thermal zone devices using it.

1.3 interface for binding a thermal zone device with a thermal cooling device
-----------------------------------------------------------------------------

::

int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
int trip, struct thermal_cooling_device *cdev,
unsigned long upper, unsigned long lower, unsigned int weight);
This interface function binds a thermal cooling device to a particular trip
point of a thermal zone device.

This function is usually called in the thermal zone device .bind callback.

tz:
the thermal zone device
cdev:
thermal cooling device
trip:
indicates which trip point in this thermal zone the cooling device
is associated with.
upper:
the Maximum cooling state for this trip point.
THERMAL_NO_LIMIT means no upper limit,
and the cooling device can be in max_state.
lower:
the Minimum cooling state can be used for this trip point.
THERMAL_NO_LIMIT means no lower limit,
and the cooling device can be in cooling state 0.
weight:
the influence of this cooling device in this thermal
zone. See 1.4.1 below for more information.

::

int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
int trip, struct thermal_cooling_device *cdev);
This interface function unbinds a thermal cooling device from a particular
trip point of a thermal zone device. This function is usually called in
the thermal zone device .unbind callback.

tz:
the thermal zone device
cdev:
thermal cooling device
trip:
indicates which trip point in this thermal zone the cooling device
is associated with.

1.4 Thermal Zone Parameters
---------------------------

Expand Down Expand Up @@ -366,8 +315,6 @@ Thermal cooling device sys I/F, created once it's registered::

Then next two dynamic attributes are created/removed in pairs. They represent
the relationship between a thermal zone and its associated cooling device.
They are created/removed for each successful execution of
thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device.

::

Expand Down Expand Up @@ -459,14 +406,7 @@ are supposed to implement the callback. If they don't, the thermal
framework calculated the trend by comparing the previous and the current
temperature values.

4.2. get_thermal_instance
-------------------------

This function returns the thermal_instance corresponding to a given
{thermal_zone, cooling_device, trip_point} combination. Returns NULL
if such an instance does not exist.

4.3. thermal_cdev_update
4.2. thermal_cdev_update
------------------------

This function serves as an arbitrator to set the state of a cooling
Expand Down
66 changes: 10 additions & 56 deletions drivers/acpi/thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,77 +558,31 @@ static void acpi_thermal_zone_device_critical(struct thermal_zone_device *therma
thermal_zone_device_critical(thermal);
}

struct acpi_thermal_bind_data {
struct thermal_zone_device *thermal;
struct thermal_cooling_device *cdev;
bool bind;
};

static int bind_unbind_cdev_cb(struct thermal_trip *trip, void *arg)
static bool acpi_thermal_should_bind_cdev(struct thermal_zone_device *thermal,
const struct thermal_trip *trip,
struct thermal_cooling_device *cdev,
struct cooling_spec *c)
{
struct acpi_thermal_trip *acpi_trip = trip->priv;
struct acpi_thermal_bind_data *bd = arg;
struct thermal_zone_device *thermal = bd->thermal;
struct thermal_cooling_device *cdev = bd->cdev;
struct acpi_device *cdev_adev = cdev->devdata;
int i;

/* Skip critical and hot trips. */
if (!acpi_trip)
return 0;
return false;

for (i = 0; i < acpi_trip->devices.count; i++) {
acpi_handle handle = acpi_trip->devices.handles[i];
struct acpi_device *adev = acpi_fetch_acpi_dev(handle);

if (adev != cdev_adev)
continue;

if (bd->bind) {
int ret;

ret = thermal_bind_cdev_to_trip(thermal, trip, cdev,
THERMAL_NO_LIMIT,
THERMAL_NO_LIMIT,
THERMAL_WEIGHT_DEFAULT);
if (ret)
return ret;
} else {
thermal_unbind_cdev_from_trip(thermal, trip, cdev);
}
}

return 0;
}

static int acpi_thermal_bind_unbind_cdev(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev,
bool bind)
{
struct acpi_thermal_bind_data bd = {
.thermal = thermal, .cdev = cdev, .bind = bind
};

return for_each_thermal_trip(thermal, bind_unbind_cdev_cb, &bd);
}

static int
acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev)
{
return acpi_thermal_bind_unbind_cdev(thermal, cdev, true);
}
if (acpi_fetch_acpi_dev(handle) == cdev_adev)
return true;
}

static int
acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev)
{
return acpi_thermal_bind_unbind_cdev(thermal, cdev, false);
return false;
}

static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
.bind = acpi_thermal_bind_cooling_device,
.unbind = acpi_thermal_unbind_cooling_device,
.should_bind = acpi_thermal_should_bind_cdev,
.get_temp = thermal_get_temp,
.get_trend = thermal_get_trend,
.hot = acpi_thermal_zone_device_hot,
Expand Down
115 changes: 31 additions & 84 deletions drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,52 +165,22 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
return -ENODEV;
}

static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
struct thermal_cooling_device *cdev)
static bool mlxsw_thermal_should_bind(struct thermal_zone_device *tzdev,
const struct thermal_trip *trip,
struct thermal_cooling_device *cdev,
struct cooling_spec *c)
{
struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev);
struct device *dev = thermal->bus_info->dev;
int i, err;
const struct mlxsw_cooling_states *state = trip->priv;

/* If the cooling device is one of ours bind it */
if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
return 0;
return false;

for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
const struct mlxsw_cooling_states *state = &thermal->cooling_states[i];
c->upper = state->max_state;
c->lower = state->min_state;

err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
state->max_state,
state->min_state,
THERMAL_WEIGHT_DEFAULT);
if (err < 0) {
dev_err(dev, "Failed to bind cooling device to trip %d\n", i);
return err;
}
}
return 0;
}

static int mlxsw_thermal_unbind(struct thermal_zone_device *tzdev,
struct thermal_cooling_device *cdev)
{
struct mlxsw_thermal *thermal = thermal_zone_device_priv(tzdev);
struct device *dev = thermal->bus_info->dev;
int i;
int err;

/* If the cooling device is our one unbind it */
if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
return 0;

for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
err = thermal_zone_unbind_cooling_device(tzdev, i, cdev);
if (err < 0) {
dev_err(dev, "Failed to unbind cooling device\n");
return err;
}
}
return 0;
return true;
}

static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
Expand Down Expand Up @@ -240,57 +210,27 @@ static struct thermal_zone_params mlxsw_thermal_params = {
};

static struct thermal_zone_device_ops mlxsw_thermal_ops = {
.bind = mlxsw_thermal_bind,
.unbind = mlxsw_thermal_unbind,
.should_bind = mlxsw_thermal_should_bind,
.get_temp = mlxsw_thermal_get_temp,
};

static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
struct thermal_cooling_device *cdev)
static bool mlxsw_thermal_module_should_bind(struct thermal_zone_device *tzdev,
const struct thermal_trip *trip,
struct thermal_cooling_device *cdev,
struct cooling_spec *c)
{
struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev);
const struct mlxsw_cooling_states *state = trip->priv;
struct mlxsw_thermal *thermal = tz->parent;
int i, j, err;

/* If the cooling device is one of ours bind it */
if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
return 0;
return false;

for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
const struct mlxsw_cooling_states *state = &tz->cooling_states[i];
c->upper = state->max_state;
c->lower = state->min_state;

err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
state->max_state,
state->min_state,
THERMAL_WEIGHT_DEFAULT);
if (err < 0)
goto err_thermal_zone_bind_cooling_device;
}
return 0;

err_thermal_zone_bind_cooling_device:
for (j = i - 1; j >= 0; j--)
thermal_zone_unbind_cooling_device(tzdev, j, cdev);
return err;
}

static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev,
struct thermal_cooling_device *cdev)
{
struct mlxsw_thermal_module *tz = thermal_zone_device_priv(tzdev);
struct mlxsw_thermal *thermal = tz->parent;
int i;
int err;

/* If the cooling device is one of ours unbind it */
if (mlxsw_get_cooling_device_idx(thermal, cdev) < 0)
return 0;

for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
err = thermal_zone_unbind_cooling_device(tzdev, i, cdev);
WARN_ON(err);
}
return err;
return true;
}

static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
Expand All @@ -313,8 +253,7 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
}

static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
.bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind,
.should_bind = mlxsw_thermal_module_should_bind,
.get_temp = mlxsw_thermal_module_temp_get,
};

Expand Down Expand Up @@ -342,8 +281,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
}

static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
.bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind,
.should_bind = mlxsw_thermal_module_should_bind,
.get_temp = mlxsw_thermal_gearbox_temp_get,
};

Expand Down Expand Up @@ -451,6 +389,7 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
struct mlxsw_thermal_area *area, u8 module)
{
struct mlxsw_thermal_module *module_tz;
int i;

module_tz = &area->tz_module_arr[module];
/* Skip if parent is already set (case of port split). */
Expand All @@ -465,6 +404,8 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
sizeof(thermal->trips));
memcpy(module_tz->cooling_states, default_cooling_states,
sizeof(thermal->cooling_states));
for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++)
module_tz->trips[i].priv = &module_tz->cooling_states[i];
}

static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
Expand Down Expand Up @@ -579,7 +520,7 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
struct mlxsw_thermal_module *gearbox_tz;
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
u8 gbox_num;
int i;
int i, j;
int err;

mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index);
Expand All @@ -606,6 +547,9 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
sizeof(thermal->trips));
memcpy(gearbox_tz->cooling_states, default_cooling_states,
sizeof(thermal->cooling_states));
for (j = 0; j < MLXSW_THERMAL_NUM_TRIPS; j++)
gearbox_tz->trips[j].priv = &gearbox_tz->cooling_states[j];

gearbox_tz->module = i;
gearbox_tz->parent = thermal;
gearbox_tz->slot_index = area->slot_index;
Expand Down Expand Up @@ -722,6 +666,9 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
thermal->bus_info = bus_info;
memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
memcpy(thermal->cooling_states, default_cooling_states, sizeof(thermal->cooling_states));
for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++)
thermal->trips[i].priv = &thermal->cooling_states[i];

thermal->line_cards[0].slot_index = 0;

err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
Expand Down
Loading

0 comments on commit f5c0597

Please sign in to comment.