mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
thermal: export weight to sysfs
It's useful to have access to the weights for the cooling devices for thermal zones and change them if needed. Export them to sysfs. Cc: Zhang Rui <rui.zhang@intel.com> Cc: Eduardo Valentin <edubezval@gmail.com> Signed-off-by: Javi Merino <javi.merino@arm.com> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
This commit is contained in:
parent
80b89172f9
commit
db91651311
@ -194,6 +194,8 @@ thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device.
|
||||
/sys/class/thermal/thermal_zone[0-*]:
|
||||
|---cdev[0-*]: [0-*]th cooling device in current thermal zone
|
||||
|---cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with
|
||||
|---cdev[0-*]_weight: Influence of the cooling device in
|
||||
this thermal zone
|
||||
|
||||
Besides the thermal zone device sysfs I/F and cooling device sysfs I/F,
|
||||
the generic thermal driver also creates a hwmon sysfs I/F for each _type_
|
||||
@ -267,6 +269,14 @@ cdev[0-*]_trip_point
|
||||
point.
|
||||
RO, Optional
|
||||
|
||||
cdev[0-*]_weight
|
||||
The influence of cdev[0-*] in this thermal zone. This value
|
||||
is relative to the rest of cooling devices in the thermal
|
||||
zone. For example, if a cooling device has a weight double
|
||||
than that of other, it's twice as effective in cooling the
|
||||
thermal zone.
|
||||
RW, Optional
|
||||
|
||||
passive
|
||||
Attribute is only present for zones in which the passive cooling
|
||||
policy is not supported by native thermal driver. Default is zero
|
||||
@ -320,7 +330,8 @@ passive, active. If an ACPI thermal zone supports critical, passive,
|
||||
active[0] and active[1] at the same time, it may register itself as a
|
||||
thermal_zone_device (thermal_zone1) with 4 trip points in all.
|
||||
It has one processor and one fan, which are both registered as
|
||||
thermal_cooling_device.
|
||||
thermal_cooling_device. Both are considered to have the same
|
||||
effectiveness in cooling the thermal zone.
|
||||
|
||||
If the processor is listed in _PSL method, and the fan is listed in _AL0
|
||||
method, the sys I/F structure will be built like this:
|
||||
@ -342,8 +353,10 @@ method, the sys I/F structure will be built like this:
|
||||
|---trip_point_3_type: active1
|
||||
|---cdev0: --->/sys/class/thermal/cooling_device0
|
||||
|---cdev0_trip_point: 1 /* cdev0 can be used for passive */
|
||||
|---cdev0_weight: 1024
|
||||
|---cdev1: --->/sys/class/thermal/cooling_device3
|
||||
|---cdev1_trip_point: 2 /* cdev1 can be used for active[0]*/
|
||||
|---cdev1_weight: 1024
|
||||
|
||||
|cooling_device0:
|
||||
|---type: Processor
|
||||
|
@ -922,6 +922,34 @@ static const struct attribute_group *cooling_device_attr_groups[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
thermal_cooling_device_weight_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct thermal_instance *instance;
|
||||
|
||||
instance = container_of(attr, struct thermal_instance, weight_attr);
|
||||
|
||||
return sprintf(buf, "%d\n", instance->weight);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
thermal_cooling_device_weight_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct thermal_instance *instance;
|
||||
int ret, weight;
|
||||
|
||||
ret = kstrtoint(buf, 0, &weight);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
instance = container_of(attr, struct thermal_instance, weight_attr);
|
||||
instance->weight = weight;
|
||||
|
||||
return count;
|
||||
}
|
||||
/* Device management */
|
||||
|
||||
/**
|
||||
@ -1016,6 +1044,16 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
||||
if (result)
|
||||
goto remove_symbol_link;
|
||||
|
||||
sprintf(dev->weight_attr_name, "cdev%d_weight", dev->id);
|
||||
sysfs_attr_init(&dev->weight_attr.attr);
|
||||
dev->weight_attr.attr.name = dev->weight_attr_name;
|
||||
dev->weight_attr.attr.mode = S_IWUSR | S_IRUGO;
|
||||
dev->weight_attr.show = thermal_cooling_device_weight_show;
|
||||
dev->weight_attr.store = thermal_cooling_device_weight_store;
|
||||
result = device_create_file(&tz->device, &dev->weight_attr);
|
||||
if (result)
|
||||
goto remove_trip_file;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
mutex_lock(&cdev->lock);
|
||||
list_for_each_entry(pos, &tz->thermal_instances, tz_node)
|
||||
@ -1033,6 +1071,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
device_remove_file(&tz->device, &dev->weight_attr);
|
||||
remove_trip_file:
|
||||
device_remove_file(&tz->device, &dev->attr);
|
||||
remove_symbol_link:
|
||||
sysfs_remove_link(&tz->device.kobj, dev->name);
|
||||
|
@ -46,6 +46,8 @@ struct thermal_instance {
|
||||
unsigned long target; /* expected cooling state */
|
||||
char attr_name[THERMAL_NAME_LENGTH];
|
||||
struct device_attribute attr;
|
||||
char weight_attr_name[THERMAL_NAME_LENGTH];
|
||||
struct device_attribute weight_attr;
|
||||
struct list_head tz_node; /* node in tz->thermal_instances */
|
||||
struct list_head cdev_node; /* node in cdev->thermal_instances */
|
||||
unsigned int weight; /* The weight of the cooling device */
|
||||
|
Loading…
Reference in New Issue
Block a user