Skip to content

Commit f119734

Browse files
spandruvadarafaeljw
authored andcommitted
ACPI: fan: Add additional attributes for fine grain control
Add additional attributes, which helps in implementing algorithm in the user space to optimize fan control. These attributes are presented in the same directory as the existing performance state attributes. Additional attributes: 1. Support of fine grain control Publish support of presence of fine grain control so that fan speed can be tuned correctly. This attribute is called "fine_grain_control". 2. fan speed Publish the actual fan rpm in sysfs. Knowing fan rpm is helpful to reduce noise level and use passive control instead. Also fan performance may not be same over time, so the same control value may not be enough to run the fan at a speed. So a feedback value of speed is helpful. This sysfs attribute is called "fan_speed_rpm". Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent bea2d98 commit f119734

3 files changed

Lines changed: 57 additions & 3 deletions

File tree

drivers/acpi/fan.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ struct acpi_fan {
4848
struct acpi_fan_fps *fps;
4949
int fps_count;
5050
struct thermal_cooling_device *cdev;
51+
struct device_attribute fst_speed;
52+
struct device_attribute fine_grain_control;
5153
};
5254

55+
int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst);
5356
int acpi_fan_create_attributes(struct acpi_device *device);
5457
void acpi_fan_delete_attributes(struct acpi_device *device);
5558
#endif

drivers/acpi/fan_attr.c

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,50 @@ static ssize_t show_state(struct device *dev, struct device_attribute *attr, cha
4949
return count;
5050
}
5151

52+
static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, char *buf)
53+
{
54+
struct acpi_device *acpi_dev = container_of(dev, struct acpi_device, dev);
55+
struct acpi_fan_fst fst;
56+
int status;
57+
58+
status = acpi_fan_get_fst(acpi_dev, &fst);
59+
if (status)
60+
return status;
61+
62+
return sprintf(buf, "%lld\n", fst.speed);
63+
}
64+
65+
static ssize_t show_fine_grain_control(struct device *dev, struct device_attribute *attr, char *buf)
66+
{
67+
struct acpi_device *acpi_dev = container_of(dev, struct acpi_device, dev);
68+
struct acpi_fan *fan = acpi_driver_data(acpi_dev);
69+
70+
return sprintf(buf, "%d\n", fan->fif.fine_grain_ctrl);
71+
}
72+
5273
int acpi_fan_create_attributes(struct acpi_device *device)
5374
{
5475
struct acpi_fan *fan = acpi_driver_data(device);
55-
int i, status = 0;
76+
int i, status;
77+
78+
sysfs_attr_init(&fan->fine_grain_control.attr);
79+
fan->fine_grain_control.show = show_fine_grain_control;
80+
fan->fine_grain_control.store = NULL;
81+
fan->fine_grain_control.attr.name = "fine_grain_control";
82+
fan->fine_grain_control.attr.mode = 0444;
83+
status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr);
84+
if (status)
85+
return status;
86+
87+
/* _FST is present if we are here */
88+
sysfs_attr_init(&fan->fst_speed.attr);
89+
fan->fst_speed.show = show_fan_speed;
90+
fan->fst_speed.store = NULL;
91+
fan->fst_speed.attr.name = "fan_speed_rpm";
92+
fan->fst_speed.attr.mode = 0444;
93+
status = sysfs_create_file(&device->dev.kobj, &fan->fst_speed.attr);
94+
if (status)
95+
goto rem_fine_grain_attr;
5696

5797
for (i = 0; i < fan->fps_count; ++i) {
5898
struct acpi_fan_fps *fps = &fan->fps[i];
@@ -69,10 +109,18 @@ int acpi_fan_create_attributes(struct acpi_device *device)
69109

70110
for (j = 0; j < i; ++j)
71111
sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
72-
break;
112+
goto rem_fst_attr;
73113
}
74114
}
75115

116+
return 0;
117+
118+
rem_fst_attr:
119+
sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
120+
121+
rem_fine_grain_attr:
122+
sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
123+
76124
return status;
77125
}
78126

@@ -83,4 +131,7 @@ void acpi_fan_delete_attributes(struct acpi_device *device)
83131

84132
for (i = 0; i < fan->fps_count; ++i)
85133
sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);
134+
135+
sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
136+
sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
86137
}

drivers/acpi/fan_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
7575
return 0;
7676
}
7777

78-
static int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst)
78+
int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst)
7979
{
8080
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
8181
union acpi_object *obj;

0 commit comments

Comments
 (0)