Skip to content

Commit 423de5b

Browse files
committed
thermal/of: Fix cdev lookup in thermal_of_should_bind()
Since thermal_of_should_bind() terminates the loop after processing the first child found in cooling-maps, it will never match more than one cdev to a given trip point which is incorrect, as there may be cooling-maps associating one trip point with multiple cooling devices. Address this by letting the loop continue until either all children have been processed or a matching one has been found. To avoid adding conditionals or goto statements, put the loop in question into a separate function and make that function return right away after finding a matching cooling-maps entry. Fixes: 94c6110 ("thermal/of: Use the .should_bind() thermal zone callback") Link: https://lore.kernel.org/linux-pm/20250219-fix-thermal-of-v1-1-de36e7a590c4@chromium.org/ Reported-by: Yu-Che Cheng <giver@chromium.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Yu-Che Cheng <giver@chromium.org> Tested-by: Yu-Che Cheng <giver@chromium.org> Reviewed-by: Lukasz Luba <lukasz.luba@arm.com> Tested-by: Lukasz Luba <lukasz.luba@arm.com> Link: https://patch.msgid.link/2788228.mvXUDI8C0e@rjwysocki.net
1 parent 4ecaa75 commit 423de5b

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

drivers/thermal/thermal_of.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,34 @@ static bool thermal_of_get_cooling_spec(struct device_node *map_np, int index,
274274
return true;
275275
}
276276

277+
static bool thermal_of_cm_lookup(struct device_node *cm_np,
278+
const struct thermal_trip *trip,
279+
struct thermal_cooling_device *cdev,
280+
struct cooling_spec *c)
281+
{
282+
for_each_child_of_node_scoped(cm_np, child) {
283+
struct device_node *tr_np;
284+
int count, i;
285+
286+
tr_np = of_parse_phandle(child, "trip", 0);
287+
if (tr_np != trip->priv)
288+
continue;
289+
290+
/* The trip has been found, look up the cdev. */
291+
count = of_count_phandle_with_args(child, "cooling-device",
292+
"#cooling-cells");
293+
if (count <= 0)
294+
pr_err("Add a cooling_device property with at least one device\n");
295+
296+
for (i = 0; i < count; i++) {
297+
if (thermal_of_get_cooling_spec(child, i, cdev, c))
298+
return true;
299+
}
300+
}
301+
302+
return false;
303+
}
304+
277305
static bool thermal_of_should_bind(struct thermal_zone_device *tz,
278306
const struct thermal_trip *trip,
279307
struct thermal_cooling_device *cdev,
@@ -293,27 +321,7 @@ static bool thermal_of_should_bind(struct thermal_zone_device *tz,
293321
goto out;
294322

295323
/* Look up the trip and the cdev in the cooling maps. */
296-
for_each_child_of_node_scoped(cm_np, child) {
297-
struct device_node *tr_np;
298-
int count, i;
299-
300-
tr_np = of_parse_phandle(child, "trip", 0);
301-
if (tr_np != trip->priv)
302-
continue;
303-
304-
/* The trip has been found, look up the cdev. */
305-
count = of_count_phandle_with_args(child, "cooling-device", "#cooling-cells");
306-
if (count <= 0)
307-
pr_err("Add a cooling_device property with at least one device\n");
308-
309-
for (i = 0; i < count; i++) {
310-
result = thermal_of_get_cooling_spec(child, i, cdev, c);
311-
if (result)
312-
break;
313-
}
314-
315-
break;
316-
}
324+
result = thermal_of_cm_lookup(cm_np, trip, cdev, c);
317325

318326
of_node_put(cm_np);
319327
out:

0 commit comments

Comments
 (0)