Przeglądaj źródła

Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/cpupowerutils

Pull cpupower updates from Dominik Brodowski.

* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/cpupowerutils:
  cpupower tools: add install target to the debug tools' makefiles
  cpupower tools: allow to build debug tools in a separate directory too
  cpupower: Fix broken mask values
  cpupower tool: allow to build in a separate directory
  cpupower tool: makefile: simplify the recipe used to generate cpupower.pot target
  cpupower tool: remove use of undefined variables from the clean target of the top makefile
  cpupower: Fix linking with --as-needed
  cpupower: Remove unneeded code and by that fix a memleak
  cpupower: Fix number of idle states
  cpupower: Unify cpupower-frequency-* manpages
  cpupower: Add cpupower-idle-info manpage
  cpupower: AMD fam14h/Ontario monitor can also be used by fam12h cpus
  cpupower: Better interface for accessing AMD pci registers
Linus Torvalds 13 lat temu
rodzic
commit
1c03658877

+ 57 - 36
tools/power/cpupower/Makefile

@@ -19,6 +19,16 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
+OUTPUT=./
+ifeq ("$(origin O)", "command line")
+	OUTPUT := $(O)/
+endif
+
+ifneq ($(OUTPUT),)
+# check that the output directory actually exists
+OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
+$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
+endif
 
 # --- CONFIGURATION BEGIN ---
 
@@ -87,6 +97,7 @@ AR = $(CROSS)ar
 STRIP = $(CROSS)strip
 RANLIB = $(CROSS)ranlib
 HOSTCC = gcc
+MKDIR = mkdir
 
 
 # Now we set up the build system
@@ -95,7 +106,7 @@ HOSTCC = gcc
 # set up PWD so that older versions of make will work with our build.
 PWD = $(shell pwd)
 
-GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo po/$$HLANG.gmo; done;}
+GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo $(OUTPUT)po/$$HLANG.gmo; done;}
 
 export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
 
@@ -122,15 +133,18 @@ UTIL_OBJS =  utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \
 	utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \
 	utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o
 
+UTIL_SRC := $(UTIL_OBJS:.o=.c)
+
+UTIL_OBJS := $(addprefix $(OUTPUT),$(UTIL_OBJS))
+
 UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \
 	utils/helpers/bitmask.h \
 	utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def
 
-UTIL_SRC := $(UTIL_OBJS:.o=.c)
-
 LIB_HEADERS = 	lib/cpufreq.h lib/sysfs.h
 LIB_SRC = 	lib/cpufreq.c lib/sysfs.c
 LIB_OBJS = 	lib/cpufreq.o lib/sysfs.o
+LIB_OBJS :=	$(addprefix $(OUTPUT),$(LIB_OBJS))
 
 CFLAGS +=	-pipe
 
@@ -168,83 +182,90 @@ endif
 
 # the actual make rules
 
-all: libcpupower cpupower $(COMPILE_NLS) $(COMPILE_BENCH)
+all: libcpupower $(OUTPUT)cpupower $(COMPILE_NLS) $(COMPILE_BENCH)
 
-lib/%.o: $(LIB_SRC) $(LIB_HEADERS)
+$(OUTPUT)lib/%.o: $(LIB_SRC) $(LIB_HEADERS)
 	$(ECHO) "  CC      " $@
 	$(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
 
-libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
+$(OUTPUT)libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
 	$(ECHO) "  LD      " $@
 	$(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \
 		-Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS)
-	@ln -sf $@ libcpupower.so
-	@ln -sf $@ libcpupower.so.$(LIB_MIN)
+	@ln -sf $(@F) $(OUTPUT)libcpupower.so
+	@ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MIN)
 
-libcpupower: libcpupower.so.$(LIB_MAJ)
+libcpupower: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
 
 # Let all .o files depend on its .c file and all headers
 # Might be worth to put this into utils/Makefile at some point of time
 $(UTIL_OBJS): $(UTIL_HEADERS)
 
