Lines Matching +full:cooling +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0
3 * thermal.c - Generic Thermal Management Sysfs support.
12 #include <linux/device.h>
59 if (!strncasecmp(name, pos->name, THERMAL_NAME_LENGTH)) in __find_governor()
66 * bind_previous_governor() - bind the previous governor of the thermal zone
76 if (tz->governor && tz->governor->bind_to_tz) { in bind_previous_governor()
77 if (tz->governor->bind_to_tz(tz)) { in bind_previous_governor()
78 dev_err(&tz->device, in bind_previous_governor()
80 failed_gov_name, tz->governor->name, tz->type); in bind_previous_governor()
81 tz->governor = NULL; in bind_previous_governor()
87 * thermal_set_governor() - Switch to another governor
100 if (tz->governor && tz->governor->unbind_from_tz) in thermal_set_governor()
101 tz->governor->unbind_from_tz(tz); in thermal_set_governor()
103 if (new_gov && new_gov->bind_to_tz) { in thermal_set_governor()
104 ret = new_gov->bind_to_tz(tz); in thermal_set_governor()
106 bind_previous_governor(tz, new_gov->name); in thermal_set_governor()
112 tz->governor = new_gov; in thermal_set_governor()
124 return -EINVAL; in thermal_register_governor()
128 err = -EBUSY; in thermal_register_governor()
129 if (!__find_governor(governor->name)) { in thermal_register_governor()
133 list_add(&governor->governor_list, &thermal_governor_list); in thermal_register_governor()
134 match_default = !strncmp(governor->name, in thermal_register_governor()
146 * only thermal zones with specified tz->tzp->governor_name in thermal_register_governor()
147 * may run with tz->govenor unset in thermal_register_governor()
149 if (pos->governor) in thermal_register_governor()
152 name = pos->tzp->governor_name; in thermal_register_governor()
154 if (!strncasecmp(name, governor->name, THERMAL_NAME_LENGTH)) { in thermal_register_governor()
159 dev_err(&pos->device, in thermal_register_governor()
161 governor->name, pos->type, ret); in thermal_register_governor()
177 if (!__find_governor(governor->name)) in thermal_unregister_governor()
180 list_del(&governor->governor_list); in thermal_unregister_governor()
185 if (!strncasecmp(pos->governor->name, governor->name, in thermal_unregister_governor()
195 int ret = -EINVAL; in thermal_zone_device_set_policy()
217 count += sysfs_emit_at(buf, count, "%s ", pos->name); in thermal_build_list_of_policies()
241 (*governor)->name); in thermal_register_governors()
246 (*governor)->name); in thermal_register_governors()
265 if (tz->ops.change_mode) { in __thermal_zone_device_set_mode()
268 ret = tz->ops.change_mode(tz, mode); in __thermal_zone_device_set_mode()
273 tz->mode = mode; in __thermal_zone_device_set_mode()
282 dev_err(&tz->device, "Unable to get temperature, disabling!\n"); in thermal_zone_broken_disable()
291 if (td->trip.type == THERMAL_TRIP_CRITICAL && in thermal_zone_broken_disable()
292 td->trip.temperature > THERMAL_TEMP_INVALID) { in thermal_zone_broken_disable()
293 dev_crit(&tz->device, in thermal_zone_broken_disable()
306 * - Non-critical trips will invoke the governor responsible for that zone;
307 * - Hot trips will produce a notification to userspace;
308 * - Critical trip point will cause a system shutdown.
316 mod_delayed_work(system_freezable_power_efficient_wq, &tz->poll_queue, delay); in thermal_zone_device_set_polling()
321 if (error == -EAGAIN) { in thermal_zone_recheck()
331 if (tz->recheck_delay_jiffies == THERMAL_RECHECK_DELAY) in thermal_zone_recheck()
332 dev_info(&tz->device, "Temperature check failed (%d)\n", error); in thermal_zone_recheck()
334 thermal_zone_device_set_polling(tz, tz->recheck_delay_jiffies); in thermal_zone_recheck()
336 tz->recheck_delay_jiffies += max(tz->recheck_delay_jiffies >> 1, 1ULL); in thermal_zone_recheck()
337 if (tz->recheck_delay_jiffies > THERMAL_MAX_RECHECK_DELAY) { in thermal_zone_recheck()
343 tz->recheck_delay_jiffies = THERMAL_RECHECK_DELAY; in thermal_zone_recheck()
349 if (tz->passive > 0 && tz->passive_delay_jiffies) in monitor_thermal_zone()
350 thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies); in monitor_thermal_zone()
351 else if (tz->polling_delay_jiffies) in monitor_thermal_zone()
352 thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies); in monitor_thermal_zone()
357 if (tz->governor) in thermal_get_tz_governor()
358 return tz->governor; in thermal_get_tz_governor()
366 if (!tz->governor || !tz->governor->update_tz) in thermal_governor_update_tz()
369 tz->governor->update_tz(tz, reason); in thermal_governor_update_tz()
382 dev_emerg(&tz->device, "%s: critical temperature reached\n", tz->type); in thermal_zone_device_halt()
406 trace_thermal_zone_trip(tz, thermal_zone_trip_id(tz, trip), trip->type); in handle_critical_trips()
408 if (trip->type == THERMAL_TRIP_CRITICAL) in handle_critical_trips()
409 tz->ops.critical(tz); in handle_critical_trips()
410 else if (tz->ops.hot) in handle_critical_trips()
411 tz->ops.hot(tz); in handle_critical_trips()
423 list_del(&td->list_node); in move_trip_to_sorted_list()
427 if (entry->threshold <= td->threshold) { in move_trip_to_sorted_list()
428 list_add(&td->list_node, &entry->list_node); in move_trip_to_sorted_list()
432 list_add(&td->list_node, list); in move_trip_to_sorted_list()
438 td->threshold = td->trip.temperature; in move_to_trips_high()
439 move_trip_to_sorted_list(td, &tz->trips_high); in move_to_trips_high()
445 td->threshold = td->trip.temperature - td->trip.hysteresis; in move_to_trips_reached()
446 move_trip_to_sorted_list(td, &tz->trips_reached); in move_to_trips_reached()
452 td->threshold = INT_MAX; in move_to_trips_invalid()
453 list_move(&td->list_node, &tz->trips_invalid); in move_to_trips_invalid()
461 if (trip->type == THERMAL_TRIP_HOT || trip->type == THERMAL_TRIP_CRITICAL) in thermal_governor_trip_crossed()
464 if (governor->trip_crossed) in thermal_governor_trip_crossed()
465 governor->trip_crossed(tz, trip, upward); in thermal_governor_trip_crossed()
473 const struct thermal_trip *trip = &td->trip; in thermal_trip_crossed()
476 if (trip->type == THERMAL_TRIP_PASSIVE) in thermal_trip_crossed()
477 tz->passive++; in thermal_trip_crossed()
478 else if (trip->type == THERMAL_TRIP_CRITICAL || in thermal_trip_crossed()
479 trip->type == THERMAL_TRIP_HOT) in thermal_trip_crossed()
485 if (trip->type == THERMAL_TRIP_PASSIVE) { in thermal_trip_crossed()
486 tz->passive--; in thermal_trip_crossed()
487 WARN_ON(tz->passive < 0); in thermal_trip_crossed()
500 WRITE_ONCE(trip->hysteresis, hyst); in thermal_zone_set_trip_hyst()
508 if (tz->temperature >= td->threshold) in thermal_zone_set_trip_hyst()
516 int old_temp = trip->temperature; in thermal_zone_set_trip_temp()
521 WRITE_ONCE(trip->temperature, temp); in thermal_zone_set_trip_temp()
542 if (tz->temperature >= td->threshold) in thermal_zone_set_trip_temp()
554 if (tz->temperature >= td->threshold) in thermal_zone_set_trip_temp()
569 list_for_each_entry_safe_reverse(td, next, &tz->trips_reached, list_node) { in thermal_zone_handle_trips()
570 if (td->threshold <= tz->temperature) in thermal_zone_handle_trips()
578 list_move(&td->list_node, &way_down_list); in thermal_zone_handle_trips()
581 list_for_each_entry_safe(td, next, &tz->trips_high, list_node) { in thermal_zone_handle_trips()
582 if (td->threshold > tz->temperature) in thermal_zone_handle_trips()
592 if (!list_empty(&tz->trips_reached)) { in thermal_zone_handle_trips()
593 td = list_last_entry(&tz->trips_reached, in thermal_zone_handle_trips()
600 *low = td->threshold - 1; in thermal_zone_handle_trips()
602 if (!list_empty(&tz->trips_high)) { in thermal_zone_handle_trips()
603 td = list_first_entry(&tz->trips_high, in thermal_zone_handle_trips()
605 *high = td->threshold; in thermal_zone_handle_trips()
613 int low = -INT_MAX, high = INT_MAX; in __thermal_zone_device_update()
616 if (tz->state != TZ_STATE_READY || tz->mode != THERMAL_DEVICE_ENABLED) in __thermal_zone_device_update()
633 tz->recheck_delay_jiffies = THERMAL_RECHECK_DELAY; in __thermal_zone_device_update()
635 tz->last_temperature = tz->temperature; in __thermal_zone_device_update()
636 tz->temperature = temp; in __thermal_zone_device_update()
640 thermal_genl_sampling_temp(tz->id, temp); in __thermal_zone_device_update()
642 tz->notify_event = event; in __thermal_zone_device_update()
650 if (governor->manage) in __thermal_zone_device_update()
651 governor->manage(tz); in __thermal_zone_device_update()
667 if (mode == tz->mode) in thermal_zone_device_set_mode()
698 return !list_empty(&tz->node); in thermal_zone_is_present()
772 if (tz->id == id) { in thermal_zone_get_by_id()
773 get_device(&tz->device); in thermal_zone_get_by_id()
782 * Device management section: cooling devices, zones devices, and binding
785 * - cooling devices lifecycle: registration, unregistration,
787 * - thermal zone devices lifecycle: registration, unregistration,
797 list_for_each_entry(instance, &td->thermal_instances, trip_node) { in thermal_instance_add()
798 if (instance->cdev == cdev) in thermal_instance_add()
799 return -EEXIST; in thermal_instance_add()
802 list_add_tail(&new_instance->trip_node, &td->thermal_instances); in thermal_instance_add()
806 list_add_tail(&new_instance->cdev_node, &cdev->thermal_instances); in thermal_instance_add()
812 * thermal_bind_cdev_to_trip - bind a cooling device to a thermal zone
816 * @cool_spec: cooling specification for the trip point and @cdev
818 * This interface function bind a thermal cooling device to the certain trip
819 * point of a thermal zone device.
820 * This function is usually called in the thermal zone device .bind callback.
834 if (cool_spec->lower == THERMAL_NO_LIMIT) in thermal_bind_cdev_to_trip()
835 cool_spec->lower = 0; in thermal_bind_cdev_to_trip()
837 if (cool_spec->upper == THERMAL_NO_LIMIT) { in thermal_bind_cdev_to_trip()
838 cool_spec->upper = cdev->max_state; in thermal_bind_cdev_to_trip()
844 if (cool_spec->lower > cool_spec->upper || cool_spec->upper > cdev->max_state) in thermal_bind_cdev_to_trip()
845 return -EINVAL; in thermal_bind_cdev_to_trip()
849 return -ENOMEM; in thermal_bind_cdev_to_trip()
851 dev->cdev = cdev; in thermal_bind_cdev_to_trip()
852 dev->trip = &td->trip; in thermal_bind_cdev_to_trip()
853 dev->upper = cool_spec->upper; in thermal_bind_cdev_to_trip()
854 dev->upper_no_limit = upper_no_limit; in thermal_bind_cdev_to_trip()
855 dev->lower = cool_spec->lower; in thermal_bind_cdev_to_trip()
856 dev->target = THERMAL_NO_TARGET; in thermal_bind_cdev_to_trip()
857 dev->weight = cool_spec->weight; in thermal_bind_cdev_to_trip()
859 result = ida_alloc(&tz->ida, GFP_KERNEL); in thermal_bind_cdev_to_trip()
863 dev->id = result; in thermal_bind_cdev_to_trip()
864 sprintf(dev->name, "cdev%d", dev->id); in thermal_bind_cdev_to_trip()
866 sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name); in thermal_bind_cdev_to_trip()
870 snprintf(dev->attr_name, sizeof(dev->attr_name), "cdev%d_trip_point", in thermal_bind_cdev_to_trip()
871 dev->id); in thermal_bind_cdev_to_trip()
872 sysfs_attr_init(&dev->attr.attr); in thermal_bind_cdev_to_trip()
873 dev->attr.attr.name = dev->attr_name; in thermal_bind_cdev_to_trip()
874 dev->attr.attr.mode = 0444; in thermal_bind_cdev_to_trip()
875 dev->attr.show = trip_point_show; in thermal_bind_cdev_to_trip()
876 result = device_create_file(&tz->device, &dev->attr); in thermal_bind_cdev_to_trip()
880 snprintf(dev->weight_attr_name, sizeof(dev->weight_attr_name), in thermal_bind_cdev_to_trip()
881 "cdev%d_weight", dev->id); in thermal_bind_cdev_to_trip()
882 sysfs_attr_init(&dev->weight_attr.attr); in thermal_bind_cdev_to_trip()
883 dev->weight_attr.attr.name = dev->weight_attr_name; in thermal_bind_cdev_to_trip()
884 dev->weight_attr.attr.mode = S_IWUSR | S_IRUGO; in thermal_bind_cdev_to_trip()
885 dev->weight_attr.show = weight_show; in thermal_bind_cdev_to_trip()
886 dev->weight_attr.store = weight_store; in thermal_bind_cdev_to_trip()
887 result = device_create_file(&tz->device, &dev->weight_attr); in thermal_bind_cdev_to_trip()
900 device_remove_file(&tz->device, &dev->weight_attr); in thermal_bind_cdev_to_trip()
902 device_remove_file(&tz->device, &dev->attr); in thermal_bind_cdev_to_trip()
904 sysfs_remove_link(&tz->device.kobj, dev->name); in thermal_bind_cdev_to_trip()
906 ida_free(&tz->ida, dev->id); in thermal_bind_cdev_to_trip()
914 list_del(&instance->trip_node); in thermal_instance_delete()
916 guard(cooling_dev)(instance->cdev); in thermal_instance_delete()
918 list_del(&instance->cdev_node); in thermal_instance_delete()
922 * thermal_unbind_cdev_from_trip - unbind a cooling device from a thermal zone.
927 * This interface function unbind a thermal cooling device from the certain
928 * trip point of a thermal zone device.
929 * This function is usually called in the thermal zone device .unbind callback.
937 list_for_each_entry_safe(pos, next, &td->thermal_instances, trip_node) { in thermal_unbind_cdev_from_trip()
938 if (pos->cdev == cdev) { in thermal_unbind_cdev_from_trip()
949 device_remove_file(&tz->device, &pos->weight_attr); in thermal_unbind_cdev_from_trip()
950 device_remove_file(&tz->device, &pos->attr); in thermal_unbind_cdev_from_trip()
951 sysfs_remove_link(&tz->device.kobj, pos->name); in thermal_unbind_cdev_from_trip()
952 ida_free(&tz->ida, pos->id); in thermal_unbind_cdev_from_trip()
956 static void thermal_release(struct device *dev) in thermal_release()
962 sizeof("thermal_zone") - 1)) { in thermal_release()
965 mutex_destroy(&tz->lock); in thermal_release()
966 complete(&tz->removal); in thermal_release()
968 sizeof("cooling_device") - 1)) { in thermal_release()
971 kfree_const(cdev->type); in thermal_release()
972 ida_free(&thermal_cdev_ida, cdev->id); in thermal_release()
984 dev_err(&tz->device, "binding cdev %s to trip %d failed: %d\n", in print_bind_err_msg()
985 cdev->type, thermal_zone_trip_id(tz, &td->trip), ret); in print_bind_err_msg()
994 if (!tz->ops.should_bind) in __thermal_zone_cdev_bind()
1005 if (!tz->ops.should_bind(tz, &td->trip, cdev, &c)) in __thermal_zone_cdev_bind()
1035 list_add(&cdev->node, &thermal_cdev_list); in thermal_cooling_device_init_complete()
1042 * __thermal_cooling_device_register() - register a new thermal cooling device
1043 * @np: a pointer to a device tree node.
1044 * @type: the thermal cooling device type.
1045 * @devdata: device private data.
1046 * @ops: standard thermal cooling devices callbacks.
1048 * This interface function adds a new thermal cooling device (fan/processor/...)
1049 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
1051 * It also gives the opportunity to link the cooling device to a device tree
1052 * node, so that it can be bound to a thermal zone created out of device tree.
1066 if (!ops || !ops->get_max_state || !ops->get_cur_state || in __thermal_cooling_device_register()
1067 !ops->set_cur_state) in __thermal_cooling_device_register()
1068 return ERR_PTR(-EINVAL); in __thermal_cooling_device_register()
1071 return ERR_PTR(-ENODEV); in __thermal_cooling_device_register()
1075 return ERR_PTR(-ENOMEM); in __thermal_cooling_device_register()
1080 cdev->id = ret; in __thermal_cooling_device_register()
1083 cdev->type = kstrdup_const(type ? type : "", GFP_KERNEL); in __thermal_cooling_device_register()
1084 if (!cdev->type) { in __thermal_cooling_device_register()
1085 ret = -ENOMEM; in __thermal_cooling_device_register()
1089 mutex_init(&cdev->lock); in __thermal_cooling_device_register()
1090 INIT_LIST_HEAD(&cdev->thermal_instances); in __thermal_cooling_device_register()
1091 cdev->np = np; in __thermal_cooling_device_register()
1092 cdev->ops = ops; in __thermal_cooling_device_register()
1093 cdev->updated = false; in __thermal_cooling_device_register()
1094 cdev->device.class = thermal_class; in __thermal_cooling_device_register()
1095 cdev->devdata = devdata; in __thermal_cooling_device_register()
1097 ret = cdev->ops->get_max_state(cdev, &cdev->max_state); in __thermal_cooling_device_register()
1102 * The cooling device's current state is only needed for debug in __thermal_cooling_device_register()
1104 * the entire cooling device initialization to fail. However, in __thermal_cooling_device_register()
1105 * the debug will not work for the device if its initial state in __thermal_cooling_device_register()
1109 ret = cdev->ops->get_cur_state(cdev, ¤t_state); in __thermal_cooling_device_register()
1115 ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id); in __thermal_cooling_device_register()
1119 ret = device_register(&cdev->device); in __thermal_cooling_device_register()
1122 put_device(&cdev->device); in __thermal_cooling_device_register()
1126 if (current_state <= cdev->max_state) in __thermal_cooling_device_register()
1136 kfree_const(cdev->type); in __thermal_cooling_device_register()
1145 * thermal_cooling_device_register() - register a new thermal cooling device
1146 * @type: the thermal cooling device type.
1147 * @devdata: device private data.
1148 * @ops: standard thermal cooling devices callbacks.
1150 * This interface function adds a new thermal cooling device (fan/processor/...)
1151 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
1166 * thermal_of_cooling_device_register() - register an OF thermal cooling device
1167 * @np: a pointer to a device tree node.
1168 * @type: the thermal cooling device type.
1169 * @devdata: device private data.
1170 * @ops: standard thermal cooling devices callbacks.
1172 * This function will register a cooling device with device tree node reference.
1173 * This interface function adds a new thermal cooling device (fan/processor/...)
1174 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
1189 static void thermal_cooling_device_release(struct device *dev, void *res) in thermal_cooling_device_release()
1196 * devm_thermal_of_cooling_device_register() - register an OF thermal cooling
1197 * device
1198 * @dev: a valid struct device pointer of a sensor device.
1199 * @np: a pointer to a device tree node.
1200 * @type: the thermal cooling device type.
1201 * @devdata: device private data.
1202 * @ops: standard thermal cooling devices callbacks.
1204 * This function will register a cooling device with device tree node reference.
1205 * This interface function adds a new thermal cooling device (fan/processor/...)
1206 * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
1213 devm_thermal_of_cooling_device_register(struct device *dev, in devm_thermal_of_cooling_device_register()
1223 return ERR_PTR(-ENOMEM); in devm_thermal_of_cooling_device_register()
1251 * thermal_cooling_device_update - Update a cooling device object
1252 * @cdev: Target cooling device.
1256 * Must be called when the maximum cooling state of @cdev becomes invalid and so
1258 * cooling state value.
1269 * Hold thermal_list_lock throughout the update to prevent the device in thermal_cooling_device_update()
1283 if (cdev->ops->get_max_state(cdev, &cdev->max_state)) in thermal_cooling_device_update()
1288 list_for_each_entry(ti, &cdev->thermal_instances, cdev_node) { in thermal_cooling_device_update()
1289 if (ti->upper == cdev->max_state) in thermal_cooling_device_update()
1292 if (ti->upper < cdev->max_state) { in thermal_cooling_device_update()
1293 if (ti->upper_no_limit) in thermal_cooling_device_update()
1294 ti->upper = cdev->max_state; in thermal_cooling_device_update()
1299 ti->upper = cdev->max_state; in thermal_cooling_device_update()
1300 if (ti->lower > ti->upper) in thermal_cooling_device_update()
1301 ti->lower = ti->upper; in thermal_cooling_device_update()
1303 if (ti->target == THERMAL_NO_TARGET) in thermal_cooling_device_update()
1306 if (ti->target > ti->upper) in thermal_cooling_device_update()
1307 ti->target = ti->upper; in thermal_cooling_device_update()
1310 if (cdev->ops->get_cur_state(cdev, &state) || state > cdev->max_state) in thermal_cooling_device_update()
1343 list_del(&cdev->node); in thermal_cooling_device_exit()
1352 * thermal_cooling_device_unregister() - removes a thermal cooling device
1353 * @cdev: Thermal cooling device to remove.
1363 device_unregister(&cdev->device); in thermal_cooling_device_unregister()
1370 int ret = -EINVAL; in thermal_zone_get_crit_temp()
1372 if (tz->ops.get_crit_temp) in thermal_zone_get_crit_temp()
1373 return tz->ops.get_crit_temp(tz, temp); in thermal_zone_get_crit_temp()
1378 const struct thermal_trip *trip = &td->trip; in thermal_zone_get_crit_temp()
1380 if (trip->type == THERMAL_TRIP_CRITICAL) { in thermal_zone_get_crit_temp()
1381 *temp = trip->temperature; in thermal_zone_get_crit_temp()
1403 INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check); in thermal_zone_device_init()
1405 tz->temperature = THERMAL_TEMP_INIT; in thermal_zone_device_init()
1406 tz->passive = 0; in thermal_zone_device_init()
1407 tz->prev_low_trip = -INT_MAX; in thermal_zone_device_init()
1408 tz->prev_high_trip = INT_MAX; in thermal_zone_device_init()
1412 list_for_each_entry(instance, &td->thermal_instances, trip_node) in thermal_zone_device_init()
1413 instance->initialized = false; in thermal_zone_device_init()
1419 list_for_each_entry_safe(td, next, &tz->trips_invalid, list_node) { in thermal_zone_device_init()
1420 if (td->trip.temperature != THERMAL_TEMP_INVALID) in thermal_zone_device_init()
1424 list_for_each_entry_safe(td, next, &tz->trips_reached, list_node) { in thermal_zone_device_init()
1425 if (td->trip.temperature == THERMAL_TEMP_INVALID) in thermal_zone_device_init()
1438 if (tz->tzp) in thermal_zone_init_governor()
1439 governor = __find_governor(tz->tzp->governor_name); in thermal_zone_init_governor()
1452 list_add_tail(&tz->node, &thermal_tz_list); in thermal_zone_init_complete()
1456 /* Bind cooling devices for this zone. */ in thermal_zone_init_complete()
1460 tz->state &= ~TZ_STATE_FLAG_INIT; in thermal_zone_init_complete()
1467 tz->state |= TZ_STATE_FLAG_SUSPENDED; in thermal_zone_init_complete()
1473 * thermal_zone_device_register_with_trips() - register a new thermal zone device
1474 * @type: the thermal zone device type
1477 * @devdata: private device data
1478 * @ops: standard thermal zone device callbacks
1481 * performing passive cooling
1486 * This interface function adds a new thermal zone device (sensor) to
1487 * /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
1488 * thermal cooling devices registered at the same time.
1489 * thermal_zone_device_unregister() must be called when the device is no
1490 * longer needed. The passive cooling depends on the .get_trend() return value.
1513 return ERR_PTR(-EINVAL); in thermal_zone_device_register_with_trips()
1519 return ERR_PTR(-EINVAL); in thermal_zone_device_register_with_trips()
1524 return ERR_PTR(-EINVAL); in thermal_zone_device_register_with_trips()
1527 if (!ops || !ops->get_temp) { in thermal_zone_device_register_with_trips()
1528 pr_err("Thermal zone device ops not defined or invalid\n"); in thermal_zone_device_register_with_trips()
1529 return ERR_PTR(-EINVAL); in thermal_zone_device_register_with_trips()
1533 return ERR_PTR(-EINVAL); in thermal_zone_device_register_with_trips()
1536 return ERR_PTR(-EINVAL); in thermal_zone_device_register_with_trips()
1539 return ERR_PTR(-ENODEV); in thermal_zone_device_register_with_trips()
1543 return ERR_PTR(-ENOMEM); in thermal_zone_device_register_with_trips()
1546 tz->tzp = kmemdup(tzp, sizeof(*tzp), GFP_KERNEL); in thermal_zone_device_register_with_trips()
1547 if (!tz->tzp) { in thermal_zone_device_register_with_trips()
1548 result = -ENOMEM; in thermal_zone_device_register_with_trips()
1553 INIT_LIST_HEAD(&tz->node); in thermal_zone_device_register_with_trips()
1554 INIT_LIST_HEAD(&tz->trips_high); in thermal_zone_device_register_with_trips()
1555 INIT_LIST_HEAD(&tz->trips_reached); in thermal_zone_device_register_with_trips()
1556 INIT_LIST_HEAD(&tz->trips_invalid); in thermal_zone_device_register_with_trips()
1557 ida_init(&tz->ida); in thermal_zone_device_register_with_trips()
1558 mutex_init(&tz->lock); in thermal_zone_device_register_with_trips()
1559 init_completion(&tz->removal); in thermal_zone_device_register_with_trips()
1560 init_completion(&tz->resume); in thermal_zone_device_register_with_trips()
1567 tz->id = id; in thermal_zone_device_register_with_trips()
1568 strscpy(tz->type, type, sizeof(tz->type)); in thermal_zone_device_register_with_trips()
1570 tz->ops = *ops; in thermal_zone_device_register_with_trips()
1571 if (!tz->ops.critical) in thermal_zone_device_register_with_trips()
1572 tz->ops.critical = thermal_zone_device_critical; in thermal_zone_device_register_with_trips()
1574 tz->device.class = thermal_class; in thermal_zone_device_register_with_trips()
1575 tz->devdata = devdata; in thermal_zone_device_register_with_trips()
1576 tz->num_trips = num_trips; in thermal_zone_device_register_with_trips()
1578 td->trip = *trip++; in thermal_zone_device_register_with_trips()
1579 INIT_LIST_HEAD(&td->thermal_instances); in thermal_zone_device_register_with_trips()
1580 INIT_LIST_HEAD(&td->list_node); in thermal_zone_device_register_with_trips()
1589 tz->polling_delay_jiffies = msecs_to_jiffies(polling_delay); in thermal_zone_device_register_with_trips()
1590 tz->passive_delay_jiffies = msecs_to_jiffies(passive_delay); in thermal_zone_device_register_with_trips()
1591 tz->recheck_delay_jiffies = THERMAL_RECHECK_DELAY; in thermal_zone_device_register_with_trips()
1593 tz->state = TZ_STATE_FLAG_INIT; in thermal_zone_device_register_with_trips()
1595 result = dev_set_name(&tz->device, "thermal_zone%d", tz->id); in thermal_zone_device_register_with_trips()
1611 result = device_register(&tz->device); in thermal_zone_device_register_with_trips()
1615 if (!tz->tzp || !tz->tzp->no_hwmon) { in thermal_zone_device_register_with_trips()
1636 device_del(&tz->device); in thermal_zone_device_register_with_trips()
1638 put_device(&tz->device); in thermal_zone_device_register_with_trips()
1642 kfree(tz->tzp); in thermal_zone_device_register_with_trips()
1662 return tzd->devdata; in thermal_zone_device_priv()
1668 return tzd->type; in thermal_zone_device_type()
1674 return tzd->id; in thermal_zone_device_id()
1678 struct device *thermal_zone_device(struct thermal_zone_device *tzd) in thermal_zone_device()
1680 return &tzd->device; in thermal_zone_device()
1690 if (list_empty(&tz->node)) in thermal_zone_exit()
1695 tz->state |= TZ_STATE_FLAG_EXIT; in thermal_zone_exit()
1696 list_del_init(&tz->node); in thermal_zone_exit()
1706 * thermal_zone_device_unregister - removes the registered thermal zone device
1707 * @tz: the thermal zone device to remove
1719 cancel_delayed_work_sync(&tz->poll_queue); in thermal_zone_device_unregister()
1725 ida_free(&thermal_tz_ida, tz->id); in thermal_zone_device_unregister()
1726 ida_destroy(&tz->ida); in thermal_zone_device_unregister()
1728 device_del(&tz->device); in thermal_zone_device_unregister()
1729 put_device(&tz->device); in thermal_zone_device_unregister()
1733 wait_for_completion(&tz->removal); in thermal_zone_device_unregister()
1734 kfree(tz->tzp); in thermal_zone_device_unregister()
1740 * thermal_zone_get_zone_by_name() - search for a zone and returns its ref
1746 * matching name equals to @name, an ERR_PTR otherwise (-EINVAL for invalid
1747 * paramenters, -ENODEV for not found and -EEXIST for multiple matches).
1751 struct thermal_zone_device *pos = NULL, *ref = ERR_PTR(-EINVAL); in thermal_zone_get_zone_by_name()
1755 return ERR_PTR(-EINVAL); in thermal_zone_get_zone_by_name()
1760 if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) { in thermal_zone_get_zone_by_name()
1766 return ERR_PTR(-ENODEV); in thermal_zone_get_zone_by_name()
1770 return ERR_PTR(-EEXIST); in thermal_zone_get_zone_by_name()
1784 tz->state &= ~(TZ_STATE_FLAG_SUSPENDED | TZ_STATE_FLAG_RESUMING); in thermal_zone_device_resume()
1791 complete(&tz->resume); in thermal_zone_device_resume()
1798 if (tz->state & TZ_STATE_FLAG_RESUMING) { in thermal_zone_pm_prepare()
1805 wait_for_completion(&tz->resume); in thermal_zone_pm_prepare()
1809 tz->state |= TZ_STATE_FLAG_SUSPENDED; in thermal_zone_pm_prepare()
1828 cancel_delayed_work(&tz->poll_queue); in thermal_zone_pm_complete()
1830 reinit_completion(&tz->resume); in thermal_zone_pm_complete()
1831 tz->state |= TZ_STATE_FLAG_RESUMING; in thermal_zone_pm_complete()
1837 INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_resume); in thermal_zone_pm_complete()
1839 mod_delayed_work(system_freezable_power_efficient_wq, &tz->poll_queue, 0); in thermal_zone_pm_complete()
1900 result = -ENOMEM; in thermal_init()
1904 thermal_class->name = "thermal"; in thermal_init()
1905 thermal_class->dev_release = thermal_release; in thermal_init()