Additional thermal control updates for 6.13-rc1

- Add a NULL pointer check that was missed by recent modifications of
    the Power Allocator thermal governor (Rafael Wysocki).
 
  - Remove the data_vault attribute_group from int3400 because it is only
    used for exposing one binary file that can be exposed directly (Thomas
    Weißschuh).
 
  - Prevent the current_uuid sysfs attribute in int3400 from mistakenly
    treating valid UUID values as invalid on some older systems (Srinivas
    Pandruvada).
 
  - Use the cleanup.h mechanics to simplify DT data parsing in the thermal
    core and some drivers (Krzysztof Kozlowski).
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmdHY1ASHHJqd0Byand5
 c29ja2kubmV0AAoJEILEb/54YlRxg6gP/2Yrv1tBY2rjGgjd7zm4SYMsC/z72aXi
 hiNfvA4d735t1HZ33DifoZa4ukQhlxYvHmEhv3QTx/nNULTTKyBlw/B7zgDwieY6
 4zOYf944Yl7D3ckUbbQcHIbrwJnDpv7HKJEwlKMbBCeZuzoJc/6S256QlUrQn6VT
 LXWtUHsjntsH2g3wkz2Ju4wTd4QdekIhNnfIxGri6WHsnPHJEEVY7gojvkZQdoRt
 gmuZlAAg09VTjzRrBktyRgFBj3Uh+4GBlP5MU+Ao2h6L2c6W38u9CInT2bE0nYRD
 //zJnAVVPxv0VHcY3BSlZt1y/rNr9f6+ndunoTnmp1yWzVrVB0XRpKDPIbw2E2wq
 7WJr2J3ESDsr3VVGGHo08zeU33yoxMUd21Y4aABW09FA5zxGgOW17eCCmT1zbSQa
 JANpc8dFD2NSiwJMcMrKI5SOynlhGbuhnIin3vx78irJysZy9AvPbh2JJp73fqfD
 rWXmgYiXo2h+Hcmu87gyu8yDIfwuVwdBpZJek6P6h0Z3eQlOkD0B2OrRYI6X0Si9
 ukIarNvp5eAbjaSRB7d4u33puFhASQ2RF5YwX1Ll0Dx87f16nRmrYPunRCTEKp97
 UjhAPTUIoArVq3Y+I6qmieJDFzPw6YoOUnD0vQQjRC/UsbjWH1wYhUV+BtKWJnxM
 Fie/qwzNs+6B
 =9Wp9
 -----END PGP SIGNATURE-----

Merge tag 'thermal-6.13-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more thermal control updates from Rafael Wysocki:
 "These fix a Power Allocator thermal governor issue reported recently,
  update the Intel int3400 thermal driver and simplify DT data parsing
  in the thermal control subsystem:

   - Add a NULL pointer check that was missed by recent modifications of
     the Power Allocator thermal governor (Rafael Wysocki)

   - Remove the data_vault attribute_group from int3400 because it is
     only used for exposing one binary file that can be exposed directly
     (Thomas Weißschuh)

   - Prevent the current_uuid sysfs attribute in int3400 from mistakenly
     treating valid UUID values as invalid on some older systems
     (Srinivas Pandruvada)

   - Use the cleanup.h mechanics to simplify DT data parsing in the
     thermal core and some drivers (Krzysztof Kozlowski)"

* tag 'thermal-6.13-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  thermal: sun8i: Use scoped device node handling to simplify error paths
  thermal: tegra: Simplify with scoped for each OF child loop
  thermal: qcom-spmi-adc-tm5: Simplify with scoped for each OF child loop
  thermal: of: Use scoped device node handling to simplify of_thermal_zone_find()
  thermal: of: Use scoped memory and OF handling to simplify thermal_of_trips_init()
  thermal: of: Simplify thermal_of_should_bind with scoped for each OF child
  thermal: gov_power_allocator: Add missing NULL pointer check
  thermal: int3400: Remove unneeded data_vault attribute_group
  thermal: int3400: Fix reading of current_uuid for active policy
This commit is contained in:
Linus Torvalds 2024-11-27 14:36:00 -08:00
commit 92b459d82a
6 changed files with 34 additions and 64 deletions

View File

@ -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",

View File

@ -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)
@ -137,7 +128,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]);
@ -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);

View File

@ -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++;
}

View File

@ -9,6 +9,7 @@
*/
#include <linux/bitmap.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/interrupt.h>
@ -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;
}

View File

@ -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;
}

View File

@ -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,39 +107,27 @@ 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);
*ntrips = count;
return tt;
out_kfree:
kfree(tt);
out_of_node_put:
of_node_put(trips);
return ERR_PTR(ret);
return no_free_ptr(tt);
}
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);
@ -159,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++) {
@ -172,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)
@ -297,7 +278,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 +292,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 +311,6 @@ static bool thermal_of_should_bind(struct thermal_zone_device *tz,
break;
}
of_node_put(child);
break;
}