xref: /openbmc/linux/drivers/acpi/fan_attr.c (revision 00ae053a0533155d830da27070a931e6fa747327)
1*00ae053aSSrinivas Pandruvada // SPDX-License-Identifier: GPL-2.0-or-later
2*00ae053aSSrinivas Pandruvada /*
3*00ae053aSSrinivas Pandruvada  *  fan_attr.c - Create extra attributes for ACPI Fan driver
4*00ae053aSSrinivas Pandruvada  *
5*00ae053aSSrinivas Pandruvada  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6*00ae053aSSrinivas Pandruvada  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7*00ae053aSSrinivas Pandruvada  *  Copyright (C) 2022 Intel Corporation. All rights reserved.
8*00ae053aSSrinivas Pandruvada  */
9*00ae053aSSrinivas Pandruvada 
10*00ae053aSSrinivas Pandruvada #include <linux/kernel.h>
11*00ae053aSSrinivas Pandruvada #include <linux/module.h>
12*00ae053aSSrinivas Pandruvada #include <linux/init.h>
13*00ae053aSSrinivas Pandruvada #include <linux/acpi.h>
14*00ae053aSSrinivas Pandruvada 
15*00ae053aSSrinivas Pandruvada #include "fan.h"
16*00ae053aSSrinivas Pandruvada 
17*00ae053aSSrinivas Pandruvada MODULE_LICENSE("GPL");
18*00ae053aSSrinivas Pandruvada 
19*00ae053aSSrinivas Pandruvada static ssize_t show_state(struct device *dev, struct device_attribute *attr, char *buf)
20*00ae053aSSrinivas Pandruvada {
21*00ae053aSSrinivas Pandruvada 	struct acpi_fan_fps *fps = container_of(attr, struct acpi_fan_fps, dev_attr);
22*00ae053aSSrinivas Pandruvada 	int count;
23*00ae053aSSrinivas Pandruvada 
24*00ae053aSSrinivas Pandruvada 	if (fps->control == 0xFFFFFFFF || fps->control > 100)
25*00ae053aSSrinivas Pandruvada 		count = scnprintf(buf, PAGE_SIZE, "not-defined:");
26*00ae053aSSrinivas Pandruvada 	else
27*00ae053aSSrinivas Pandruvada 		count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);
28*00ae053aSSrinivas Pandruvada 
29*00ae053aSSrinivas Pandruvada 	if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
30*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
31*00ae053aSSrinivas Pandruvada 	else
32*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point);
33*00ae053aSSrinivas Pandruvada 
34*00ae053aSSrinivas Pandruvada 	if (fps->speed == 0xFFFFFFFF)
35*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
36*00ae053aSSrinivas Pandruvada 	else
37*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed);
38*00ae053aSSrinivas Pandruvada 
39*00ae053aSSrinivas Pandruvada 	if (fps->noise_level == 0xFFFFFFFF)
40*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
41*00ae053aSSrinivas Pandruvada 	else
42*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100);
43*00ae053aSSrinivas Pandruvada 
44*00ae053aSSrinivas Pandruvada 	if (fps->power == 0xFFFFFFFF)
45*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n");
46*00ae053aSSrinivas Pandruvada 	else
47*00ae053aSSrinivas Pandruvada 		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power);
48*00ae053aSSrinivas Pandruvada 
49*00ae053aSSrinivas Pandruvada 	return count;
50*00ae053aSSrinivas Pandruvada }
51*00ae053aSSrinivas Pandruvada 
52*00ae053aSSrinivas Pandruvada int acpi_fan_create_attributes(struct acpi_device *device)
53*00ae053aSSrinivas Pandruvada {
54*00ae053aSSrinivas Pandruvada 	struct acpi_fan *fan = acpi_driver_data(device);
55*00ae053aSSrinivas Pandruvada 	int i, status = 0;
56*00ae053aSSrinivas Pandruvada 
57*00ae053aSSrinivas Pandruvada 	for (i = 0; i < fan->fps_count; ++i) {
58*00ae053aSSrinivas Pandruvada 		struct acpi_fan_fps *fps = &fan->fps[i];
59*00ae053aSSrinivas Pandruvada 
60*00ae053aSSrinivas Pandruvada 		snprintf(fps->name, ACPI_FPS_NAME_LEN, "state%d", i);
61*00ae053aSSrinivas Pandruvada 		sysfs_attr_init(&fps->dev_attr.attr);
62*00ae053aSSrinivas Pandruvada 		fps->dev_attr.show = show_state;
63*00ae053aSSrinivas Pandruvada 		fps->dev_attr.store = NULL;
64*00ae053aSSrinivas Pandruvada 		fps->dev_attr.attr.name = fps->name;
65*00ae053aSSrinivas Pandruvada 		fps->dev_attr.attr.mode = 0444;
66*00ae053aSSrinivas Pandruvada 		status = sysfs_create_file(&device->dev.kobj, &fps->dev_attr.attr);
67*00ae053aSSrinivas Pandruvada 		if (status) {
68*00ae053aSSrinivas Pandruvada 			int j;
69*00ae053aSSrinivas Pandruvada 
70*00ae053aSSrinivas Pandruvada 			for (j = 0; j < i; ++j)
71*00ae053aSSrinivas Pandruvada 				sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
72*00ae053aSSrinivas Pandruvada 			break;
73*00ae053aSSrinivas Pandruvada 		}
74*00ae053aSSrinivas Pandruvada 	}
75*00ae053aSSrinivas Pandruvada 
76*00ae053aSSrinivas Pandruvada 	return status;
77*00ae053aSSrinivas Pandruvada }
78*00ae053aSSrinivas Pandruvada 
79*00ae053aSSrinivas Pandruvada void acpi_fan_delete_attributes(struct acpi_device *device)
80*00ae053aSSrinivas Pandruvada {
81*00ae053aSSrinivas Pandruvada 	struct acpi_fan *fan = acpi_driver_data(device);
82*00ae053aSSrinivas Pandruvada 	int i;
83*00ae053aSSrinivas Pandruvada 
84*00ae053aSSrinivas Pandruvada 	for (i = 0; i < fan->fps_count; ++i)
85*00ae053aSSrinivas Pandruvada 		sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);
86*00ae053aSSrinivas Pandruvada }
87