Browse Source

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
Rafael J. Wysocki 11 years ago
parent
commit
2e30baad22

+ 2 - 0
tools/power/acpi/Makefile

@@ -19,6 +19,8 @@ OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
 $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
 $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
 endif
 endif
 
 
+SUBDIRS = tools/ec
+
 # --- CONFIGURATION BEGIN ---
 # --- CONFIGURATION BEGIN ---
 
 
 # Set the following to `true' to make a unstripped, unoptimized
 # Set the following to `true' to make a unstripped, unoptimized

+ 22 - 0
tools/power/acpi/tools/ec/Makefile

@@ -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

+ 238 - 0
tools/power/acpi/tools/ec/ec_access.c

@@ -0,0 +1,238 @@
+/*
+ * ec_access.c
+ *
+ * Copyright (C) 2010 SUSE Linux Products GmbH
+ * Author:
+ *      Thomas Renninger <trenn@suse.de>
+ *
+ * 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);
+}

+ 8 - 2
tools/power/cpupower/Makefile

@@ -274,6 +274,8 @@ install-man:
 	$(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
 	$(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
 	$(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
 	$(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
 	$(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
 	$(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
+	$(INSTALL_DATA) -D man/cpupower-idle-set.1 $(DESTDIR)${mandir}/man1/cpupower-idle-set.1
+	$(INSTALL_DATA) -D man/cpupower-idle-info.1 $(DESTDIR)${mandir}/man1/cpupower-idle-info.1
 	$(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1
 	$(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1
 	$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
 	$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
 	$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
 	$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
@@ -295,8 +297,12 @@ uninstall:
 	- rm -f $(DESTDIR)${libdir}/libcpupower.*
 	- rm -f $(DESTDIR)${libdir}/libcpupower.*
 	- rm -f $(DESTDIR)${includedir}/cpufreq.h
 	- rm -f $(DESTDIR)${includedir}/cpufreq.h
 	- rm -f $(DESTDIR)${bindir}/utils/cpupower
 	- rm -f $(DESTDIR)${bindir}/utils/cpupower
-	- rm -f $(DESTDIR)${mandir}/man1/cpufreq-set.1
-	- rm -f $(DESTDIR)${mandir}/man1/cpufreq-info.1
+	- rm -f $(DESTDIR)${mandir}/man1/cpupower.1
+	- rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
+	- rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
+	- rm -f $(DESTDIR)${mandir}/man1/cpupower-set.1
+	- rm -f $(DESTDIR)${mandir}/man1/cpupower-info.1
+	- rm -f $(DESTDIR)${mandir}/man1/cpupower-monitor.1
 	- for HLANG in $(LANGUAGES); do \
 	- for HLANG in $(LANGUAGES); do \
 		rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
 		rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
 	  done;
 	  done;

+ 11 - 13
tools/power/cpupower/README

@@ -1,6 +1,4 @@
-The cpufrequtils package (homepage: 
-http://www.kernel.org/pub/linux/utils/kernel/cpufreq/cpufrequtils.html ) 
-consists of the following elements:
+The cpupower package consists of the following elements:
 
 
 requirements
 requirements
 ------------
 ------------
@@ -11,10 +9,10 @@ providing cpuid.h is needed.
 For both it's not explicitly checked for (yet).
 For both it's not explicitly checked for (yet).
 
 
 
 
-libcpufreq
+libcpupower
 ----------
 ----------
 
 
-"libcpufreq" is a library which offers a unified access method for userspace
+"libcpupower" is a library which offers a unified access method for userspace
 tools and programs to the cpufreq core and drivers in the Linux kernel. This
 tools and programs to the cpufreq core and drivers in the Linux kernel. This
 allows for code reduction in userspace tools, a clean implementation of
 allows for code reduction in userspace tools, a clean implementation of
 the interaction to the cpufreq core, and support for both the sysfs and proc
 the interaction to the cpufreq core, and support for both the sysfs and proc
@@ -28,22 +26,22 @@ make
 su
 su
 make install
 make install
 
 
-should suffice on most systems. It builds default libcpufreq,
-cpufreq-set and cpufreq-info files and installs them in /usr/lib and
-/usr/bin, respectively. If you want to set up the paths differently and/or
-want to configure the package to your specific needs, you need to open
-"Makefile" with an editor of your choice and edit the block marked
-CONFIGURATION.
+should suffice on most systems. It builds libcpupower to put in
+/usr/lib; cpupower, cpufreq-bench_plot.sh to put in /usr/bin; and
+cpufreq-bench to put in /usr/sbin. If you want to set up the paths
+differently and/or want to configure the package to your specific
+needs, you need to open "Makefile" with an editor of your choice and
+edit the block marked CONFIGURATION.
 
 
 
 
 THANKS
 THANKS
 ------
 ------
 Many thanks to Mattia Dongili who wrote the autotoolization and
 Many thanks to Mattia Dongili who wrote the autotoolization and
-libtoolization, the manpages and the italian language file for cpufrequtils;
+libtoolization, the manpages and the italian language file for cpupower;
 to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his
 to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his
 powernow-k8-decode and intel_gsic tools as well as the french language file;
 powernow-k8-decode and intel_gsic tools as well as the french language file;
 and to various others commenting on the previous (pre-)releases of 
 and to various others commenting on the previous (pre-)releases of 
-cpufrequtils.
+cpupower.
 
 
 
 
         Dominik Brodowski
         Dominik Brodowski

+ 0 - 1
tools/power/cpupower/ToDo

@@ -3,7 +3,6 @@ ToDos sorted by priority:
 - Use bitmask functions to parse CPU topology more robust
 - Use bitmask functions to parse CPU topology more robust
   (current implementation has issues on AMD)
   (current implementation has issues on AMD)
 - Try to read out boost states and frequencies on Intel
 - Try to read out boost states and frequencies on Intel
-- Adjust README
 - Somewhere saw the ability to read power consumption of
 - Somewhere saw the ability to read power consumption of
   RAM from HW on Intel SandyBridge -> another monitor?
   RAM from HW on Intel SandyBridge -> another monitor?
 - Add another c1e debug idle monitor
 - Add another c1e debug idle monitor

+ 3 - 0
tools/power/cpupower/man/cpupower-frequency-info.1

@@ -50,6 +50,9 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and
 \fB\-m\fR \fB\-\-human\fR
 \fB\-m\fR \fB\-\-human\fR
 human\-readable output for the \-f, \-w, \-s and \-y parameters.
 human\-readable output for the \-f, \-w, \-s and \-y parameters.
 .TP  
 .TP  
+\fB\-n\fR \fB\-\-no-rounding\fR
+Output frequencies and latencies without rounding off values.
+.TP  
 .SH "REMARKS"
 .SH "REMARKS"
 .LP 
 .LP 
 By default only values of core zero are displayed. How to display settings of
 By default only values of core zero are displayed. How to display settings of

+ 8 - 2
tools/power/cpupower/man/cpupower-idle-set.1

@@ -13,11 +13,17 @@ sleep states. This can be handy for power vs performance tuning.
 .SH "OPTIONS"
 .SH "OPTIONS"
 .LP
 .LP
 .TP
 .TP
-\fB\-d\fR \fB\-\-disable\fR
+\fB\-d\fR \fB\-\-disable\fR <STATE_NO>
 Disable a specific processor sleep state.
 Disable a specific processor sleep state.
 .TP
 .TP
-\fB\-e\fR \fB\-\-enable\fR
+\fB\-e\fR \fB\-\-enable\fR <STATE_NO>
 Enable a specific processor sleep state.
 Enable a specific processor sleep state.
+.TP
+\fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY>
+Disable all idle states with a equal or higher latency than <LATENCY>
+.TP
+\fB\-E\fR \fB\-\-enable-all\fR
+Enable all idle states if not enabled already.
 
 
 .SH "REMARKS"
 .SH "REMARKS"
 .LP
 .LP

+ 1 - 1
tools/power/cpupower/man/cpupower-info.1

@@ -3,7 +3,7 @@
 cpupower\-info \- Shows processor power related kernel or hardware configurations
 cpupower\-info \- Shows processor power related kernel or hardware configurations
 .SH SYNOPSIS
 .SH SYNOPSIS
 .ft B
 .ft B
-.B cpupower info [ \-b ] [ \-s ] [ \-m ]
+.B cpupower info [ \-b ]
 
 
 .SH DESCRIPTION
 .SH DESCRIPTION
 \fBcpupower info \fP shows kernel configurations or processor hardware
 \fBcpupower info \fP shows kernel configurations or processor hardware

+ 1 - 30
tools/power/cpupower/man/cpupower-set.1

@@ -3,7 +3,7 @@
 cpupower\-set \- Set processor power related kernel or hardware configurations
 cpupower\-set \- Set processor power related kernel or hardware configurations
 .SH SYNOPSIS
 .SH SYNOPSIS
 .ft B
 .ft B
-.B cpupower set [ \-b VAL ] [ \-s VAL ] [ \-m VAL ]
+.B cpupower set [ \-b VAL ]
 
 
 
 
 .SH DESCRIPTION
 .SH DESCRIPTION
@@ -55,35 +55,6 @@ Use \fBcpupower -c all info -b\fP to verify.
 
 
 This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
 This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
 .RE
 .RE
-.PP
-\-\-sched\-mc,  \-m [ VAL ]
-.RE
-\-\-sched\-smt, \-s [ VAL ]
-.RS 4
-\-\-sched\-mc utilizes cores in one processor package/socket first before
-processes are scheduled to other processor packages/sockets.
-
-\-\-sched\-smt utilizes thread siblings of one processor core first before
-processes are scheduled to other cores.
-
-The impact on power consumption and performance (positiv or negativ) heavily
-depends on processor support for deep sleep states, frequency scaling and
-frequency boost modes and their dependencies between other thread siblings
-and processor cores.
-
-Taken over from kernel documentation:
-
-Adjust the kernel's multi-core scheduler support.
-
-Possible values are:
-.RS 2
-0 - No power saving load balance (default value)
-
-1 - Fill one thread/core/package first for long running threads
-
-2 - Also bias task wakeups to semi-idle cpu package for power
-savings
-.RE
 
 
 .SH "SEE ALSO"
 .SH "SEE ALSO"
 cpupower-info(1), cpupower-monitor(1), powertop(1)
 cpupower-info(1), cpupower-monitor(1), powertop(1)

+ 70 - 40
tools/power/cpupower/utils/cpufreq-info.c

@@ -82,29 +82,42 @@ static void proc_cpufreq_output(void)
 	}
 	}
 }
 }
 
 
+static int no_rounding;
 static void print_speed(unsigned long speed)
 static void print_speed(unsigned long speed)
 {
 {
 	unsigned long tmp;
 	unsigned long tmp;
 
 
-	if (speed > 1000000) {
-		tmp = speed % 10000;
-		if (tmp >= 5000)
-			speed += 10000;
-		printf("%u.%02u GHz", ((unsigned int) speed/1000000),
-			((unsigned int) (speed%1000000)/10000));
-	} else if (speed > 100000) {
-		tmp = speed % 1000;
-		if (tmp >= 500)
-			speed += 1000;
-		printf("%u MHz", ((unsigned int) speed / 1000));
-	} else if (speed > 1000) {
-		tmp = speed % 100;
-		if (tmp >= 50)
-			speed += 100;
-		printf("%u.%01u MHz", ((unsigned int) speed/1000),
-			((unsigned int) (speed%1000)/100));
-	} else
-		printf("%lu kHz", speed);
+	if (no_rounding) {
+		if (speed > 1000000)
+			printf("%u.%06u GHz", ((unsigned int) speed/1000000),
+				((unsigned int) speed%1000000));
+		else if (speed > 100000)
+			printf("%u MHz", (unsigned int) speed);
+		else if (speed > 1000)
+			printf("%u.%03u MHz", ((unsigned int) speed/1000),
+				(unsigned int) (speed%1000));
+		else
+			printf("%lu kHz", speed);
+	} else {
+		if (speed > 1000000) {
+			tmp = speed%10000;
+			if (tmp >= 5000)
+				speed += 10000;
+			printf("%u.%02u GHz", ((unsigned int) speed/1000000),
+				((unsigned int) (speed%1000000)/10000));
+		} else if (speed > 100000) {
+			tmp = speed%1000;
+			if (tmp >= 500)
+				speed += 1000;
+			printf("%u MHz", ((unsigned int) speed/1000));
+		} else if (speed > 1000) {
+			tmp = speed%100;
+			if (tmp >= 50)
+				speed += 100;
+			printf("%u.%01u MHz", ((unsigned int) speed/1000),
+				((unsigned int) (speed%1000)/100));
+		}
+	}
 
 
 	return;
 	return;
 }
 }
@@ -113,26 +126,38 @@ static void print_duration(unsigned long duration)
 {
 {
 	unsigned long tmp;
 	unsigned long tmp;
 
 
-	if (duration > 1000000) {
-		tmp = duration % 10000;
-		if (tmp >= 5000)
-			duration += 10000;
-		printf("%u.%02u ms", ((unsigned int) duration/1000000),
-			((unsigned int) (duration%1000000)/10000));
-	} else if (duration > 100000) {
-		tmp = duration % 1000;
-		if (tmp >= 500)
-			duration += 1000;
-		printf("%u us", ((unsigned int) duration / 1000));
-	} else if (duration > 1000) {
-		tmp = duration % 100;
-		if (tmp >= 50)
-			duration += 100;
-		printf("%u.%01u us", ((unsigned int) duration/1000),
-			((unsigned int) (duration%1000)/100));
-	} else
-		printf("%lu ns", duration);
-
+	if (no_rounding) {
+		if (duration > 1000000)
+			printf("%u.%06u ms", ((unsigned int) duration/1000000),
+				((unsigned int) duration%1000000));
+		else if (duration > 100000)
+			printf("%u us", ((unsigned int) duration/1000));
+		else if (duration > 1000)
+			printf("%u.%03u us", ((unsigned int) duration/1000),
+				((unsigned int) duration%1000));
+		else
+			printf("%lu ns", duration);
+	} else {
+		if (duration > 1000000) {
+			tmp = duration%10000;
+			if (tmp >= 5000)
+				duration += 10000;
+			printf("%u.%02u ms", ((unsigned int) duration/1000000),
+				((unsigned int) (duration%1000000)/10000));
+		} else if (duration > 100000) {
+			tmp = duration%1000;
+			if (tmp >= 500)
+				duration += 1000;
+			printf("%u us", ((unsigned int) duration / 1000));
+		} else if (duration > 1000) {
+			tmp = duration%100;
+			if (tmp >= 50)
+				duration += 100;
+			printf("%u.%01u us", ((unsigned int) duration/1000),
+				((unsigned int) (duration%1000)/100));
+		} else
+			printf("%lu ns", duration);
+	}
 	return;
 	return;
 }
 }
 
 
@@ -525,6 +550,7 @@ static struct option info_opts[] = {
 	{ .name = "latency",	.has_arg = no_argument,		.flag = NULL,	.val = 'y'},
 	{ .name = "latency",	.has_arg = no_argument,		.flag = NULL,	.val = 'y'},
 	{ .name = "proc",	.has_arg = no_argument,		.flag = NULL,	.val = 'o'},
 	{ .name = "proc",	.has_arg = no_argument,		.flag = NULL,	.val = 'o'},
 	{ .name = "human",	.has_arg = no_argument,		.flag = NULL,	.val = 'm'},
 	{ .name = "human",	.has_arg = no_argument,		.flag = NULL,	.val = 'm'},
+	{ .name = "no-rounding", .has_arg = no_argument,	.flag = NULL,	.val = 'n'},
 	{ },
 	{ },
 };
 };
 
 
@@ -538,7 +564,8 @@ int cmd_freq_info(int argc, char **argv)
 	int output_param = 0;
 	int output_param = 0;
 
 
 	do {
 	do {
-		ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL);
+		ret = getopt_long(argc, argv, "oefwldpgrasmybn", info_opts,
+				  NULL);
 		switch (ret) {
 		switch (ret) {
 		case '?':
 		case '?':
 			output_param = '?';
 			output_param = '?';
@@ -575,6 +602,9 @@ int cmd_freq_info(int argc, char **argv)
 			}
 			}
 			human = 1;
 			human = 1;
 			break;
 			break;
+		case 'n':
+			no_rounding = 1;
+			break;
 		default:
 		default:
 			fprintf(stderr, "invalid or unknown argument\n");
 			fprintf(stderr, "invalid or unknown argument\n");
 			return EXIT_FAILURE;
 			return EXIT_FAILURE;

+ 69 - 6
tools/power/cpupower/utils/cpuidle-set.c

@@ -13,8 +13,14 @@
 #include "helpers/sysfs.h"
 #include "helpers/sysfs.h"
 
 
 static struct option info_opts[] = {
 static struct option info_opts[] = {
-	{ .name = "disable",	.has_arg = required_argument,	.flag = NULL,	.val = 'd'},
-	{ .name = "enable",	.has_arg = required_argument,	.flag = NULL,	.val = 'e'},
+	{ .name = "disable",
+	  .has_arg = required_argument,	.flag = NULL,	.val = 'd'},
+	{ .name = "enable",
+	  .has_arg = required_argument,	.flag = NULL,	.val = 'e'},
+	{ .name = "disable-by-latency",
+	  .has_arg = required_argument,	.flag = NULL,	.val = 'D'},
+	{ .name = "enable-all",
+	  .has_arg = no_argument,	.flag = NULL,	.val = 'E'},
 	{ },
 	{ },
 };
 };
 
 
@@ -23,11 +29,13 @@ int cmd_idle_set(int argc, char **argv)
 {
 {
 	extern char *optarg;
 	extern char *optarg;
 	extern int optind, opterr, optopt;
 	extern int optind, opterr, optopt;
-	int ret = 0, cont = 1, param = 0, idlestate = 0;
-	unsigned int cpu = 0;
+	int ret = 0, cont = 1, param = 0, disabled;
+	unsigned long long latency = 0, state_latency;
+	unsigned int cpu = 0, idlestate = 0, idlestates = 0;
+	char *endptr;
 
 
 	do {
 	do {
-		ret = getopt_long(argc, argv, "d:e:", info_opts, NULL);
+		ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL);
 		if (ret == -1)
 		if (ret == -1)
 			break;
 			break;
 		switch (ret) {
 		switch (ret) {
@@ -53,6 +61,27 @@ int cmd_idle_set(int argc, char **argv)
 			param = ret;
 			param = ret;
 			idlestate = atoi(optarg);
 			idlestate = atoi(optarg);
 			break;
 			break;
+		case 'D':
+			if (param) {
+				param = -1;
+				cont = 0;
+				break;
+			}
+			param = ret;
+			latency = strtoull(optarg, &endptr, 10);
+			if (*endptr != '\0') {
+				printf(_("Bad latency value: %s\n"), optarg);
+				exit(EXIT_FAILURE);
+			}
+			break;
+		case 'E':
+			if (param) {
+				param = -1;
+				cont = 0;
+				break;
+			}
+			param = ret;
+			break;
 		case -1:
 		case -1:
 			cont = 0;
 			cont = 0;
 			break;
 			break;
@@ -79,8 +108,14 @@ int cmd_idle_set(int argc, char **argv)
 		if (!bitmask_isbitset(cpus_chosen, cpu))
 		if (!bitmask_isbitset(cpus_chosen, cpu))
 			continue;
 			continue;
 
 
-		switch (param) {
+		if (sysfs_is_cpu_online(cpu) != 1)
+			continue;
+
+		idlestates = sysfs_get_idlestate_count(cpu);
+		if (idlestates <= 0)
+			continue;
 
 
+		switch (param) {
 		case 'd':
 		case 'd':
 			ret = sysfs_idlestate_disable(cpu, idlestate, 1);
 			ret = sysfs_idlestate_disable(cpu, idlestate, 1);
 			if (ret == 0)
 			if (ret == 0)
@@ -107,6 +142,34 @@ int cmd_idle_set(int argc, char **argv)
 		printf(_("Idlestate %u not enabled on CPU %u\n"),
 		printf(_("Idlestate %u not enabled on CPU %u\n"),
 		       idlestate, cpu);
 		       idlestate, cpu);
 			break;
 			break;
+		case 'D':
+			for (idlestate = 0; idlestate < idlestates; idlestate++) {
+				disabled = sysfs_is_idlestate_disabled
+					(cpu, idlestate);
+				state_latency = sysfs_get_idlestate_latency
+					(cpu, idlestate);
+				printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n",
+				       cpu, idlestate, state_latency, latency);
+				if (disabled == 1 || latency > state_latency)
+					continue;
+				ret = sysfs_idlestate_disable
+					(cpu, idlestate, 1);
+				if (ret == 0)
+		printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
+			}
+			break;
+		case 'E':
+			for (idlestate = 0; idlestate < idlestates; idlestate++) {
+				disabled = sysfs_is_idlestate_disabled
+					(cpu, idlestate);
+				if (disabled == 1) {
+					ret = sysfs_idlestate_disable
+						(cpu, idlestate, 0);
+					if (ret == 0)
+		printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
+				}
+			}
+			break;
 		default:
 		default:
 			/* Not reachable with proper args checking */
 			/* Not reachable with proper args checking */
 			printf(_("Invalid or unknown argument\n"));
 			printf(_("Invalid or unknown argument\n"));

