forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branches 'acpi-tools' and 'pm-tools'
* acpi-tools: ACPI / tools: Introduce ec_access.c - tool to access the EC * pm-tools: cpupower: Remove mc and smt power aware scheduler info/settings cpupower: cpupower info -b should return 0 on success, not the perf bias value cpupower: If root, try to load msr driver on x86 if /dev/cpu/0/msr is not available cpupower: Install recently added cpupower-idle-{set, info} manpages cpupower: Introduce idle state disable-by-latency and enable-all cpupower: Remove all manpages on make uninstall cpupower: Remove dead link to homepage, and update the targets built. cpupower: Rename cpufrequtils -> cpupower, and libcpufreq -> libcpupower. PM / tools: cpupower: add option to display values without round offs tools / power: turbostat: Drop temperature checks
- Loading branch information
Showing
16 changed files
with
456 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
ec_access: ec_access.o | ||
$(ECHO) " LD " $@ | ||
$(QUIET) $(LD) $(CFLAGS) $(LDFLAGS) $< -o $@ | ||
$(QUIET) $(STRIPCMD) $@ | ||
|
||
%.o: %.c | ||
$(ECHO) " CC " $@ | ||
$(QUIET) $(CC) -c $(CFLAGS) -o $@ $< | ||
|
||
all: ec_access | ||
|
||
install: | ||
$(INSTALL) -d $(DESTDIR)${sbindir} | ||
$(INSTALL_PROGRAM) ec_access $(DESTDIR)${sbindir} | ||
|
||
uninstall: | ||
- rm -f $(DESTDIR)${sbindir}/ec_access | ||
|
||
clean: | ||
-rm -f $(OUTPUT)ec_access | ||
|
||
.PHONY: all install uninstall |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
/* | ||
* ec_access.c | ||
* | ||
* Copyright (C) 2010 SUSE Linux Products GmbH | ||
* Author: | ||
* Thomas Renninger <[email protected]> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2. | ||
*/ | ||
|
||
#include <fcntl.h> | ||
#include <err.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <libgen.h> | ||
#include <unistd.h> | ||
#include <getopt.h> | ||
#include <stdint.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
|
||
|
||
#define EC_SPACE_SIZE 256 | ||
#define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io" | ||
|
||
/* TBD/Enhancements: | ||
- Provide param for accessing different ECs (not supported by kernel yet) | ||
*/ | ||
|
||
static int read_mode = -1; | ||
static int sleep_time; | ||
static int write_byte_offset = -1; | ||
static int read_byte_offset = -1; | ||
static uint8_t write_value = -1; | ||
|
||
void usage(char progname[], int exit_status) | ||
{ | ||
printf("Usage:\n"); | ||
printf("1) %s -r [-s sleep]\n", basename(progname)); | ||
printf("2) %s -b byte_offset\n", basename(progname)); | ||
printf("3) %s -w byte_offset -v value\n\n", basename(progname)); | ||
|
||
puts("\t-r [-s sleep] : Dump EC registers"); | ||
puts("\t If sleep is given, sleep x seconds,"); | ||
puts("\t re-read EC registers and show changes"); | ||
puts("\t-b offset : Read value at byte_offset (in hex)"); | ||
puts("\t-w offset -v value : Write value at byte_offset"); | ||
puts("\t-h : Print this help\n\n"); | ||
puts("Offsets and values are in hexadecimal number sytem."); | ||
puts("The offset and value must be between 0 and 0xff."); | ||
exit(exit_status); | ||
} | ||
|
||
void parse_opts(int argc, char *argv[]) | ||
{ | ||
int c; | ||
|
||
while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) { | ||
|
||
switch (c) { | ||
case 'r': | ||
if (read_mode != -1) | ||
usage(argv[0], EXIT_FAILURE); | ||
read_mode = 1; | ||
break; | ||
case 's': | ||
if (read_mode != -1 && read_mode != 1) | ||
usage(argv[0], EXIT_FAILURE); | ||
|
||
sleep_time = atoi(optarg); | ||
if (sleep_time <= 0) { | ||
sleep_time = 0; | ||
usage(argv[0], EXIT_FAILURE); | ||
printf("Bad sleep time: %s\n", optarg); | ||
} | ||
break; | ||
case 'b': | ||
if (read_mode != -1) | ||
usage(argv[0], EXIT_FAILURE); | ||
read_mode = 1; | ||
read_byte_offset = strtoul(optarg, NULL, 16); | ||
break; | ||
case 'w': | ||
if (read_mode != -1) | ||
usage(argv[0], EXIT_FAILURE); | ||
read_mode = 0; | ||
write_byte_offset = strtoul(optarg, NULL, 16); | ||
break; | ||
case 'v': | ||
write_value = strtoul(optarg, NULL, 16); | ||
break; | ||
case 'h': | ||
usage(argv[0], EXIT_SUCCESS); | ||
default: | ||
fprintf(stderr, "Unknown option!\n"); | ||
usage(argv[0], EXIT_FAILURE); | ||
} | ||
} | ||
if (read_mode == 0) { | ||
if (write_byte_offset < 0 || | ||
write_byte_offset >= EC_SPACE_SIZE) { | ||
fprintf(stderr, "Wrong byte offset 0x%.2x, valid: " | ||
"[0-0x%.2x]\n", | ||
write_byte_offset, EC_SPACE_SIZE - 1); | ||
usage(argv[0], EXIT_FAILURE); | ||
} | ||
if (write_value < 0 || | ||
write_value >= 255) { | ||
fprintf(stderr, "Wrong byte offset 0x%.2x, valid:" | ||
"[0-0xff]\n", write_byte_offset); | ||
usage(argv[0], EXIT_FAILURE); | ||
} | ||
} | ||
if (read_mode == 1 && read_byte_offset != -1) { | ||
if (read_byte_offset < -1 || | ||
read_byte_offset >= EC_SPACE_SIZE) { | ||
fprintf(stderr, "Wrong byte offset 0x%.2x, valid: " | ||
"[0-0x%.2x]\n", | ||
read_byte_offset, EC_SPACE_SIZE - 1); | ||
usage(argv[0], EXIT_FAILURE); | ||
} | ||
} | ||
/* Add additional parameter checks here */ | ||
} | ||
|
||
void dump_ec(int fd) | ||
{ | ||
char buf[EC_SPACE_SIZE]; | ||
char buf2[EC_SPACE_SIZE]; | ||
int byte_off, bytes_read; | ||
|
||
bytes_read = read(fd, buf, EC_SPACE_SIZE); | ||
|
||
if (bytes_read == -1) | ||
err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH); | ||
|
||
if (bytes_read != EC_SPACE_SIZE) | ||
fprintf(stderr, "Could only read %d bytes\n", bytes_read); | ||
|
||
printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); | ||
for (byte_off = 0; byte_off < bytes_read; byte_off++) { | ||
if ((byte_off % 16) == 0) | ||
printf("\n%.2X: ", byte_off); | ||
printf(" %.2x ", (uint8_t)buf[byte_off]); | ||
} | ||
printf("\n"); | ||
|
||
if (!sleep_time) | ||
return; | ||
|
||
printf("\n"); | ||
lseek(fd, 0, SEEK_SET); | ||
sleep(sleep_time); | ||
|
||
bytes_read = read(fd, buf2, EC_SPACE_SIZE); | ||
|
||
if (bytes_read == -1) | ||
err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH); | ||
|
||
if (bytes_read != EC_SPACE_SIZE) | ||
fprintf(stderr, "Could only read %d bytes\n", bytes_read); | ||
|
||
printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); | ||
for (byte_off = 0; byte_off < bytes_read; byte_off++) { | ||
if ((byte_off % 16) == 0) | ||
printf("\n%.2X: ", byte_off); | ||
|
||
if (buf[byte_off] == buf2[byte_off]) | ||
printf(" %.2x ", (uint8_t)buf2[byte_off]); | ||
else | ||
printf("*%.2x ", (uint8_t)buf2[byte_off]); | ||
} | ||
printf("\n"); | ||
} | ||
|
||
void read_ec_val(int fd, int byte_offset) | ||
{ | ||
uint8_t buf; | ||
int error; | ||
|
||
error = lseek(fd, byte_offset, SEEK_SET); | ||
if (error != byte_offset) | ||
err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset); | ||
|
||
error = read(fd, &buf, 1); | ||
if (error != 1) | ||
err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n", | ||
byte_offset, SYSFS_PATH); | ||
printf("0x%.2x\n", buf); | ||
return; | ||
} | ||
|
||
void write_ec_val(int fd, int byte_offset, uint8_t value) | ||
{ | ||
int error; | ||
|
||
error = lseek(fd, byte_offset, SEEK_SET); | ||
if (error != byte_offset) | ||
err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset); | ||
|
||
error = write(fd, &value, 1); | ||
if (error != 1) | ||
err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x", | ||
value, byte_offset); | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
int file_mode = O_RDONLY; | ||
int fd; | ||
|
||
parse_opts(argc, argv); | ||
|
||
if (read_mode == 0) | ||
file_mode = O_WRONLY; | ||
else if (read_mode == 1) | ||
file_mode = O_RDONLY; | ||
else | ||
usage(argv[0], EXIT_FAILURE); | ||
|
||
fd = open(SYSFS_PATH, file_mode); | ||
if (fd == -1) | ||
err(EXIT_FAILURE, "%s", SYSFS_PATH); | ||
|
||
if (read_mode) | ||
if (read_byte_offset == -1) | ||
dump_ec(fd); | ||
else if (read_byte_offset < 0 || | ||
read_byte_offset >= EC_SPACE_SIZE) | ||
usage(argv[0], EXIT_FAILURE); | ||
else | ||
read_ec_val(fd, read_byte_offset); | ||
else | ||
write_ec_val(fd, write_byte_offset, write_value); | ||
close(fd); | ||
|
||
exit(EXIT_SUCCESS); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.