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