+ 5 - 37
tools/power/cpupower/utils/cpupower-info.c

@@ -18,8 +18,6 @@
 
 
 static struct option set_opts[] = {
 static struct option set_opts[] = {
 	{ .name = "perf-bias",	.has_arg = optional_argument,	.flag = NULL,	.val = 'b'},
 	{ .name = "perf-bias",	.has_arg = optional_argument,	.flag = NULL,	.val = 'b'},
-	{ .name = "sched-mc",	.has_arg = optional_argument,	.flag = NULL,	.val = 'm'},
-	{ .name = "sched-smt",	.has_arg = optional_argument,	.flag = NULL,	.val = 's'},
 	{ },
 	{ },
 };
 };
 
 
@@ -37,8 +35,6 @@ int cmd_info(int argc, char **argv)
 
 
 	union {
 	union {
 		struct {
 		struct {
-			int sched_mc:1;
-			int sched_smt:1;
 			int perf_bias:1;
 			int perf_bias:1;
 		};
 		};
 		int params;
 		int params;
@@ -49,23 +45,13 @@ int cmd_info(int argc, char **argv)
 	textdomain(PACKAGE);
 	textdomain(PACKAGE);
 
 
 	/* parameter parsing */
 	/* parameter parsing */
-	while ((ret = getopt_long(argc, argv, "msb", set_opts, NULL)) != -1) {
+	while ((ret = getopt_long(argc, argv, "b", set_opts, NULL)) != -1) {
 		switch (ret) {
 		switch (ret) {
 		case 'b':
 		case 'b':
 			if (params.perf_bias)
 			if (params.perf_bias)
 				print_wrong_arg_exit();
 				print_wrong_arg_exit();
 			params.perf_bias = 1;
 			params.perf_bias = 1;
 			break;
 			break;
-		case 'm':
-			if (params.sched_mc)
-				print_wrong_arg_exit();
-			params.sched_mc = 1;
-			break;
-		case 's':
-			if (params.sched_smt)
-				print_wrong_arg_exit();
-			params.sched_smt = 1;
-			break;
 		default:
 		default:
 			print_wrong_arg_exit();
 			print_wrong_arg_exit();
 		}
 		}
@@ -78,25 +64,6 @@ int cmd_info(int argc, char **argv)
 	if (bitmask_isallclear(cpus_chosen))
 	if (bitmask_isallclear(cpus_chosen))
 		bitmask_setbit(cpus_chosen, 0);
 		bitmask_setbit(cpus_chosen, 0);
 
 
-	if (params.sched_mc) {
-		ret = sysfs_get_sched("mc");
-		printf(_("System's multi core scheduler setting: "));
-		if (ret < 0)
-			/* if sysfs file is missing it's: errno == ENOENT */
-			printf(_("not supported\n"));
-		else
-			printf("%d\n", ret);
-	}
-	if (params.sched_smt) {
-		ret = sysfs_get_sched("smt");
-		printf(_("System's thread sibling scheduler setting: "));
-		if (ret < 0)
-			/* if sysfs file is missing it's: errno == ENOENT */
-			printf(_("not supported\n"));
-		else
-			printf("%d\n", ret);
-	}
-
 	/* Add more per cpu options here */
 	/* Add more per cpu options here */
 	if (!params.perf_bias)
 	if (!params.perf_bias)
 		return ret;
 		return ret;
@@ -125,11 +92,12 @@ int cmd_info(int argc, char **argv)
 		if (params.perf_bias) {
 		if (params.perf_bias) {
 			ret = msr_intel_get_perf_bias(cpu);
 			ret = msr_intel_get_perf_bias(cpu);
 			if (ret < 0) {
 			if (ret < 0) {
-				printf(_("Could not read perf-bias value\n"));
-				break;
+				fprintf(stderr,
+			_("Could not read perf-bias value[%d]\n"), ret);
+				exit(EXIT_FAILURE);
 			} else
 			} else
 				printf(_("perf-bias: %d\n"), ret);
 				printf(_("perf-bias: %d\n"), ret);
 		}
 		}
 	}
 	}
-	return ret;
+	return 0;
 }
 }

