From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM <linux-pm@vger.kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Lukasz Luba <lukasz.luba@arm.com>,
Zhang Rui <rui.zhang@intel.com>,
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Subject: [PATCH v3 12/14] thermal/of: Use the .should_bind() thermal zone callback
Date: Mon, 19 Aug 2024 18:30:18 +0200 [thread overview]
Message-ID: <2236794.NgBsaNRSFp@rjwysocki.net> (raw)
In-Reply-To: <2205737.irdbgypaU6@rjwysocki.net>
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Make the thermal_of driver use the .should_bind() thermal zone callback
to provide the thermal core with the information on whether or not to
bind the given cooling device to the given trip point in the given
thermal zone. If it returns 'true', the thermal core will bind the
cooling device to the trip and the corresponding unbinding will be
taken care of automatically by the core on the removal of the involved
thermal zone or cooling device.
This replaces the .bind() and .unbind() thermal zone callbacks which
assumed the same trip points ordering in the driver and in the thermal
core (that may not be true any more in the future). The .bind()
callback would walk the given thermal zone's cooling maps to find all
of the valid trip point combinations with the given cooling device and
it would call thermal_zone_bind_cooling_device() for all of them using
trip point indices reflecting the ordering of the trips in the DT.
The .should_bind() callback still walks the thermal zone's cooling maps,
but it can use the trip object passed to it by the thermal core to find
the trip in question in the first place and then it uses the
corresponding 'cooling-device' entries to look up the given cooling
device. To be able to match the trip object provided by the thermal
core to a specific device node, the driver sets the 'priv' field of each
trip to the corresponding device node pointer during initialization.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v2 -> v3: Reorder (previously [14/17])
v1 -> v2:
* Fix a build issue (undefined symbol)
This patch only depends on the [06/14] introducing the .should_bind()
thermal zone callback:
https://lore.kernel.org/linux-pm/9334403.CDJkKcVGEf@rjwysocki.net/
---
drivers/thermal/thermal_of.c | 171 ++++++++++---------------------------------
1 file changed, 41 insertions(+), 130 deletions(-)
Index: linux-pm/drivers/thermal/thermal_of.c
===================================================================
--- linux-pm.orig/drivers/thermal/thermal_of.c
+++ linux-pm/drivers/thermal/thermal_of.c
@@ -20,37 +20,6 @@
/*** functions parsing device tree nodes ***/
-static int of_find_trip_id(struct device_node *np, struct device_node *trip)
-{
- struct device_node *trips;
- struct device_node *t;
- int i = 0;
-
- trips = of_get_child_by_name(np, "trips");
- if (!trips) {
- pr_err("Failed to find 'trips' node\n");
- return -EINVAL;
- }
-
- /*
- * Find the trip id point associated with the cooling device map
- */
- for_each_child_of_node(trips, t) {
-
- if (t == trip) {
- of_node_put(t);
- goto out;
- }
- i++;
- }
-
- i = -ENXIO;
-out:
- of_node_put(trips);
-
- return i;
-}
-
/*
* It maps 'enum thermal_trip_type' found in include/linux/thermal.h
* into the device tree binding of 'trip', property type.
@@ -119,6 +88,8 @@ static int thermal_of_populate_trip(stru
trip->flags = THERMAL_TRIP_FLAG_RW_TEMP;
+ trip->priv = np;
+
return 0;
}
@@ -290,39 +261,9 @@ static struct device_node *thermal_of_zo
return tz_np;
}
-static int __thermal_of_unbind(struct device_node *map_np, int index, int trip_id,
- struct thermal_zone_device *tz, struct thermal_cooling_device *cdev)
-{
- struct of_phandle_args cooling_spec;
- int ret;
-
- ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells",
- index, &cooling_spec);
-
- if (ret < 0) {
- pr_err("Invalid cooling-device entry\n");
- return ret;
- }
-
- of_node_put(cooling_spec.np);
-
- if (cooling_spec.args_count < 2) {
- pr_err("wrong reference to cooling device, missing limits\n");
- return -EINVAL;
- }
-
- if (cooling_spec.np != cdev->np)
- return 0;
-
- ret = thermal_zone_unbind_cooling_device(tz, trip_id, cdev);
- if (ret)
- pr_err("Failed to unbind '%s' with '%s': %d\n", tz->type, cdev->type, ret);
-
- return ret;
-}
-
-static int __thermal_of_bind(struct device_node *map_np, int index, int trip_id,
- struct thermal_zone_device *tz, struct thermal_cooling_device *cdev)
+static bool thermal_of_get_cooling_spec(struct device_node *map_np, int index,
+ struct thermal_cooling_device *cdev,
+ struct cooling_spec *c)
{
struct of_phandle_args cooling_spec;
int ret, weight = THERMAL_WEIGHT_DEFAULT;
@@ -334,104 +275,75 @@ static int __thermal_of_bind(struct devi
if (ret < 0) {
pr_err("Invalid cooling-device entry\n");
- return ret;
+ return false;
}
of_node_put(cooling_spec.np);
if (cooling_spec.args_count < 2) {
pr_err("wrong reference to cooling device, missing limits\n");
- return -EINVAL;
+ return false;
}
if (cooling_spec.np != cdev->np)
- return 0;
-
- ret = thermal_zone_bind_cooling_device(tz, trip_id, cdev, cooling_spec.args[1],
- cooling_spec.args[0],
- weight);
- if (ret)
- pr_err("Failed to bind '%s' with '%s': %d\n", tz->type, cdev->type, ret);
-
- return ret;
-}
-
-static int thermal_of_for_each_cooling_device(struct device_node *tz_np, struct device_node *map_np,
- struct thermal_zone_device *tz, struct thermal_cooling_device *cdev,
- int (*action)(struct device_node *, int, int,
- struct thermal_zone_device *, struct thermal_cooling_device *))
-{
- struct device_node *tr_np;
- int count, i, trip_id;
-
- tr_np = of_parse_phandle(map_np, "trip", 0);
- if (!tr_np)
- return -ENODEV;
-
- trip_id = of_find_trip_id(tz_np, tr_np);
- if (trip_id < 0)
- return trip_id;
-
- count = of_count_phandle_with_args(map_np, "cooling-device", "#cooling-cells");
- if (count <= 0) {
- pr_err("Add a cooling_device property with at least one device\n");
- return -ENOENT;
- }
+ return false;
- /*
- * At this point, we don't want to bail out when there is an
- * error, we will try to bind/unbind as many as possible
- * cooling devices
- */
- for (i = 0; i < count; i++)
- action(map_np, i, trip_id, tz, cdev);
+ c->lower = cooling_spec.args[0];
+ c->upper = cooling_spec.args[1];
+ c->weight = weight;
- return 0;
+ return true;
}
-static int thermal_of_for_each_cooling_maps(struct thermal_zone_device *tz,
- struct thermal_cooling_device *cdev,
- int (*action)(struct device_node *, int, int,
- struct thermal_zone_device *, struct thermal_cooling_device *))
+static bool thermal_of_should_bind(struct thermal_zone_device *tz,
+ const struct thermal_trip *trip,
+ struct thermal_cooling_device *cdev,
+ struct cooling_spec *c)
{
struct device_node *tz_np, *cm_np, *child;
- int ret = 0;
+ bool result = false;
tz_np = thermal_of_zone_get_by_name(tz);
if (IS_ERR(tz_np)) {
pr_err("Failed to get node tz by name\n");
- return PTR_ERR(tz_np);
+ return false;
}
cm_np = of_get_child_by_name(tz_np, "cooling-maps");
if (!cm_np)
goto out;
+ /* Look up the trip and the cdev in the cooling maps. */
for_each_child_of_node(cm_np, child) {
- ret = thermal_of_for_each_cooling_device(tz_np, child, tz, cdev, action);
- if (ret) {
+ struct device_node *tr_np;
+ int count, i;
+
+ tr_np = of_parse_phandle(child, "trip", 0);
+ if (tr_np != trip->priv) {
of_node_put(child);
- break;
+ continue;
+ }
+
+ /* The trip has been found, look up the cdev. */
+ count = of_count_phandle_with_args(child, "cooling-device", "#cooling-cells");
+ if (count <= 0)
+ pr_err("Add a cooling_device property with at least one device\n");
+
+ for (i = 0; i < count; i++) {
+ result = thermal_of_get_cooling_spec(child, i, cdev, c);
+ if (result)
+ break;
}
+
+ of_node_put(child);
+ break;
}
of_node_put(cm_np);
out:
of_node_put(tz_np);
- return ret;
-}
-
-static int thermal_of_bind(struct thermal_zone_device *tz,
- struct thermal_cooling_device *cdev)
-{
- return thermal_of_for_each_cooling_maps(tz, cdev, __thermal_of_bind);
-}
-
-static int thermal_of_unbind(struct thermal_zone_device *tz,
- struct thermal_cooling_device *cdev)
-{
- return thermal_of_for_each_cooling_maps(tz, cdev, __thermal_of_unbind);
+ return result;
}
/**
@@ -502,8 +414,7 @@ static struct thermal_zone_device *therm
thermal_of_parameters_init(np, &tzp);
- of_ops.bind = thermal_of_bind;
- of_ops.unbind = thermal_of_unbind;
+ of_ops.should_bind = thermal_of_should_bind;
ret = of_property_read_string(np, "critical-action", &action);
if (!ret)
next prev parent reply other threads:[~2024-08-19 16:33 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-19 15:49 [PATCH v3 00/14] thermal: Rework binding cooling devices to trip points Rafael J. Wysocki
2024-08-19 15:50 ` [PATCH v3 01/14] thermal: core: Fold two functions into their respective callers Rafael J. Wysocki
2024-08-20 7:04 ` Zhang, Rui
2024-08-21 7:57 ` Daniel Lezcano
2024-08-19 15:51 ` [PATCH v3 02/14] thermal: core: Rearrange checks in thermal_bind_cdev_to_trip() Rafael J. Wysocki
2024-08-20 7:05 ` Zhang, Rui
2024-08-21 7:59 ` Daniel Lezcano
2024-08-21 8:49 ` lihuisong (C)
2024-08-21 9:28 ` Daniel Lezcano
2024-08-21 9:44 ` lihuisong (C)
2024-08-21 10:49 ` Daniel Lezcano
2024-08-21 11:22 ` lihuisong (C)
2024-08-21 11:12 ` Rafael J. Wysocki
2024-08-21 10:51 ` Rafael J. Wysocki
2024-08-19 15:52 ` [PATCH v3 03/14] thermal: core: Drop redundant thermal instance checks Rafael J. Wysocki
2024-08-20 7:05 ` Zhang, Rui
2024-08-21 9:32 ` Daniel Lezcano
2024-08-21 11:11 ` Rafael J. Wysocki
2024-08-21 11:56 ` Daniel Lezcano
2024-08-21 12:52 ` Rafael J. Wysocki
2024-08-19 15:56 ` [PATCH v3 04/14] thermal: sysfs: Use the dev argument in instance-related show/store Rafael J. Wysocki
2024-08-20 7:05 ` Zhang, Rui
2024-08-20 7:59 ` lihuisong (C)
2024-08-21 9:36 ` Daniel Lezcano
2024-08-19 15:58 ` [PATCH v3 05/14] thermal: core: Move thermal zone locking out of bind/unbind functions Rafael J. Wysocki
2024-08-20 7:05 ` Zhang, Rui
2024-08-20 8:27 ` lihuisong (C)
2024-08-20 10:27 ` Rafael J. Wysocki
2024-08-21 9:02 ` lihuisong (C)
2024-08-21 10:30 ` Rafael J. Wysocki
2024-08-21 9:46 ` Daniel Lezcano
2024-08-19 16:00 ` [PATCH v3 06/14] thermal: core: Introduce .should_bind() thermal zone callback Rafael J. Wysocki
2024-08-20 7:06 ` Zhang, Rui
2024-08-21 9:09 ` lihuisong (C)
2024-08-21 13:21 ` Daniel Lezcano
2024-08-19 16:02 ` [PATCH v3 07/14] thermal: ACPI: Use the " Rafael J. Wysocki
2024-08-20 7:06 ` Zhang, Rui
2024-08-21 13:22 ` Daniel Lezcano
2024-08-19 16:05 ` [PATCH v3 08/14] thermal: core: Unexport thermal_bind_cdev_to_trip() and thermal_unbind_cdev_from_trip() Rafael J. Wysocki
2024-08-20 7:08 ` Zhang, Rui
2024-08-21 9:18 ` lihuisong (C)
2024-08-21 13:23 ` Daniel Lezcano
2024-08-19 16:19 ` [PATCH v3 09/14] platform/x86: acerhdf: Use the .should_bind() thermal zone callback Rafael J. Wysocki
2024-08-19 20:24 ` Peter Kästle
2024-08-21 13:25 ` Daniel Lezcano
2024-08-19 16:24 ` [PATCH v3 10/14] mlxsw: core_thermal: " Rafael J. Wysocki
2024-08-19 16:26 ` [PATCH v3 11/14] thermal: imx: " Rafael J. Wysocki
2024-08-21 13:42 ` Daniel Lezcano
2024-08-19 16:30 ` Rafael J. Wysocki [this message]
2024-08-21 14:20 ` [PATCH v3 12/14] thermal/of: " Daniel Lezcano
2024-08-26 11:31 ` Marek Szyprowski
2024-08-26 12:14 ` Rafael J. Wysocki
2024-08-26 20:49 ` Marek Szyprowski
2024-08-27 11:39 ` Rafael J. Wysocki
2024-08-19 16:31 ` [PATCH v3 13/14] thermal: core: Drop unused bind/unbind functions and callbacks Rafael J. Wysocki
2024-08-20 7:10 ` Zhang, Rui
2024-08-21 9:33 ` lihuisong (C)
2024-08-21 14:24 ` Daniel Lezcano
2024-08-19 16:33 ` [PATCH v3 14/14] thermal: core: Clean up trip bind/unbind functions Rafael J. Wysocki
2024-08-20 7:11 ` Zhang, Rui
2024-08-21 9:34 ` lihuisong (C)
2024-08-21 14:29 ` Daniel Lezcano
2024-08-21 16:21 ` Rafael J. Wysocki
2024-08-24 18:45 ` [PATCH v3 00/14] thermal: Rework binding cooling devices to trip points Nícolas F. R. A. Prado
2024-08-26 9:58 ` Rafael J. Wysocki
2024-08-30 13:55 ` Nícolas F. R. A. Prado
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2236794.NgBsaNRSFp@rjwysocki.net \
--to=rjw@rjwysocki.net \
--cc=daniel.lezcano@linaro.org \
--cc=krzysztof.kozlowski@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lukasz.luba@arm.com \
--cc=rui.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox