Skip to content

Commit 3d439b1

Browse files
committed
thermal/core: Alloc-copy-free the thermal zone parameters structure
The caller of the function thermal_zone_device_register_with_trips() can pass a thermal_zone_params structure parameter. This one is used by the thermal core code until the thermal zone is destroyed. That forces the caller, so the driver, to keep the pointer valid until it unregisters the thermal zone if we want to make the thermal zone device structure private the core code. As the thermal zone device structure would be private, the driver can not access to thermal zone device structure to retrieve the tzp field after it passed it to register the thermal zone. So instead of forcing the users of the function to deal with the tzp structure life cycle, make the usage easier by allocating our own thermal zone params, copying the parameter content and by freeing at unregister time. The user can then create the parameters on the stack, pass it to the registering function and forget about it. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/20230404075138.2914680-3-daniel.lezcano@linaro.org
1 parent ac614a9 commit 3d439b1

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

drivers/thermal/thermal_core.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,13 +1256,21 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
12561256
if (!tz)
12571257
return ERR_PTR(-ENOMEM);
12581258

1259+
if (tzp) {
1260+
tz->tzp = kmemdup(tzp, sizeof(*tzp), GFP_KERNEL);
1261+
if (!tz->tzp) {
1262+
result = -ENOMEM;
1263+
goto free_tz;
1264+
}
1265+
}
1266+
12591267
INIT_LIST_HEAD(&tz->thermal_instances);
12601268
ida_init(&tz->ida);
12611269
mutex_init(&tz->lock);
12621270
id = ida_alloc(&thermal_tz_ida, GFP_KERNEL);
12631271
if (id < 0) {
12641272
result = id;
1265-
goto free_tz;
1273+
goto free_tzp;
12661274
}
12671275

12681276
tz->id = id;
@@ -1272,7 +1280,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
12721280
ops->critical = thermal_zone_device_critical;
12731281

12741282
tz->ops = ops;
1275-
tz->tzp = tzp;
12761283
tz->device.class = thermal_class;
12771284
tz->devdata = devdata;
12781285
tz->trips = trips;
@@ -1354,6 +1361,8 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
13541361
tz = NULL;
13551362
remove_id:
13561363
ida_free(&thermal_tz_ida, id);
1364+
free_tzp:
1365+
kfree(tz->tzp);
13571366
free_tz:
13581367
kfree(tz);
13591368
return ERR_PTR(result);
@@ -1434,6 +1443,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
14341443
device_del(&tz->device);
14351444
mutex_unlock(&tz->lock);
14361445

1446+
kfree(tz->tzp);
1447+
14371448
put_device(&tz->device);
14381449

14391450
thermal_notify_tz_delete(tz_id);

0 commit comments

Comments
 (0)