+ 2 - 41
tools/power/cpupower/utils/cpupower-set.c

@@ -19,8 +19,6 @@
 
 
 static struct option set_opts[] = {
 static struct option set_opts[] = {
 	{ .name = "perf-bias",	.has_arg = required_argument,	.flag = NULL,	.val = 'b'},
 	{ .name = "perf-bias",	.has_arg = required_argument,	.flag = NULL,	.val = 'b'},
-	{ .name = "sched-mc",	.has_arg = required_argument,	.flag = NULL,	.val = 'm'},
-	{ .name = "sched-smt",	.has_arg = required_argument,	.flag = NULL,	.val = 's'},
 	{ },
 	{ },
 };
 };
 
 
@@ -38,13 +36,11 @@ int cmd_set(int argc, char **argv)
 
 
 	union {
 	union {
 		struct {
 		struct {
-			int sched_mc:1;
-			int sched_smt:1;
 			int perf_bias:1;
 			int perf_bias:1;
 		};
 		};
 		int params;
 		int params;
 	} params;
 	} params;
-	int sched_mc = 0, sched_smt = 0, perf_bias = 0;
+	int perf_bias = 0;
 	int ret = 0;
 	int ret = 0;
 
 
 	setlocale(LC_ALL, "");
 	setlocale(LC_ALL, "");