-.c.o:
+$(OUTPUT)%.o: %.c
 	$(ECHO) "  CC      " $@
 	$(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c
 
-cpupower: $(UTIL_OBJS) libcpupower.so.$(LIB_MAJ)
+$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
 	$(ECHO) "  CC      " $@
-	$(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) -lcpupower -lrt -lpci -L. -o $@ $(UTIL_OBJS)
+	$(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
 	$(QUIET) $(STRIPCMD) $@
 
-po/$(PACKAGE).pot: $(UTIL_SRC)
+$(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
 	$(ECHO) "  GETTEXT " $@
 	$(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \
-		--keyword=_ --keyword=N_ $(UTIL_SRC) && \
-	test -f $(PACKAGE).po && \
-	mv -f $(PACKAGE).po po/$(PACKAGE).pot
+		--keyword=_ --keyword=N_ $(UTIL_SRC) -p $(@D) -o $(@F)
 
-po/%.gmo: po/%.po
+$(OUTPUT)po/%.gmo: po/%.po
 	$(ECHO) "  MSGFMT  " $@
 	$(QUIET) msgfmt -o $@ po/$*.po
 
 create-gmo: ${GMO_FILES}
 
-update-po: po/$(PACKAGE).pot
+update-po: $(OUTPUT)po/$(PACKAGE).pot
 	$(ECHO) "  MSGMRG  " $@
 	$(QUIET) @for HLANG in $(LANGUAGES); do \
 		echo -n "Updating $$HLANG "; \
-		if msgmerge po/$$HLANG.po po/$(PACKAGE).pot -o \
-		   po/$$HLANG.new.po; then \
-			mv -f po/$$HLANG.new.po po/$$HLANG.po; \
+		if msgmerge po/$$HLANG.po $< -o \
+		   $(OUTPUT)po/$$HLANG.new.po; then \
+			mv -f $(OUTPUT)po/$$HLANG.new.po $(OUTPUT)po/$$HLANG.po; \
 		else \
 			echo "msgmerge for $$HLANG failed!"; \
-			rm -f po/$$HLANG.new.po; \
+			rm -f $(OUTPUT)po/$$HLANG.new.po; \
 		fi; \
 	done;
 
-compile-bench: libcpupower.so.$(LIB_MAJ)
-	@V=$(V) confdir=$(confdir) $(MAKE) -C bench
+compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
+	@V=$(V) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT)
+
+# we compile into subdirectories. if the target directory is not the
+# source directory, they might not exists. So we depend the various
+# files onto their directories.
+DIRECTORY_DEPS = $(LIB_OBJS) $(UTIL_OBJS) $(GMO_FILES)
+$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
+
+# In the second step, we make a rule to actually create these directories
+$(sort $(dir $(DIRECTORY_DEPS))):
+	$(ECHO) "  MKDIR      " $@
+	$(QUIET) $(MKDIR) -p $@ 2>/dev/null
 
 clean:
-	-find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \
+	-find $(OUTPUT) \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \
 	 | xargs rm -f
-	-rm -f $(UTIL_BINS)
-	-rm -f $(IDLE_OBJS)
-	-rm -f cpupower
-	-rm -f libcpupower.so*
-	-rm -rf po/*.gmo po/*.pot
-	$(MAKE) -C bench clean
+	-rm -f $(OUTPUT)cpupower
+	-rm -f $(OUTPUT)libcpupower.so*
+	-rm -rf $(OUTPUT)po/*.{gmo,pot}
+	$(MAKE) -C bench O=$(OUTPUT) clean
 
 
 install-lib:
 	$(INSTALL) -d $(DESTDIR)${libdir}
-	$(CP) libcpupower.so* $(DESTDIR)${libdir}/
+	$(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/
 	$(INSTALL) -d $(DESTDIR)${includedir}
 	$(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
 
 install-tools:
 	$(INSTALL) -d $(DESTDIR)${bindir}
-	$(INSTALL_PROGRAM) cpupower $(DESTDIR)${bindir}
+	$(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir}
 
 install-man:
 	$(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
@@ -257,13 +278,13 @@ install-man:
 install-gmo:
 	$(INSTALL) -d $(DESTDIR)${localedir}
 	for HLANG in $(LANGUAGES); do \
-		echo '$(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
-		$(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
+		echo '$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
+		$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
 	done;
 
 install-bench:
 	@#DESTDIR must be set from outside to survive
-	@sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench install
+	@sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install
 
 install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH)
 

+ 15 - 8
tools/power/cpupower/bench/Makefile

@@ -1,29 +1,36 @@
-LIBS = -L../ -lm -lcpupower
+OUTPUT := ./
+ifeq ("$(origin O)", "command line")
+ifneq ($(O),)
+	OUTPUT := $(O)/
+endif
+endif
 
-OBJS = main.o parse.o system.o benchmark.o
+LIBS = -L../ -L$(OUTPUT) -lm -lcpupower
+
+OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o
 CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\"
 
-%.o : %.c
+$(OUTPUT)%.o : %.c
 	$(ECHO) "  CC      " $@
 	$(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
-cpufreq-bench: $(OBJS)
+$(OUTPUT)cpufreq-bench: $(OBJS)
 	$(ECHO) "  CC      " $@
 	$(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS)
 
-all: cpufreq-bench
+all: $(OUTPUT)cpufreq-bench
 
 install:
 	mkdir -p $(DESTDIR)/$(sbindir)
 	mkdir -p $(DESTDIR)/$(bindir)
 	mkdir -p $(DESTDIR)/$(docdir)
 	mkdir -p $(DESTDIR)/$(confdir)
-	install -m 755 cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench
+	install -m 755 $(OUTPUT)cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench
 	install -m 755 cpufreq-bench_plot.sh $(DESTDIR)/$(bindir)/cpufreq-bench_plot.sh
 	install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH
 	install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh
 	install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf
 
 clean:
-	rm -f *.o
-	rm -f cpufreq-bench
+	rm -f $(OUTPUT)*.o
+	rm -f $(OUTPUT)cpufreq-bench

+ 29 - 11
tools/power/cpupower/debug/i386/Makefile

@@ -1,20 +1,38 @@
+OUTPUT=./
+ifeq ("$(origin O)", "command line")
+	OUTPUT := $(O)/
+endif
+
+DESTDIR =
+bindir  = /usr/bin
+
+INSTALL = /usr/bin/install
+
+
 default: all
 
-centrino-decode: centrino-decode.c
-	$(CC) $(CFLAGS) -o centrino-decode centrino-decode.c
+$(OUTPUT)centrino-decode: centrino-decode.c
+	$(CC) $(CFLAGS) -o $@ centrino-decode.c
 
-dump_psb: dump_psb.c
-	$(CC) $(CFLAGS) -o dump_psb dump_psb.c
+$(OUTPUT)dump_psb: dump_psb.c
+	$(CC) $(CFLAGS) -o $@ dump_psb.c
 
-intel_gsic: intel_gsic.c
-	$(CC) $(CFLAGS) -o intel_gsic -llrmi intel_gsic.c
+$(OUTPUT)intel_gsic: intel_gsic.c
+	$(CC) $(CFLAGS) -o $@ -llrmi intel_gsic.c
 
-powernow-k8-decode: powernow-k8-decode.c
-	$(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c
+$(OUTPUT)powernow-k8-decode: powernow-k8-decode.c
+	$(CC) $(CFLAGS) -o $@ powernow-k8-decode.c
 
-all: centrino-decode dump_psb intel_gsic powernow-k8-decode
+all: $(OUTPUT)centrino-decode $(OUTPUT)dump_psb $(OUTPUT)intel_gsic $(OUTPUT)powernow-k8-decode
 
 clean:
-	rm -rf centrino-decode dump_psb intel_gsic powernow-k8-decode
+	rm -rf $(OUTPUT){centrino-decode,dump_psb,intel_gsic,powernow-k8-decode}
+
+install:
+	$(INSTALL) -d $(DESTDIR)${bindir}
+	$(INSTALL) $(OUTPUT)centrino-decode $(DESTDIR)${bindir}
+	$(INSTALL) $(OUTPUT)powernow-k8-decode $(DESTDIR)${bindir}
+	$(INSTALL) $(OUTPUT)dump_psb $(DESTDIR)${bindir}
+	$(INSTALL) $(OUTPUT)intel_gsic $(DESTDIR)${bindir}
 
-.PHONY: all default clean
+.PHONY: all default clean install

+ 21 - 5
tools/power/cpupower/debug/x86_64/Makefile

@@ -1,14 +1,30 @@
+OUTPUT=./
+ifeq ("$(origin O)", "command line")
+	OUTPUT := $(O)/
+endif
+
+DESTDIR =
+bindir  = /usr/bin
+
+INSTALL = /usr/bin/install
+
+
 default: all
 
-centrino-decode: ../i386/centrino-decode.c
+$(OUTPUT)centrino-decode: ../i386/centrino-decode.c
 	$(CC) $(CFLAGS) -o $@ $<
 
-powernow-k8-decode: ../i386/powernow-k8-decode.c
+$(OUTPUT)powernow-k8-decode: ../i386/powernow-k8-decode.c
 	$(CC) $(CFLAGS) -o $@ $<
 
-all: centrino-decode powernow-k8-decode
+all: $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode
 
 clean:
-	rm -rf centrino-decode powernow-k8-decode
+	rm -rf $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode
+
+install:
+	$(INSTALL) -d $(DESTDIR)${bindir}
+	$(INSTALL) $(OUTPUT)centrino-decode $(DESTDIR)${bindir}
+	$(INSTALL) $(OUTPUT)powernow-k8-decode $(DESTDIR)${bindir}
 
-.PHONY: all default clean
+.PHONY: all default clean install

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

@@ -1,4 +1,4 @@
-.TH "cpupower-frequency-info" "1" "0.1" "Mattia Dongili" ""
+.TH "CPUPOWER\-FREQUENCY\-INFO" "1" "0.1" "" "cpupower Manual"
 .SH "NAME"
 .LP 
 cpupower frequency\-info \- Utility to retrieve cpufreq kernel information
@@ -50,8 +50,6 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and
 \fB\-m\fR \fB\-\-human\fR
 human\-readable output for the \-f, \-w, \-s and \-y parameters.
 .TP  
-\fB\-h\fR \fB\-\-help\fR
-Prints out the help screen.
 .SH "REMARKS"
 .LP 
 By default only values of core zero are displayed. How to display settings of

+ 1 - 3
tools/power/cpupower/man/cpupower-frequency-set.1

@@ -1,4 +1,4 @@
-.TH "cpupower-freqency-set" "1" "0.1" "Mattia Dongili" ""
+.TH "CPUPOWER\-FREQUENCY\-SET" "1" "0.1" "" "cpupower Manual"
 .SH "NAME"
 .LP 
 cpupower frequency\-set \- A small tool which allows to modify cpufreq settings.
@@ -26,8 +26,6 @@ specific frequency to be set. Requires userspace governor to be available and lo
 \fB\-r\fR \fB\-\-related\fR
 modify all hardware-related CPUs at the same time
 .TP 
-\fB\-h\fR \fB\-\-help\fR
-Prints out the help screen.
 .SH "REMARKS"
 .LP 
 By default values are applied on all cores. How to modify single core

+ 90 - 0
tools/power/cpupower/man/cpupower-idle-info.1

@@ -0,0 +1,90 @@
+.TH "CPUPOWER-IDLE-INFO" "1" "0.1" "" "cpupower Manual"
+.SH "NAME"
+.LP
+cpupower idle\-info \- Utility to retrieve cpu idle kernel information
+.SH "SYNTAX"
+.LP
+cpupower [ \-c cpulist ] idle\-info [\fIoptions\fP]
+.SH "DESCRIPTION"
+.LP
+A tool which prints out per cpu idle information helpful to developers and interested users.
+.SH "OPTIONS"
+.LP
+.TP
+\fB\-f\fR \fB\-\-silent\fR
+Only print a summary of all available C-states in the system.
+.TP
+\fB\-e\fR \fB\-\-proc\fR
+deprecated.
+Prints out idle information in old /proc/acpi/processor/*/power format. This
+interface has been removed from the kernel for quite some time, do not let
+further code depend on this option, best do not use it.
+
+.SH IDLE\-INFO DESCRIPTIONS
+CPU sleep state statistics and descriptions are retrieved from sysfs files,
+exported by the cpuidle kernel subsystem. The kernel only updates these
+statistics when it enters or leaves an idle state, therefore on a very idle or
+a very busy system, these statistics may not be accurate. They still provide a
+good overview about the usage and availability of processor sleep states on
+the platform.
+
+Be aware that the sleep states as exported by the hardware or BIOS and used by
+the Linux kernel may not exactly reflect the capabilities of the
+processor. This often is the case on the X86 architecture when the acpi_idle
+driver is used. It is also possible that the hardware overrules the kernel
+requests, due to internal activity monitors or other reasons.
+On recent X86 platforms it is often possible to read out hardware registers
+which monitor the duration of sleep states the processor resided in. The
+cpupower monitor tool (cpupower\-monitor(1)) can be used to show real sleep
+state residencies. Please refer to the architecture specific description
+section below.
+
+.SH IDLE\-INFO ARCHITECTURE SPECIFIC DESCRIPTIONS
+.SS "X86"
+POLL idle state
+
+If cpuidle is active, X86 platforms have one special idle state.
+The POLL idle state is not a real idle state, it does not save any
+power. Instead, a busy\-loop is executed doing nothing for a short period of
+time. This state is used if the kernel knows that work has to be processed
+very soon and entering any real hardware idle state may result in a slight
+performance penalty.
+
+There exist two different cpuidle drivers on the X86 architecture platform:
+
+"acpi_idle" cpuidle driver
+
+The acpi_idle cpuidle driver retrieves available sleep states (C\-states) from
+the ACPI BIOS tables (from the _CST ACPI function on recent platforms or from
+the FADT BIOS table on older ones).
+The C1 state is not retrieved from ACPI tables. If the C1 state is entered,
+the kernel will call the hlt instruction (or mwait on Intel).
+
+"intel_idle" cpuidle driver
+
+In kernel 2.6.36 the intel_idle driver was introduced.
+It only serves recent Intel CPUs (Nehalem, Westmere, Sandybridge, Atoms or
+newer). On older Intel CPUs the acpi_idle driver is still used (if the BIOS
+provides C\-state ACPI tables).
+The intel_idle driver knows the sleep state capabilities of the processor and
+ignores ACPI BIOS exported processor sleep states tables.
+
+.SH "REMARKS"
+.LP
+By default only values of core zero are displayed. How to display settings of
+other cores is described in the cpupower(1) manpage in the \-\-cpu option
+section.
+.SH REFERENCES
+http://www.acpi.info/spec.htm
+.SH "FILES"
+.nf
+\fI/sys/devices/system/cpu/cpu*/cpuidle/state*\fP
+\fI/sys/devices/system/cpu/cpuidle/*\fP
+.fi
+.SH "AUTHORS"
+.nf
+Thomas Renninger <trenn@suse.de>
+.fi
+.SH "SEE ALSO"
+.LP
+cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1)

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

@@ -107,7 +107,7 @@ Deepest package sleep states may in reality show up as machine/platform wide
 sleep states and can only be entered if all cores are idle. Look up Intel
 manuals (some are provided in the References section) for further details.
 
-.SS "Ontario" "Liano"
+.SS "Fam_12h" "Fam_14h"
 AMD laptop and desktop processor (family 12h and 14h) sleep state counters.
 The registers are accessed via PCI and therefore can still be read out while
 cores have been offlined.

+ 2 - 10
tools/power/cpupower/utils/cpuidle-info.c

@@ -35,17 +35,9 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
 		printf(_("CPU %u: Can't read idle state info\n"), cpu);
 		return;
 	}
-	tmp = sysfs_get_idlestate_name(cpu, idlestates - 1);
-	if (!tmp) {
-		printf(_("Could not determine max idle state %u\n"),
-		       idlestates - 1);
-		return;
-	}
-
 	printf(_("Number of idle states: %d\n"), idlestates);
-
 	printf(_("Available idle states:"));
-	for (idlestate = 1; idlestate < idlestates; idlestate++) {
+	for (idlestate = 0; idlestate < idlestates; idlestate++) {
 		tmp = sysfs_get_idlestate_name(cpu, idlestate);
 		if (!tmp)
 			continue;
@@ -57,7 +49,7 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
 	if (!verbose)
 		return;
 
-	for (idlestate = 1; idlestate < idlestates; idlestate++) {
+	for (idlestate = 0; idlestate < idlestates; idlestate++) {
 		tmp = sysfs_get_idlestate_name(cpu, idlestate);
 		if (!tmp)
 			continue;

+ 1 - 3
tools/power/cpupower/utils/helpers/amd.c

@@ -112,14 +112,12 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family,
 int amd_pci_get_num_boost_states(int *active, int *states)
 {
 	struct pci_access *pci_acc;
-	int vendor_id = 0x1022;
-	int boost_dev_ids[4] = {0x1204, 0x1604, 0x1704, 0};
 	struct pci_dev *device;
 	uint8_t val = 0;
 
 	*active = *states = 0;
 
-	device = pci_acc_init(&pci_acc, vendor_id, boost_dev_ids);
+	device = pci_slot_func_init(&pci_acc, 0x18, 4);
 
 	if (device == NULL)
 		return -ENODEV;

+ 7 - 4
tools/power/cpupower/utils/helpers/helpers.h

@@ -66,8 +66,8 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
 #define CPUPOWER_CAP_AMD_CBP		0x00000004
 #define CPUPOWER_CAP_PERF_BIAS		0x00000008
 #define CPUPOWER_CAP_HAS_TURBO_RATIO	0x00000010
-#define CPUPOWER_CAP_IS_SNB		0x00000011
-#define CPUPOWER_CAP_INTEL_IDA		0x00000012
+#define CPUPOWER_CAP_IS_SNB		0x00000020
+#define CPUPOWER_CAP_INTEL_IDA		0x00000040
 
 #define MAX_HW_PSTATES 10
 
@@ -132,8 +132,11 @@ extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);
 
 /* PCI stuff ****************************/
 extern int amd_pci_get_num_boost_states(int *active, int *states);
-extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id,
-				    int *dev_ids);
+extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain,
+				    int bus, int slot, int func, int vendor,
+				    int dev);
+extern struct pci_dev *pci_slot_func_init(struct pci_access **pacc,
+					      int slot, int func);
 
 /* PCI stuff ****************************/
 

+ 23 - 12
tools/power/cpupower/utils/helpers/pci.c

@@ -10,19 +10,24 @@
  * **pacc : if a valid pci_dev is returned
  *         *pacc must be passed to pci_acc_cleanup to free it
  *
- * vendor_id : the pci vendor id matching the pci device to access
- * dev_ids :   device ids matching the pci device to access
+ * domain: domain
+ * bus:    bus
+ * slot:   slot
+ * func:   func
+ * vendor: vendor
+ * device: device
+ * Pass -1 for one of the six above to match any
  *
  * Returns :
  * struct pci_dev which can be used with pci_{read,write}_* functions
  *                to access the PCI config space of matching pci devices
  */
-struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id,
-				    int *dev_ids)
+struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain, int bus,
+			     int slot, int func, int vendor, int dev)
 {
-	struct pci_filter filter_nb_link = { -1, -1, -1, -1, vendor_id, 0};
+	struct pci_filter filter_nb_link = { domain, bus, slot, func,
+					     vendor, dev };
 	struct pci_dev *device;
-	unsigned int i;
 
 	*pacc = pci_alloc();
 	if (*pacc == NULL)
@@ -31,14 +36,20 @@ struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id,
 	pci_init(*pacc);
 	pci_scan_bus(*pacc);
 
-	for (i = 0; dev_ids[i] != 0; i++) {
-		filter_nb_link.device = dev_ids[i];
-		for (device = (*pacc)->devices; device; device = device->next) {
-			if (pci_filter_match(&filter_nb_link, device))
-				return device;
-		}
+	for (device = (*pacc)->devices; device; device = device->next) {
+		if (pci_filter_match(&filter_nb_link, device))
+			return device;
 	}
 	pci_cleanup(*pacc);
 	return NULL;
 }
+
+/* Typically one wants to get a specific slot(device)/func of the root domain
+   and bus */
+struct pci_dev *pci_slot_func_init(struct pci_access **pacc, int slot,
+				       int func)
+{
+	return pci_acc_init(pacc, 0, 0, slot, func, -1, -1);
+}
+
 #endif /* defined(__i386__) || defined(__x86_64__) */

+ 11 - 14
tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c

@@ -20,8 +20,6 @@
 #include "idle_monitor/cpupower-monitor.h"
 #include "helpers/helpers.h"
 
-/******** PCI parts could go into own file and get shared ***************/
-
 #define PCI_NON_PC0_OFFSET	0xb0
 #define PCI_PC1_OFFSET		0xb4
 #define PCI_PC6_OFFSET		0xb8
@@ -82,10 +80,7 @@ static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = {
 };
 
 static struct pci_access *pci_acc;
-static int pci_vendor_id = 0x1022;
-static int pci_dev_ids[2] = {0x1716, 0};
 static struct pci_dev *amd_fam14h_pci_dev;
-
 static int nbp1_entered;
 
 struct timespec start_time;
@@ -286,13 +281,13 @@ struct cpuidle_monitor *amd_fam14h_register(void)
 	if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
 		return NULL;
 
-	if (cpupower_cpu_info.family == 0x14) {
-		if (cpu_count <= 0 || cpu_count > 2) {
-			fprintf(stderr, "AMD fam14h: Invalid cpu count: %d\n",
-				cpu_count);
-			return NULL;
-		}
-	} else
+	if (cpupower_cpu_info.family == 0x14)
+		strncpy(amd_fam14h_monitor.name, "Fam_14h",
+			MONITOR_NAME_LEN - 1);
+	else if (cpupower_cpu_info.family == 0x12)
+		strncpy(amd_fam14h_monitor.name, "Fam_12h",
+			MONITOR_NAME_LEN - 1);
+	else
 		return NULL;
 
 	/* We do not alloc for nbp1 machine wide counter */
@@ -303,7 +298,9 @@ struct cpuidle_monitor *amd_fam14h_register(void)
 					      sizeof(unsigned long long));
 	}
 
-	amd_fam14h_pci_dev = pci_acc_init(&pci_acc, pci_vendor_id, pci_dev_ids);
+	/* We need PCI device: Slot 18, Func 6, compare with BKDG
+	   for fam 12h/14h */
+	amd_fam14h_pci_dev = pci_slot_func_init(&pci_acc, 0x18, 6);
 	if (amd_fam14h_pci_dev == NULL || pci_acc == NULL)
 		return NULL;
 
@@ -325,7 +322,7 @@ static void amd_fam14h_unregister(void)
 }
 
 struct cpuidle_monitor amd_fam14h_monitor = {
-	.name			= "Ontario",
+	.name			= "",
 	.hw_states		= amd_fam14h_cstates,
 	.hw_states_num		= AMD_FAM14H_STATE_NUM,
 	.start			= amd_fam14h_start,