1// SPDX-License-Identifier: GPL-2.0 2 3#define _GNU_SOURCE 4 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8#include <unistd.h> 9#include <fcntl.h> 10#include <poll.h> 11#include <signal.h> 12 13#define POWER_FLOOR_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/power_limits/power_floor_enable" 14#define POWER_FLOOR_STATUS_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/power_limits/power_floor_status" 15 16void power_floor_exit(int signum) 17{ 18 int fd; 19 20 /* Disable feature via sysfs knob */ 21 22 fd = open(POWER_FLOOR_ENABLE_ATTRIBUTE, O_RDWR); 23 if (fd < 0) { 24 perror("Unable to open power floor enable file\n"); 25 exit(1); 26 } 27 28 if (write(fd, "0\n", 2) < 0) { 29 perror("Can' disable power floor notifications\n"); 30 exit(1); 31 } 32 33 printf("Disabled power floor notifications\n"); 34 35 close(fd); 36} 37 38int main(int argc, char **argv) 39{ 40 struct pollfd ufd; 41 char status_str[3]; 42 int fd, ret; 43 44 if (signal(SIGINT, power_floor_exit) == SIG_IGN) 45 signal(SIGINT, SIG_IGN); 46 if (signal(SIGHUP, power_floor_exit) == SIG_IGN) 47 signal(SIGHUP, SIG_IGN); 48 if (signal(SIGTERM, power_floor_exit) == SIG_IGN) 49 signal(SIGTERM, SIG_IGN); 50 51 /* Enable feature via sysfs knob */ 52 fd = open(POWER_FLOOR_ENABLE_ATTRIBUTE, O_RDWR); 53 if (fd < 0) { 54 perror("Unable to open power floor enable file\n"); 55 exit(1); 56 } 57 58 if (write(fd, "1\n", 2) < 0) { 59 perror("Can' enable power floor notifications\n"); 60 exit(1); 61 } 62 63 close(fd); 64 65 printf("Enabled power floor notifications\n"); 66 67 while (1) { 68 fd = open(POWER_FLOOR_STATUS_ATTRIBUTE, O_RDONLY); 69 if (fd < 0) { 70 perror("Unable to power floor status file\n"); 71 exit(1); 72 } 73 74 if ((lseek(fd, 0L, SEEK_SET)) < 0) { 75 fprintf(stderr, "Failed to set pointer to beginning\n"); 76 exit(1); 77 } 78 79 if (read(fd, status_str, sizeof(status_str)) < 0) { 80 fprintf(stderr, "Failed to read from:%s\n", 81 POWER_FLOOR_STATUS_ATTRIBUTE); 82 exit(1); 83 } 84 85 ufd.fd = fd; 86 ufd.events = POLLPRI; 87 88 ret = poll(&ufd, 1, -1); 89 if (ret < 0) { 90 perror("poll error"); 91 exit(1); 92 } else if (ret == 0) { 93 printf("Poll Timeout\n"); 94 } else { 95 if ((lseek(fd, 0L, SEEK_SET)) < 0) { 96 fprintf(stderr, "Failed to set pointer to beginning\n"); 97 exit(1); 98 } 99 100 if (read(fd, status_str, sizeof(status_str)) < 0) 101 exit(0); 102 103 printf("power floor status: %s\n", status_str); 104 } 105 106 close(fd); 107 } 108} 109