@@ -52,7 +48,7 @@ int cmd_set(int argc, char **argv)
 
 
 	params.params = 0;
 	params.params = 0;
 	/* parameter parsing */
 	/* parameter parsing */
-	while ((ret = getopt_long(argc, argv, "m:s:b:",
+	while ((ret = getopt_long(argc, argv, "b:",
 						set_opts, NULL)) != -1) {
 						set_opts, NULL)) != -1) {
 		switch (ret) {
 		switch (ret) {
 		case 'b':
 		case 'b':
@@ -66,28 +62,6 @@ int cmd_set(int argc, char **argv)
 			}
 			}
 			params.perf_bias = 1;
 			params.perf_bias = 1;
 			break;
 			break;
-		case 'm':
-			if (params.sched_mc)
-				print_wrong_arg_exit();
-			sched_mc = atoi(optarg);
-			if (sched_mc < 0 || sched_mc > 2) {
-				printf(_("--sched-mc param out "
-					 "of range [0-%d]\n"), 2);
-				print_wrong_arg_exit();
-			}
-			params.sched_mc = 1;
-			break;
-		case 's':
-			if (params.sched_smt)
-				print_wrong_arg_exit();
-			sched_smt = atoi(optarg);
-			if (sched_smt < 0 || sched_smt > 2) {
-				printf(_("--sched-smt param out "
-					 "of range [0-%d]\n"), 2);
-				print_wrong_arg_exit();
-			}
-			params.sched_smt = 1;
-			break;
 		default:
 		default:
 			print_wrong_arg_exit();
 			print_wrong_arg_exit();
 		}
 		}
