Skip to content

Commit

Permalink
thermal: export weight to sysfs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Javi Merino authored and Eduardo Valentin committed May 5, 2015
1 parent 80b8917 commit db91651
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
15 changes: 14 additions & 1 deletion Documentation/thermal/sysfs-api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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_
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
40 changes: 40 additions & 0 deletions drivers/thermal/thermal_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

/**
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/thermal/thermal_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit db91651

Please sign in to comment.