Skip to content

Commit c3bd6d5

Browse files
committed
Merge branch 'thermal-core'
Merge thermal control core changes for 6.3-rc1: - Clean up thermal device unregistration code (Viresh Kumar). - Fix and clean up thermal control core initialization error code paths (Daniel Lezcano). - Relocate the trip points handling code into a separate file (Daniel Lezcano). - Make the thermal core fail registration of thermal zones and cooling devices if the thermal class has not been registered (Rafael Wysocki). - Make the core thermal control code use sysfs_emit_at() instead of scnprintf() where applicable (ye xingchen). * thermal-core: thermal: core: Use sysfs_emit_at() instead of scnprintf() thermal: Fail object registration if thermal class is not registered thermal/core: Move the thermal trip code to a dedicated file thermal/core: Remove unneeded ida_destroy() thermal/core: Fix unregistering netlink at thermal init time thermal: core: Use device_unregister() instead of device_del/put() thermal: core: Move cdev cleanup to thermal_release()
2 parents f364beb + 5bbafd4 commit c3bd6d5

File tree

7 files changed

+239
-186
lines changed

7 files changed

+239
-186
lines changed

drivers/thermal/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#
55

66
obj-$(CONFIG_THERMAL) += thermal_sys.o
7-
thermal_sys-y += thermal_core.o thermal_sysfs.o \
8-
thermal_helpers.o
7+
thermal_sys-y += thermal_core.o thermal_sysfs.o
8+
thermal_sys-y += thermal_trip.o thermal_helpers.o
99

1010
# netlink interface to manage the thermal framework
1111
thermal_sys-$(CONFIG_THERMAL_NETLINK) += thermal_netlink.o

drivers/thermal/thermal_core.c

Lines changed: 43 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,9 @@ int thermal_build_list_of_policies(char *buf)
229229
mutex_lock(&thermal_governor_lock);
230230

231231
list_for_each_entry(pos, &thermal_governor_list, governor_list) {
232-
count += scnprintf(buf + count, PAGE_SIZE - count, "%s ",
233-
pos->name);
232+
count += sysfs_emit_at(buf, count, "%s ", pos->name);
234233
}
235-
count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
234+
count += sysfs_emit_at(buf, count, "\n");
236235

237236
mutex_unlock(&thermal_governor_lock);
238237

@@ -770,14 +769,14 @@ static void thermal_release(struct device *dev)
770769
} else if (!strncmp(dev_name(dev), "cooling_device",
771770
sizeof("cooling_device") - 1)) {
772771
cdev = to_cooling_device(dev);
772+
thermal_cooling_device_destroy_sysfs(cdev);
773+
kfree(cdev->type);
774+
ida_free(&thermal_cdev_ida, cdev->id);
773775
kfree(cdev);
774776
}
775777
}
776778

777-
static struct class thermal_class = {
778-
.name = "thermal",
779-
.dev_release = thermal_release,
780-
};
779+
static struct class *thermal_class;
781780

782781
static inline
783782
void print_bind_err_msg(struct thermal_zone_device *tz,
@@ -880,6 +879,9 @@ __thermal_cooling_device_register(struct device_node *np,
880879
!ops->set_cur_state)
881880
return ERR_PTR(-EINVAL);
882881

882+
if (!thermal_class)
883+
return ERR_PTR(-ENODEV);
884+
883885
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
884886
if (!cdev)
885887
return ERR_PTR(-ENOMEM);
@@ -901,27 +903,25 @@ __thermal_cooling_device_register(struct device_node *np,
901903
cdev->np = np;
902904
cdev->ops = ops;
903905
cdev->updated = false;
904-
cdev->device.class = &thermal_class;
906+
cdev->device.class = thermal_class;
905907
cdev->devdata = devdata;
906908

907909
ret = cdev->ops->get_max_state(cdev, &cdev->max_state);
908-
if (ret) {
909-
kfree(cdev->type);
910-
goto out_ida_remove;
911-
}
910+
if (ret)
911+
goto out_cdev_type;
912912

913913
thermal_cooling_device_setup_sysfs(cdev);
914914

915915
ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
916-
if (ret) {
917-
kfree(cdev->type);
918-
thermal_cooling_device_destroy_sysfs(cdev);
919-
goto out_ida_remove;
920-
}
916+
if (ret)
917+
goto out_cooling_dev;
921918

922919
ret = device_register(&cdev->device);
923-
if (ret)
924-
goto out_kfree_type;
920+
if (ret) {
921+
/* thermal_release() handles rest of the cleanup */
922+
put_device(&cdev->device);
923+
return ERR_PTR(ret);
924+
}
925925

926926
/* Add 'this' new cdev to the global cdev list */
927927
mutex_lock(&thermal_list_lock);
@@ -940,13 +940,10 @@ __thermal_cooling_device_register(struct device_node *np,
940940

941941
return cdev;
942942

943-
out_kfree_type:
943+
out_cooling_dev:
944944
thermal_cooling_device_destroy_sysfs(cdev);
945+
out_cdev_type:
945946
kfree(cdev->type);
946-
put_device(&cdev->device);
947-
948-
/* thermal_release() takes care of the rest */
949-
cdev = NULL;
950947
out_ida_remove:
951948
ida_free(&thermal_cdev_ida, id);
952949
out_kfree_cdev:
@@ -1107,11 +1104,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
11071104

11081105
mutex_unlock(&thermal_list_lock);
11091106

1110-
ida_free(&thermal_cdev_ida, cdev->id);
1111-
device_del(&cdev->device);
1112-
thermal_cooling_device_destroy_sysfs(cdev);
1113-
kfree(cdev->type);
1114-
put_device(&cdev->device);
1107+
device_unregister(&cdev->device);
11151108
}
11161109
EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);
11171110

@@ -1162,12 +1155,6 @@ static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms
11621155
*delay_jiffies = round_jiffies(*delay_jiffies);
11631156
}
11641157