@@ -96,19 +70,6 @@ int cmd_set(int argc, char **argv)
 	if (!params.params)
 	if (!params.params)
 		print_wrong_arg_exit();
 		print_wrong_arg_exit();
 
 
-	if (params.sched_mc) {
-		ret = sysfs_set_sched("mc", sched_mc);
-		if (ret)
-			fprintf(stderr, _("Error setting sched-mc %s\n"),
-				(ret == -ENODEV) ? "not supported" : "");
-	}
-	if (params.sched_smt) {
-		ret = sysfs_set_sched("smt", sched_smt);
-		if (ret)
-			fprintf(stderr, _("Error setting sched-smt %s\n"),
-				(ret == -ENODEV) ? "not supported" : "");
-	}
-
 	/* Default is: set all CPUs */
 	/* Default is: set all CPUs */
 	if (bitmask_isallclear(cpus_chosen))
 	if (bitmask_isallclear(cpus_chosen))
 		bitmask_setall(cpus_chosen);
 		bitmask_setall(cpus_chosen);

+ 14 - 0
tools/power/cpupower/utils/cpupower.c

@@ -12,6 +12,9 @@
 #include <string.h>
 #include <string.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <errno.h>
 #include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
 
 
 #include "builtin.h"
 #include "builtin.h"
 #include "helpers/helpers.h"
 #include "helpers/helpers.h"
