cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fan_attr.c (4174B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  fan_attr.c - Create extra attributes for ACPI Fan driver
      4 *
      5 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
      6 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
      7 *  Copyright (C) 2022 Intel Corporation. All rights reserved.
      8 */
      9
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/init.h>
     13#include <linux/acpi.h>
     14
     15#include "fan.h"
     16
     17MODULE_LICENSE("GPL");
     18
     19static ssize_t show_state(struct device *dev, struct device_attribute *attr, char *buf)
     20{
     21	struct acpi_fan_fps *fps = container_of(attr, struct acpi_fan_fps, dev_attr);
     22	int count;
     23
     24	if (fps->control == 0xFFFFFFFF || fps->control > 100)
     25		count = scnprintf(buf, PAGE_SIZE, "not-defined:");
     26	else
     27		count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);
     28
     29	if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
     30		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
     31	else
     32		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point);
     33
     34	if (fps->speed == 0xFFFFFFFF)
     35		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
     36	else
     37		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed);
     38
     39	if (fps->noise_level == 0xFFFFFFFF)
     40		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
     41	else
     42		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100);
     43
     44	if (fps->power == 0xFFFFFFFF)
     45		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n");
     46	else
     47		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power);
     48
     49	return count;
     50}
     51
     52static 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
     65static 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
     73int acpi_fan_create_attributes(struct acpi_device *device)
     74{
     75	struct acpi_fan *fan = acpi_driver_data(device);
     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;
     96
     97	for (i = 0; i < fan->fps_count; ++i) {
     98		struct acpi_fan_fps *fps = &fan->fps[i];
     99
    100		snprintf(fps->name, ACPI_FPS_NAME_LEN, "state%d", i);
    101		sysfs_attr_init(&fps->dev_attr.attr);
    102		fps->dev_attr.show = show_state;
    103		fps->dev_attr.store = NULL;
    104		fps->dev_attr.attr.name = fps->name;
    105		fps->dev_attr.attr.mode = 0444;
    106		status = sysfs_create_file(&device->dev.kobj, &fps->dev_attr.attr);
    107		if (status) {
    108			int j;
    109
    110			for (j = 0; j < i; ++j)
    111				sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
    112			goto rem_fst_attr;
    113		}
    114	}
    115
    116	return 0;
    117
    118rem_fst_attr:
    119	sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
    120
    121rem_fine_grain_attr:
    122	sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
    123
    124	return status;
    125}
    126
    127void acpi_fan_delete_attributes(struct acpi_device *device)
    128{
    129	struct acpi_fan *fan = acpi_driver_data(device);
    130	int i;
    131
    132	for (i = 0; i < fan->fps_count; ++i)
    133		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);
    137}