1165-
int thermal_zone_get_num_trips(struct thermal_zone_device *tz)
1166-
{
1167-
return tz->num_trips;
1168-
}
1169-
EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips);
1170-
11711158
int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp)
11721159
{
11731160
int i, ret = -EINVAL;
@@ -1194,87 +1181,6 @@ int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp)
11941181
}
11951182
EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp);
11961183

1197-
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
1198-
struct thermal_trip *trip)
1199-
{
1200-
int ret;
1201-
1202-
if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip)
1203-
return -EINVAL;
1204-
1205-
if (tz->trips) {
1206-
*trip = tz->trips[trip_id];
1207-
return 0;
1208-
}
1209-
1210-
if (tz->ops->get_trip_hyst) {
1211-
ret = tz->ops->get_trip_hyst(tz, trip_id, &trip->hysteresis);
1212-
if (ret)
1213-
return ret;
1214-
} else {
1215-
trip->hysteresis = 0;
1216-
}
1217-
1218-
ret = tz->ops->get_trip_temp(tz, trip_id, &trip->temperature);
1219-
if (ret)
1220-
return ret;
1221-
1222-
return tz->ops->get_trip_type(tz, trip_id, &trip->type);
1223-
}
1224-
EXPORT_SYMBOL_GPL(__thermal_zone_get_trip);
1225-
1226-
int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
1227-
struct thermal_trip *trip)
1228-
{
1229-
int ret;
1230-
1231-
mutex_lock(&tz->lock);
1232-
ret = __thermal_zone_get_trip(tz, trip_id, trip);
1233-
mutex_unlock(&tz->lock);
1234-
1235-
return ret;
1236-
}
1237-
EXPORT_SYMBOL_GPL(thermal_zone_get_trip);
1238-
1239-
int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id,
1240-
const struct thermal_trip *trip)
1241-
{
1242-
struct thermal_trip t;
1243-
int ret;
1244-
1245-
if (!tz->ops->set_trip_temp && !tz->ops->set_trip_hyst && !tz->trips)
1246-
return -EINVAL;
1247-
1248-
ret = __thermal_zone_get_trip(tz, trip_id, &t);
1249-
if (ret)
1250-
return ret;
1251-
1252-
if (t.type != trip->type)
1253-
return -EINVAL;
1254-
1255-
if (t.temperature != trip->temperature && tz->ops->set_trip_temp) {
1256-
ret = tz->ops->set_trip_temp(tz, trip_id, trip->temperature);
1257-
if (ret)
1258-
return ret;
1259-
}
1260-
1261-
if (t.hysteresis != trip->hysteresis && tz->ops->set_trip_hyst) {
1262-
ret = tz->ops->set_trip_hyst(tz, trip_id, trip->hysteresis);
1263-
if (ret)
1264-
return ret;
1265-
}
1266-
1267-
if (tz->trips && (t.temperature != trip->temperature || t.hysteresis != trip->hysteresis))
1268-
tz->trips[trip_id] = *trip;
1269-
1270-
thermal_notify_tz_trip_change(tz->id, trip_id, trip->type,
1271-
trip->temperature, trip->hysteresis);
1272-
1273-
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
1274-
1275-
return 0;
1276-
}
1277-
12781184
/**
12791185
* thermal_zone_device_register_with_trips() - register a new thermal zone device
12801186
* @type: the thermal zone device type
@@ -1349,6 +1255,9 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
13491255
if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp) && !trips)
13501256
return ERR_PTR(-EINVAL);
13511257

1258+
if (!thermal_class)
1259+
return ERR_PTR(-ENODEV);
1260+
13521261
tz = kzalloc(sizeof(*tz), GFP_KERNEL);
13531262
if (!tz)
13541263
return ERR_PTR(-ENOMEM);
@@ -1370,7 +1279,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
13701279

13711280
tz->ops = ops;
13721281
tz->tzp = tzp;
1373-
tz->device.class = &thermal_class;
1282+
tz->device.class = thermal_class;
13741283
tz->devdata = devdata;
13751284
tz->trips = trips;
13761285
tz->num_trips = num_trips;
@@ -1613,11 +1522,23 @@ static int __init thermal_init(void)
16131522

16141523
result = thermal_register_governors();
16151524
if (result)
1616-
goto error;
1525+
goto unregister_netlink;
16171526

1618-
result = class_register(&thermal_class);
1619-
if (result)
1527+
thermal_class = kzalloc(sizeof(*thermal_class), GFP_KERNEL);
1528+
if (!thermal_class) {
1529+
result = -ENOMEM;
16201530
goto unregister_governors;
1531+
}
1532+
1533+
thermal_class->name = "thermal";
1534+
thermal_class->dev_release = thermal_release;
1535+
1536+
result = class_register(thermal_class);
1537+
if (result) {
1538+
kfree(thermal_class);
1539+
thermal_class = NULL;
1540+
goto unregister_governors;
1541+
}
16211542

16221543
result = register_pm_notifier(&thermal_pm_nb);
16231544
if (result)
@@ -1628,9 +1549,9 @@ static int __init thermal_init(void)
16281549

16291550
unregister_governors:
16301551
thermal_unregister_governors();
1552+
unregister_netlink:
1553+
thermal_netlink_exit();
16311554
error:
1632-
ida_destroy(&thermal_tz_ida);
1633-
ida_destroy(&thermal_cdev_ida);
16341555
mutex_destroy(&thermal_list_lock);
16351556
mutex_destroy(&thermal_governor_lock);
16361557
return result;

drivers/thermal/thermal_core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ int for_each_thermal_cooling_device(int (*cb)(struct thermal_cooling_device *,
5252
int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
5353
void *thermal_governor);
5454

55+
int __for_each_thermal_trip(struct thermal_zone_device *,
56+
int (*cb)(struct thermal_trip *, void *),
57+
void *);
58+
5559
struct thermal_zone_device *thermal_zone_get_by_id(int id);
5660

5761
struct thermal_attr {

drivers/thermal/thermal_helpers.c

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -146,68 +146,6 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
146146
}
147147
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
148148

149-
/**
150-
* __thermal_zone_set_trips - Computes the next trip points for the driver
151-
* @tz: a pointer to a thermal zone device structure
152-
*
153-
* The function computes the next temperature boundaries by browsing
154-
* the trip points. The result is the closer low and high trip points
155-
* to the current temperature. These values are passed to the backend
156-
* driver to let it set its own notification mechanism (usually an
157-
* interrupt).
158-
*
159-
* This function must be called with tz->lock held. Both tz and tz->ops
160-
* must be valid pointers.
161-
*
162-
* It does not return a value
163-
*/
164-
void __thermal_zone_set_trips(struct thermal_zone_device *tz)
165-
{
166-
struct thermal_trip trip;
167-
int low = -INT_MAX, high = INT_MAX;
168-
int i, ret;
169-
170-
lockdep_assert_held(&tz->lock);
171-
172-
if (!tz->ops->set_trips)
173-
return;
174-
175-
for (i = 0; i < tz->num_trips; i++) {
176-
int trip_low;
177-
178-
ret = __thermal_zone_get_trip(tz, i , &trip);
179-
if (ret)
180-
return;
181-
182-
trip_low = trip.temperature - trip.hysteresis;
183-
184-
if (trip_low < tz->temperature && trip_low > low)
185-
low = trip_low;
186-
187-
if (trip.temperature > tz->temperature &&
188-
trip.temperature < high)
189-
high = trip.temperature;
190-
}
191-
192-
/* No need to change trip points */
193-
if (tz->prev_low_trip == low && tz->prev_high_trip == high)
194-
return;
195-
196-
tz->prev_low_trip = low;
197-
tz->prev_high_trip = high;
198-
199-
dev_dbg(&tz->device,
200-
"new temperature boundaries: %d < x < %d\n", low, high);
201-
202-
/*
203-
* Set a temperature window. When this window is left the driver
204-
* must inform the thermal core via thermal_zone_device_update.
205-
*/
206-
ret = tz->ops->set_trips(tz, low, high);
207-
if (ret)
208-
dev_err(&tz->device, "Failed to set trips: %d\n", ret);
209-
}
210-
211149
static void thermal_cdev_set_cur_state(struct thermal_cooling_device *cdev,
212150
int target)
213151
{

drivers/thermal/thermal_netlink.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,3 +699,8 @@ int __init thermal_netlink_init(void)
699699
{
700700
return genl_register_family(&thermal_gnl_family);
701701
}
702+
703+
void __init thermal_netlink_exit(void)
704+
{
705+
genl_unregister_family(&thermal_gnl_family);
706+
}

drivers/thermal/thermal_netlink.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct thermal_genl_cpu_caps {
1313
/* Netlink notification function */
1414
#ifdef CONFIG_THERMAL_NETLINK
1515
int __init thermal_netlink_init(void);
16+
void __init thermal_netlink_exit(void);
1617
int thermal_notify_tz_create(int tz_id, const char *name);
1718
int thermal_notify_tz_delete(int tz_id);
1819
int thermal_notify_tz_enable(int tz_id);
@@ -115,4 +116,6 @@ static inline int thermal_genl_cpu_capability_event(int count, struct thermal_ge
115116
return 0;
116117
}
117118

119+
static inline void __init thermal_netlink_exit(void) {}
120+
118121
#endif /* CONFIG_THERMAL_NETLINK */

0 commit comments

Comments
 (0)