@@ -169,6 +172,8 @@ int main(int argc, const char *argv[])
 {
 {
 	const char *cmd;
 	const char *cmd;
 	unsigned int i, ret;
 	unsigned int i, ret;
+	struct stat statbuf;
+	struct utsname uts;
 
 
 	cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
 	cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
 
 
@@ -195,6 +200,15 @@ int main(int argc, const char *argv[])
 
 
 	get_cpu_info(0, &cpupower_cpu_info);
 	get_cpu_info(0, &cpupower_cpu_info);
 	run_as_root = !getuid();
 	run_as_root = !getuid();
+	if (run_as_root) {
+		ret = uname(&uts);
+		if (!ret && !strcmp(uts.machine, "x86_64") &&
+		    stat("/dev/cpu/0/msr", &statbuf) != 0) {
+			if (system("modprobe msr") == -1)
+	fprintf(stderr, _("MSR access not available.\n"));
+		}
+	}
+		
 
 
 	for (i = 0; i < ARRAY_SIZE(commands); i++) {
 	for (i = 0; i < ARRAY_SIZE(commands); i++) {
 		struct cmd_struct *p = commands + i;
 		struct cmd_struct *p = commands + i;

+ 2 - 2
tools/power/x86/turbostat/turbostat.c

@@ -1971,13 +1971,13 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
 	if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr))
 	if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr))
 		goto guess;
 		goto guess;
 
 
-	target_c_local = (msr >> 16) & 0x7F;
+	target_c_local = (msr >> 16) & 0xFF;
 
 
 	if (verbose)
 	if (verbose)
 		fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
 		fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
 			cpu, msr, target_c_local);
 			cpu, msr, target_c_local);
 
 
-	if (target_c_local < 85 || target_c_local > 127)
+	if (!target_c_local)
 		goto guess;
 		goto guess;
 
 
 	tcc_activation_temp = target_c_local;
 	tcc_activation_temp = target_c_local;