Skip to content

Commit 9e0a9be

Browse files
committed
thermal: Fail object registration if thermal class is not registered
If thermal_class is not registered with the driver core, there is no way to expose the interfaces used by the thermal control framework, so prevent thermal zones and cooling devices from being registered in that case by returning an error from object registration functions. For this purpose, use a thermal_class pointer that will be NULL if the class is not registered. To avoid wasting memory in that case, allocate the thermal class object dynamically and if it fails to register, free it and clear the thermal_class pointer to NULL. Signed-off-by: Rafael J. Wysocki <[email protected]> Acked-by: Daniel Lezcano <[email protected]> Reviewed-by: Zhang Rui <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]>
1 parent 5b8de18 commit 9e0a9be

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

drivers/thermal/thermal_core.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -777,10 +777,7 @@ static void thermal_release(struct device *dev)
777777
}
778778
}
779779

780-
static struct class thermal_class = {
781-
.name = "thermal",
782-
.dev_release = thermal_release,
783-
};
780+
static struct class *thermal_class;
784781

785782
static inline
786783
void print_bind_err_msg(struct thermal_zone_device *tz,
@@ -883,6 +880,9 @@ __thermal_cooling_device_register(struct device_node *np,
883880
!ops->set_cur_state)
884881
return ERR_PTR(-EINVAL);
885882

883+
if (!thermal_class)
884+
return ERR_PTR(-ENODEV);
885+
886886
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
887887
if (!cdev)
888888
return ERR_PTR(-ENOMEM);
@@ -904,7 +904,7 @@ __thermal_cooling_device_register(struct device_node *np,
904904
cdev->np = np;
905905
cdev->ops = ops;
906906
cdev->updated = false;
907-
cdev->device.class = &thermal_class;
907+
cdev->device.class = thermal_class;
908908
cdev->devdata = devdata;
909909

910910
ret = cdev->ops->get_max_state(cdev, &cdev->max_state);
@@ -1256,6 +1256,9 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
12561256
if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp) && !trips)
12571257
return ERR_PTR(-EINVAL);
12581258

1259+
if (!thermal_class)
1260+
return ERR_PTR(-ENODEV);
1261+
12591262
tz = kzalloc(sizeof(*tz), GFP_KERNEL);
12601263
if (!tz)
12611264
return ERR_PTR(-ENOMEM);
@@ -1277,7 +1280,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
12771280

12781281
tz->ops = ops;
12791282
tz->tzp = tzp;
1280-
tz->device.class = &thermal_class;
1283+
tz->device.class = thermal_class;
12811284
tz->devdata = devdata;
12821285
tz->trips = trips;
12831286
tz->num_trips = num_trips;
@@ -1522,9 +1525,21 @@ static int __init thermal_init(void)
15221525
if (result)
15231526
goto unregister_netlink;
15241527

1525-
result = class_register(&thermal_class);
1526-
if (result)
1528+
thermal_class = kzalloc(sizeof(*thermal_class), GFP_KERNEL);
1529+
if (!thermal_class) {
1530+
result = -ENOMEM;
1531+
goto unregister_governors;
1532+
}
1533+
1534+
thermal_class->name = "thermal";
1535+
thermal_class->dev_release = thermal_release;
1536+
1537+
result = class_register(thermal_class);
1538+
if (result) {
1539+
kfree(thermal_class);
1540+
thermal_class = NULL;
15271541
goto unregister_governors;
1542+
}
15281543

15291544
result = register_pm_notifier(&thermal_pm_nb);
15301545
if (result)

0 commit comments

Comments
 (0)