]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
thermal/drivers/core: Use a char pointer for the cooling device name
authorDaniel Lezcano <daniel.lezcano@linaro.org>
Sun, 14 Mar 2021 11:13:29 +0000 (12:13 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Jun 2022 08:21:11 +0000 (10:21 +0200)
[ Upstream commit 58483761810087e5ffdf36e84ac1bf26df909097 ]

We want to have any kind of name for the cooling devices as we do no
longer want to rely on auto-numbering. Let's replace the cooling
device's fixed array by a char pointer to be allocated dynamically
when registering the cooling device, so we don't limit the length of
the name.

Rework the error path at the same time as we have to rollback the
allocations in case of error.

Tested with a dummy device having the name:
 "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch"

A village on the island of Anglesey (Wales), known to have the longest
name in Europe.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/20210314111333.16551-1-daniel.lezcano@linaro.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
drivers/thermal/thermal_core.c
include/linux/thermal.h

index 7ec1d0ee9beeb1b570bfbe7a672d06c760630915..ecd1856bef5e372d292647257c123acb731ab484 100644 (file)
@@ -133,7 +133,7 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
        /* Allow mlxsw thermal zone binding to an external cooling device */
        for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) {
                if (strnstr(cdev->type, mlxsw_thermal_external_allowed_cdev[i],
-                           sizeof(cdev->type)))
+                           strlen(cdev->type)))
                        return 0;
        }
 
index d9e34ac376626f9fb3e73ec7d8b5939cae575548..1abef64ccb5f1140a61715ab0af31076d17a86d1 100644 (file)
@@ -1092,10 +1092,7 @@ __thermal_cooling_device_register(struct device_node *np,
 {
        struct thermal_cooling_device *cdev;
        struct thermal_zone_device *pos = NULL;
-       int result;
-
-       if (type && strlen(type) >= THERMAL_NAME_LENGTH)
-               return ERR_PTR(-EINVAL);
+       int ret;
 
        if (!ops || !ops->get_max_state || !ops->get_cur_state ||
            !ops->set_cur_state)
@@ -1105,14 +1102,17 @@ __thermal_cooling_device_register(struct device_node *np,
        if (!cdev)
                return ERR_PTR(-ENOMEM);
 
-       result = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
-       if (result < 0) {
-               kfree(cdev);
-               return ERR_PTR(result);
+       ret = ida_simple_get(&thermal_cdev_ida, 0, 0, GFP_KERNEL);
+       if (ret < 0)
+               goto out_kfree_cdev;
+       cdev->id = ret;
+
+       cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
+       if (!cdev->type) {
+               ret = -ENOMEM;
+               goto out_ida_remove;
        }
 
-       cdev->id = result;
-       strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
        mutex_init(&cdev->lock);
        INIT_LIST_HEAD(&cdev->thermal_instances);
        cdev->np = np;
@@ -1122,12 +1122,9 @@ __thermal_cooling_device_register(struct device_node *np,
        cdev->devdata = devdata;
        thermal_cooling_device_setup_sysfs(cdev);
        dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
-       result = device_register(&cdev->device);
-       if (result) {
-               ida_simple_remove(&thermal_cdev_ida, cdev->id);
-               put_device(&cdev->device);
-               return ERR_PTR(result);
-       }
+       ret = device_register(&cdev->device);
+       if (ret)
+               goto out_kfree_type;
 
        /* Add 'this' new cdev to the global cdev list */
        mutex_lock(&thermal_list_lock);
@@ -1145,6 +1142,14 @@ __thermal_cooling_device_register(struct device_node *np,
        mutex_unlock(&thermal_list_lock);
 
        return cdev;
+
+out_kfree_type:
+       kfree(cdev->type);
+       put_device(&cdev->device);
+out_ida_remove:
+       ida_simple_remove(&thermal_cdev_ida, cdev->id);
+out_kfree_cdev:
+       return ERR_PTR(ret);
 }
 
 /**
@@ -1303,6 +1308,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
        ida_simple_remove(&thermal_cdev_ida, cdev->id);
        device_del(&cdev->device);
        thermal_cooling_device_destroy_sysfs(cdev);
+       kfree(cdev->type);
        put_device(&cdev->device);
 }
 EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);
index 176d9454e8f363429de3e746d1329f439071ea53..7097d4dcfdd078612afa64240c9fbf54f83e896e 100644 (file)
@@ -92,7 +92,7 @@ struct thermal_cooling_device_ops {
 
 struct thermal_cooling_device {
        int id;
-       char type[THERMAL_NAME_LENGTH];
+       char *type;
        struct device device;
        struct device_node *np;
        void *devdata;