From 7082503622986537f57bdb5ef23e69e70cfad881 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 14 Nov 2024 12:02:13 -0800 Subject: thermal: int3400: Fix reading of current_uuid for active policy When the current_uuid attribute is set to the active policy UUID, reading back the same attribute is returning "INVALID" instead of the active policy UUID on some platforms before Ice Lake. In platforms before Ice Lake, firmware provides a list of supported thermal policies. In this case, user space can select any of the supported thermal policies via a write to attribute "current_uuid". In commit c7ff29763989 ("thermal: int340x: Update OS policy capability handshake")', the OS policy handshake was updated to support Ice Lake and later platforms and it treated priv->current_uuid_index=0 as invalid. However, priv->current_uuid_index=0 is for the active policy, only priv->current_uuid_index=-1 is invalid. Fix this issue by updating the priv->current_uuid_index check. Fixes: c7ff29763989 ("thermal: int340x: Update OS policy capability handshake") Signed-off-by: Srinivas Pandruvada Cc: 5.18+ # 5.18+ Link: https://patch.msgid.link/20241114200213.422303-1-srinivas.pandruvada@linux.intel.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index b2fc02c3a767..c829be13d85d 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -137,7 +137,7 @@ static ssize_t current_uuid_show(struct device *dev, struct int3400_thermal_priv *priv = dev_get_drvdata(dev); int i, length = 0; - if (priv->current_uuid_index > 0) + if (priv->current_uuid_index >= 0) return sprintf(buf, "%s\n", int3400_thermal_uuids[priv->current_uuid_index]); -- cgit v1.2.3 From 13f3cbfbb8c9f3825a1e4e4371fe040fb35e41d5 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Thu, 21 Nov 2024 17:29:32 +0100 Subject: thermal: int3400: Remove unneeded data_vault attribute_group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The group only contains a single entry and the conditionals around its lifecycle make clear that this won't change. Remove the unnecessary group. This saves some memory and it's easier to read. The removal of a non-const bin_attribute[] instance is also a preparation for the constification of struct bin_attributes. Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20241121-sysfs-const-bin_attr-int340x_thermal-v1-1-2436facf9dae@weissschuh.net Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index c829be13d85d..8660ef2175be 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -75,11 +75,6 @@ struct odvp_attr { static BIN_ATTR_SIMPLE_RO(data_vault); -static struct bin_attribute *data_attributes[] = { - &bin_attr_data_vault, - NULL, -}; - static ssize_t imok_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -108,10 +103,6 @@ static const struct attribute_group imok_attribute_group = { .attrs = imok_attr, }; -static const struct attribute_group data_attribute_group = { - .bin_attrs = data_attributes, -}; - static ssize_t available_uuids_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -624,8 +615,7 @@ static int int3400_thermal_probe(struct platform_device *pdev) } if (!ZERO_OR_NULL_PTR(priv->data_vault)) { - result = sysfs_create_group(&pdev->dev.kobj, - &data_attribute_group); + result = device_create_bin_file(&pdev->dev, &bin_attr_data_vault); if (result) goto free_uuid; } @@ -648,7 +638,7 @@ free_notify: free_sysfs: cleanup_odvp(priv); if (!ZERO_OR_NULL_PTR(priv->data_vault)) { - sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group); + device_remove_bin_file(&pdev->dev, &bin_attr_data_vault); kfree(priv->data_vault); } free_uuid: @@ -683,7 +673,7 @@ static void int3400_thermal_remove(struct platform_device *pdev) acpi_thermal_rel_misc_device_remove(priv->adev->handle); if (!ZERO_OR_NULL_PTR(priv->data_vault)) - sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group); + device_remove_bin_file(&pdev->dev, &bin_attr_data_vault); sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group); sysfs_remove_group(&pdev->dev.kobj, &imok_attribute_group); thermal_zone_device_unregister(priv->thermal); -- cgit v1.2.3 From ac1f43c03fc91eee53cc95683245350d4d87781e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 25 Nov 2024 12:24:46 +0100 Subject: thermal: gov_power_allocator: Add missing NULL pointer check Commit 0dc23567c206 ("thermal: core: Move lists of thermal instances to trip descriptors") overlooked the case in which the Power Allocator governor attempts to bind to a tripless thermal zone and params->trip_max is NULL in check_power_actors(). No power actors can be found in that case, so check_power_actors() needs to be made return 0 then to restore its previous behavior. Fixes: 0dc23567c206 ("thermal: core: Move lists of thermal instances to trip descriptors") Closes: https://lore.kernel.org/linux-pm/Z0NeGF4ryCe_b5rr@sashalap/ Reported-by: Sasha Levin Signed-off-by: Rafael J. Wysocki Reviewed-by: Lukasz Luba Link: https://patch.msgid.link/2761105.mvXUDI8C0e@rjwysocki.net --- drivers/thermal/gov_power_allocator.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index ac6fa6b8f99f..3b644de3292e 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -588,10 +588,15 @@ static void allow_maximum_power(struct thermal_zone_device *tz) static int check_power_actors(struct thermal_zone_device *tz, struct power_allocator_params *params) { - const struct thermal_trip_desc *td = trip_to_trip_desc(params->trip_max); + const struct thermal_trip_desc *td; struct thermal_instance *instance; int ret = 0; + if (!params->trip_max) + return 0; + + td = trip_to_trip_desc(params->trip_max); + list_for_each_entry(instance, &td->thermal_instances, trip_node) { if (!cdev_is_power_actor(instance->cdev)) { dev_warn(&tz->device, "power_allocator: %s is not a power actor\n", -- cgit v1.2.3 From 69f3aa6ad92447d6e9f50c5b5aea85b56e80b198 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Oct 2024 20:06:17 +0200 Subject: thermal: of: Simplify thermal_of_should_bind with scoped for each OF child Use scoped for_each_child_of_node_scoped() when iterating over device nodes to make code a bit simpler. Reviewed-by: Jonathan Cameron Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20241010-b4-cleanup-h-of-node-put-thermal-v4-1-bfbe29ad81f4@linaro.org Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_of.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 07e09897165f..e406b9150a2b 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -297,7 +297,7 @@ static bool thermal_of_should_bind(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev, struct cooling_spec *c) { - struct device_node *tz_np, *cm_np, *child; + struct device_node *tz_np, *cm_np; bool result = false; tz_np = thermal_of_zone_get_by_name(tz); @@ -311,7 +311,7 @@ static bool thermal_of_should_bind(struct thermal_zone_device *tz, goto out; /* Look up the trip and the cdev in the cooling maps. */ - for_each_child_of_node(cm_np, child) { + for_each_child_of_node_scoped(cm_np, child) { struct device_node *tr_np; int count, i; @@ -330,7 +330,6 @@ static bool thermal_of_should_bind(struct thermal_zone_device *tz, break; } - of_node_put(child); break; } -- cgit v1.2.3 From a094ccfa5277cb9b92040016f3abf22408405820 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Oct 2024 20:06:18 +0200 Subject: thermal: of: Use scoped memory and OF handling to simplify thermal_of_trips_init() Obtain the device node reference and allocate memory with scoped/cleanup.h to reduce error handling and make the code a bit simpler. The code is not equivalent in one minor aspect: outgoing parameter "*ntrips" will not be zeroed on errors of memory allocation. This difference is not important, because code was already not zeroing it in case of earlier errors and the only caller does not rely on ntrips being 0 in case of errors. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chen-Yu Tsai Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/20241010-b4-cleanup-h-of-node-put-thermal-v4-2-bfbe29ad81f4@linaro.org [ rjw: Rebase ] Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_of.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index e406b9150a2b..9b0a3ec36a90 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -95,13 +95,11 @@ static int thermal_of_populate_trip(struct device_node *np, static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *ntrips) { - struct thermal_trip *tt; - struct device_node *trips; int ret, count; *ntrips = 0; - trips = of_get_child_by_name(np, "trips"); + struct device_node *trips __free(device_node) = of_get_child_by_name(np, "trips"); if (!trips) return NULL; @@ -109,31 +107,20 @@ static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *n if (!count) return NULL; - tt = kzalloc(sizeof(*tt) * count, GFP_KERNEL); - if (!tt) { - ret = -ENOMEM; - goto out_of_node_put; - } - - *ntrips = count; + struct thermal_trip *tt __free(kfree) = kzalloc(sizeof(*tt) * count, GFP_KERNEL); + if (!tt) + return ERR_PTR(-ENOMEM); count = 0; for_each_child_of_node_scoped(trips, trip) { ret = thermal_of_populate_trip(trip, &tt[count++]); if (ret) - goto out_kfree; + return ERR_PTR(ret); } - of_node_put(trips); - - return tt; - -out_kfree: - kfree(tt); -out_of_node_put: - of_node_put(trips); + *ntrips = count; - return ERR_PTR(ret); + return no_free_ptr(tt); } static struct device_node *of_thermal_zone_find(struct device_node *sensor, int id) -- cgit v1.2.3 From 8309135a39de73af2b4bbaa8385e40ffccbfc42c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Oct 2024 20:06:19 +0200 Subject: thermal: of: Use scoped device node handling to simplify of_thermal_zone_find() Obtain the device node reference with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Reviewed-by: Chen-Yu Tsai Reviewed-by: Jonathan Cameron Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20241010-b4-cleanup-h-of-node-put-thermal-v4-3-bfbe29ad81f4@linaro.org Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_of.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 9b0a3ec36a90..fab11b98ca49 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -125,10 +125,9 @@ static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *n static struct device_node *of_thermal_zone_find(struct device_node *sensor, int id) { - struct device_node *np, *tz; struct of_phandle_args sensor_specs; - np = of_find_node_by_name(NULL, "thermal-zones"); + struct device_node *np __free(device_node) = of_find_node_by_name(NULL, "thermal-zones"); if (!np) { pr_debug("No thermal zones description\n"); return ERR_PTR(-ENODEV); @@ -146,8 +145,7 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int "#thermal-sensor-cells"); if (count <= 0) { pr_err("%pOFn: missing thermal sensor\n", child); - tz = ERR_PTR(-EINVAL); - goto out; + return ERR_PTR(-EINVAL); } for (i = 0; i < count; i++) { @@ -159,22 +157,18 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int i, &sensor_specs); if (ret < 0) { pr_err("%pOFn: Failed to read thermal-sensors cells: %d\n", child, ret); - tz = ERR_PTR(ret); - goto out; + return ERR_PTR(ret); } if ((sensor == sensor_specs.np) && id == (sensor_specs.args_count ? sensor_specs.args[0] : 0)) { pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, child); - tz = no_free_ptr(child); - goto out; + return no_free_ptr(child); } } } - tz = ERR_PTR(-ENODEV); -out: - of_node_put(np); - return tz; + + return ERR_PTR(-ENODEV); } static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdelay) -- cgit v1.2.3 From 4dc00afc20ddb676aedc0ab776397c99e4025e30 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Oct 2024 20:06:20 +0200 Subject: thermal: qcom-spmi-adc-tm5: Simplify with scoped for each OF child loop Use scoped for_each_available_child_of_node_scoped() when iterating over device nodes to make code a bit simpler. Reviewed-by: Chen-Yu Tsai Reviewed-by: Jonathan Cameron Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20241010-b4-cleanup-h-of-node-put-thermal-v4-4-bfbe29ad81f4@linaro.org Signed-off-by: Rafael J. Wysocki --- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c index 5e94a45eba3e..d7f2e6ca92c2 100644 --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c @@ -938,7 +938,6 @@ static const struct adc_tm5_data adc_tm5_gen2_data_pmic = { static int adc_tm5_get_dt_data(struct adc_tm5_chip *adc_tm, struct device_node *node) { struct adc_tm5_channel *channels; - struct device_node *child; u32 value; int ret; struct device *dev = adc_tm->dev; @@ -982,12 +981,10 @@ static int adc_tm5_get_dt_data(struct adc_tm5_chip *adc_tm, struct device_node * adc_tm->avg_samples = VADC_DEF_AVG_SAMPLES; } - for_each_available_child_of_node(node, child) { + for_each_available_child_of_node_scoped(node, child) { ret = adc_tm5_get_dt_channel_data(adc_tm, channels, child); - if (ret) { - of_node_put(child); + if (ret) return ret; - } channels++; } -- cgit v1.2.3 From 2ff772f4a93f7b5abd9d1feaa9624a6006257b71 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Oct 2024 20:06:21 +0200 Subject: thermal: tegra: Simplify with scoped for each OF child loop Use scoped for_each_child_of_node_scoped() when iterating over device nodes to make code a bit simpler. Reviewed-by: Chen-Yu Tsai Reviewed-by: Jonathan Cameron Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20241010-b4-cleanup-h-of-node-put-thermal-v4-5-bfbe29ad81f4@linaro.org Signed-off-by: Rafael J. Wysocki --- drivers/thermal/tegra/soctherm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 6f1501e3fcc4..2c5ddf0db40c 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -1651,7 +1651,7 @@ static void soctherm_init_hw_throt_cdev(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct tegra_soctherm *ts = dev_get_drvdata(dev); - struct device_node *np_stc, *np_stcc; + struct device_node *np_stc; const char *name; int i; @@ -1668,7 +1668,7 @@ static void soctherm_init_hw_throt_cdev(struct platform_device *pdev) return; } - for_each_child_of_node(np_stc, np_stcc) { + for_each_child_of_node_scoped(np_stc, np_stcc) { struct soctherm_throt_cfg *stc; struct thermal_cooling_device *tcd; int err; @@ -1683,7 +1683,6 @@ static void soctherm_init_hw_throt_cdev(struct platform_device *pdev) if (stc->init) { dev_err(dev, "throttle-cfg: %s: redefined!\n", name); - of_node_put(np_stcc); break; } -- cgit v1.2.3 From c79886c540b57a86df8b0465cc1b71dc32144abf Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Oct 2024 20:06:22 +0200 Subject: thermal: sun8i: Use scoped device node handling to simplify error paths Obtain the device node reference with scoped/cleanup.h to reduce error handling and make the code a bit simpler. Reviewed-by: Chen-Yu Tsai Reviewed-by: Jonathan Cameron Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20241010-b4-cleanup-h-of-node-put-thermal-v4-6-bfbe29ad81f4@linaro.org Signed-off-by: Rafael J. Wysocki --- drivers/thermal/sun8i_thermal.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index 3203d8bd13a8..22674790629a 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -348,19 +349,18 @@ static void sun8i_ths_reset_control_assert(void *data) static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node) { - struct device_node *sram_node; struct platform_device *sram_pdev; struct regmap *regmap = NULL; - sram_node = of_parse_phandle(node, "allwinner,sram", 0); + struct device_node *sram_node __free(device_node) = + of_parse_phandle(node, "allwinner,sram", 0); if (!sram_node) return ERR_PTR(-ENODEV); sram_pdev = of_find_device_by_node(sram_node); if (!sram_pdev) { /* platform device might not be probed yet */ - regmap = ERR_PTR(-EPROBE_DEFER); - goto out_put_node; + return ERR_PTR(-EPROBE_DEFER); } /* If no regmap is found then the other device driver is at fault */ @@ -369,8 +369,7 @@ static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node) regmap = ERR_PTR(-EINVAL); platform_device_put(sram_pdev); -out_put_node: - of_node_put(sram_node); + return regmap; } -- cgit v1.2.3