Merge branch 'urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 31 Jul 2011 16:25:09 +0000 (06:25 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 31 Jul 2011 16:25:09 +0000 (06:25 -1000)
* 'urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/writeback:
  don't busy retry the inode on failed grab_super_passive()

105 files changed:
CREDITS
MAINTAINERS
drivers/mfd/max8998.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/pcmcia/pxa2xx_balloon3.c
drivers/pcmcia/pxa2xx_cm_x255.c
drivers/pcmcia/pxa2xx_cm_x270.c
drivers/pcmcia/pxa2xx_colibri.c
drivers/pcmcia/pxa2xx_mainstone.c
drivers/pcmcia/pxa2xx_palmld.c
drivers/pcmcia/pxa2xx_palmtc.c
drivers/pcmcia/pxa2xx_palmtx.c
drivers/pcmcia/pxa2xx_stargate2.c
drivers/pcmcia/pxa2xx_viper.c
drivers/pcmcia/soc_common.c
drivers/power/Kconfig
drivers/power/Makefile
drivers/power/apm_power.c
drivers/power/bq20z75.c
drivers/power/gpio-charger.c
drivers/power/max17042_battery.c
drivers/power/max8903_charger.c
drivers/power/max8997_charger.c [new file with mode: 0644]
drivers/power/max8998_charger.c [new file with mode: 0644]
drivers/power/s3c_adc_battery.c
drivers/power/twl4030_charger.c
drivers/power/wm831x_backup.c
drivers/power/wm831x_power.c
include/linux/mfd/max8997.h
include/linux/mfd/max8998.h
include/linux/power/bq20z75.h
include/linux/power/max17042_battery.h
include/pcmcia/device_id.h
tools/power/cpupower/.gitignore [new file with mode: 0644]
tools/power/cpupower/Makefile [new file with mode: 0644]
tools/power/cpupower/README [new file with mode: 0644]
tools/power/cpupower/ToDo [new file with mode: 0644]
tools/power/cpupower/bench/Makefile [new file with mode: 0644]
tools/power/cpupower/bench/README-BENCH [new file with mode: 0644]
tools/power/cpupower/bench/benchmark.c [new file with mode: 0644]
tools/power/cpupower/bench/benchmark.h [new file with mode: 0644]
tools/power/cpupower/bench/config.h [new file with mode: 0644]
tools/power/cpupower/bench/cpufreq-bench_plot.sh [new file with mode: 0644]
tools/power/cpupower/bench/cpufreq-bench_script.sh [new file with mode: 0644]
tools/power/cpupower/bench/example.cfg [new file with mode: 0644]
tools/power/cpupower/bench/main.c [new file with mode: 0644]
tools/power/cpupower/bench/parse.c [new file with mode: 0644]
tools/power/cpupower/bench/parse.h [new file with mode: 0644]
tools/power/cpupower/bench/system.c [new file with mode: 0644]
tools/power/cpupower/bench/system.h [new file with mode: 0644]
tools/power/cpupower/debug/i386/Makefile [new file with mode: 0644]
tools/power/cpupower/debug/i386/centrino-decode.c [new file with mode: 0644]
tools/power/cpupower/debug/i386/dump_psb.c [new file with mode: 0644]
tools/power/cpupower/debug/i386/intel_gsic.c [new file with mode: 0644]
tools/power/cpupower/debug/i386/powernow-k8-decode.c [new file with mode: 0644]
tools/power/cpupower/debug/kernel/Makefile [new file with mode: 0644]
tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c [new file with mode: 0644]
tools/power/cpupower/debug/x86_64/Makefile [new file with mode: 0644]
tools/power/cpupower/debug/x86_64/centrino-decode.c [new symlink]
tools/power/cpupower/debug/x86_64/powernow-k8-decode.c [new symlink]
tools/power/cpupower/lib/cpufreq.c [new file with mode: 0644]
tools/power/cpupower/lib/cpufreq.h [new file with mode: 0644]
tools/power/cpupower/lib/sysfs.c [new file with mode: 0644]
tools/power/cpupower/lib/sysfs.h [new file with mode: 0644]
tools/power/cpupower/man/cpupower-frequency-info.1 [new file with mode: 0644]
tools/power/cpupower/man/cpupower-frequency-set.1 [new file with mode: 0644]
tools/power/cpupower/man/cpupower-info.1 [new file with mode: 0644]
tools/power/cpupower/man/cpupower-monitor.1 [new file with mode: 0644]
tools/power/cpupower/man/cpupower-set.1 [new file with mode: 0644]
tools/power/cpupower/man/cpupower.1 [new file with mode: 0644]
tools/power/cpupower/po/cs.po [new file with mode: 0644]
tools/power/cpupower/po/de.po [new file with mode: 0644]
tools/power/cpupower/po/fr.po [new file with mode: 0644]
tools/power/cpupower/po/it.po [new file with mode: 0644]
tools/power/cpupower/po/pt.po [new file with mode: 0644]
tools/power/cpupower/utils/builtin.h [new file with mode: 0644]
tools/power/cpupower/utils/cpufreq-info.c [new file with mode: 0644]
tools/power/cpupower/utils/cpufreq-set.c [new file with mode: 0644]
tools/power/cpupower/utils/cpuidle-info.c [new file with mode: 0644]
tools/power/cpupower/utils/cpupower-info.c [new file with mode: 0644]
tools/power/cpupower/utils/cpupower-set.c [new file with mode: 0644]
tools/power/cpupower/utils/cpupower.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/amd.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/bitmask.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/bitmask.h [new file with mode: 0644]
tools/power/cpupower/utils/helpers/cpuid.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/helpers.h [new file with mode: 0644]
tools/power/cpupower/utils/helpers/misc.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/msr.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/pci.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/sysfs.c [new file with mode: 0644]
tools/power/cpupower/utils/helpers/sysfs.h [new file with mode: 0644]
tools/power/cpupower/utils/helpers/topology.c [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/idle_monitors.def [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/idle_monitors.h [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/mperf_monitor.c [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/nhm_idle.c [new file with mode: 0644]
tools/power/cpupower/utils/idle_monitor/snb_idle.c [new file with mode: 0644]
tools/power/cpupower/utils/version-gen.sh [new file with mode: 0755]

diff --git a/CREDITS b/CREDITS
index 1deb331..07e32a8 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -504,7 +504,7 @@ N: Dominik Brodowski
 E: linux@brodo.de
 W: http://www.brodo.de/
 P: 1024D/725B37C6  190F 3E77 9C89 3B6D BECD  46EE 67C3 0308 725B 37C6
-D: parts of CPUFreq code, ACPI bugfixes
+D: parts of CPUFreq code, ACPI bugfixes, PCMCIA rewrite, cpufrequtils
 S: Tuebingen, Germany
 
 N: Andries Brouwer
@@ -857,6 +857,10 @@ S: One Dell Way
 S: Round Rock, TX  78682
 S: USA
 
+N: Mattia Dongili
+E: malattia@gmail.com
+D: cpufrequtils (precursor to cpupowerutils)
+
 N: Ben Dooks
 E: ben-linux@fluff.org
 E: ben@simtec.co.uk
@@ -1883,6 +1887,11 @@ S: Kruislaan 419
 S: 1098 VA Amsterdam 
 S: The Netherlands
 
+N: Goran Koruga
+E: korugag@siol.net
+D: cpufrequtils (precursor to cpupowerutils)
+S: Slovenia
+
 N: Jiri Kosina
 E: jikos@jikos.cz
 E: jkosina@suse.cz
@@ -2916,6 +2925,12 @@ S: Schlossbergring 9
 S: 79098 Freiburg
 S: Germany
 
+N: Thomas Renninger
+E: trenn@suse.de
+D: cpupowerutils
+S: SUSE Linux GmbH
+S: Germany
+
 N: Joerg Reuter
 E: jreuter@yaina.de
 W: http://yaina.de/jreuter/
index cf5e8a7..c9c6324 100644 (file)
@@ -1925,6 +1925,12 @@ S:       Maintained
 F:     arch/x86/kernel/cpuid.c
 F:     arch/x86/kernel/msr.c
 
+CPU POWER MONITORING SUBSYSTEM
+M:     Dominik Brodowski <linux@dominikbrodowski.net>
+M:     Thomas Renninger <trenn@suse.de>
+S:     Maintained
+F:     tools/power/cpupower
+
 CPUSETS
 M:     Paul Menage <menage@google.com>
 W:     http://www.bullopensource.org/cpuset/
index 9ec7570..de4096a 100644 (file)
@@ -39,6 +39,8 @@ static struct mfd_cell max8998_devs[] = {
                .name = "max8998-pmic",
        }, {
                .name = "max8998-rtc",
+       }, {
+               .name = "max8998-battery",
        },
 };
 
index 1cd9394..cffbc03 100644 (file)
@@ -809,7 +809,7 @@ static int smc91c92_config(struct pcmcia_device *link)
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
     char *name;
-    int i, j, rev;
+    int i, rev, j = 0;
     unsigned int ioaddr;
     u_long mir;
 
index c052a0d..5441ad1 100644 (file)
@@ -648,6 +648,8 @@ static const struct pcmcia_device_id hostap_cs_ids[] = {
                                         0x74c5e40d),
        PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil",
                                         0x4b801a17),
+       PCMCIA_DEVICE_MANF_CARD_PROD_ID3(0x0156, 0x0002, "Version 01.02",
+                                        0x4b74baa0),
        PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",
                                    0x7a954bd9, 0x74be00c6),
        PCMCIA_DEVICE_PROD_ID123(
index 3f7fc4a..d7dbc00 100644 (file)
@@ -239,7 +239,6 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
 
 static const struct pcmcia_device_id orinoco_cs_ids[] = {
        PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
-       PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
        PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
        PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
        PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
@@ -272,6 +271,7 @@ static const struct pcmcia_device_id orinoco_cs_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
        PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
        PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
+       PCMCIA_DEVICE_MANF_CARD_PROD_ID3(0x0156, 0x0002, "Version 01.01", 0xd27deb1a), /* Lucent Orinoco */
 #ifdef CONFIG_HERMES_PRISM
        /* Only entries that certainly identify Prism chipset */
        PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
@@ -321,6 +321,9 @@ static const struct pcmcia_device_id orinoco_cs_ids[] = {
        PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
        PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
        PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
+
+       /* This may be Agere or Intersil Firmware */
+       PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
 #endif
        PCMCIA_DEVICE_NULL,
 };
index 4c3e94c..f56d7de 100644 (file)
@@ -103,22 +103,12 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void balloon3_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void balloon3_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level balloon3_pcmcia_ops = {
        .owner                  = THIS_MODULE,
        .hw_init                = balloon3_pcmcia_hw_init,
        .hw_shutdown            = balloon3_pcmcia_hw_shutdown,
        .socket_state           = balloon3_pcmcia_socket_state,
        .configure_socket       = balloon3_pcmcia_configure_socket,
-       .socket_init            = balloon3_pcmcia_socket_init,
-       .socket_suspend         = balloon3_pcmcia_socket_suspend,
        .first                  = 0,
        .nr                     = 1,
 };
index 05913d0..63f4d52 100644 (file)
@@ -102,23 +102,12 @@ static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void cmx255_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void cmx255_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
-
 static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
        .owner                  = THIS_MODULE,
        .hw_init                = cmx255_pcmcia_hw_init,
        .hw_shutdown            = cmx255_pcmcia_shutdown,
        .socket_state           = cmx255_pcmcia_socket_state,
        .configure_socket       = cmx255_pcmcia_configure_socket,
-       .socket_init            = cmx255_pcmcia_socket_init,
-       .socket_suspend         = cmx255_pcmcia_socket_suspend,
        .nr                     = 1,
 };
 
index 5662646..6ee42b4 100644 (file)
@@ -82,23 +82,12 @@ static int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void cmx270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void cmx270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
-
 static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
        .owner                  = THIS_MODULE,
        .hw_init                = cmx270_pcmcia_hw_init,
        .hw_shutdown            = cmx270_pcmcia_shutdown,
        .socket_state           = cmx270_pcmcia_socket_state,
        .configure_socket       = cmx270_pcmcia_configure_socket,
-       .socket_init            = cmx270_pcmcia_socket_init,
-       .socket_suspend         = cmx270_pcmcia_socket_suspend,
        .nr                     = 1,
 };
 
index 443cb7f..c6dec57 100644 (file)
@@ -116,14 +116,6 @@ colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void colibri_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void colibri_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level colibri_pcmcia_ops = {
        .owner                  = THIS_MODULE,
 
@@ -135,9 +127,6 @@ static struct pcmcia_low_level colibri_pcmcia_ops = {
 
        .socket_state           = colibri_pcmcia_socket_state,
        .configure_socket       = colibri_pcmcia_configure_socket,
-
-       .socket_init            = colibri_pcmcia_socket_init,
-       .socket_suspend         = colibri_pcmcia_socket_suspend,
 };
 
 static struct platform_device *colibri_pcmcia_device;
index 92016fe..aded706 100644 (file)
@@ -128,22 +128,12 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return ret;
 }
 
-static void mst_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void mst_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
        .owner                  = THIS_MODULE,
        .hw_init                = mst_pcmcia_hw_init,
        .hw_shutdown            = mst_pcmcia_hw_shutdown,
        .socket_state           = mst_pcmcia_socket_state,
        .configure_socket       = mst_pcmcia_configure_socket,
-       .socket_init            = mst_pcmcia_socket_init,
-       .socket_suspend         = mst_pcmcia_socket_suspend,
        .nr                     = 2,
 };
 
index 69f7367..d589ad1 100644 (file)
@@ -65,14 +65,6 @@ static int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void palmld_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level palmld_pcmcia_ops = {
        .owner                  = THIS_MODULE,
 
@@ -84,9 +76,6 @@ static struct pcmcia_low_level palmld_pcmcia_ops = {
 
        .socket_state           = palmld_pcmcia_socket_state,
        .configure_socket       = palmld_pcmcia_configure_socket,
-
-       .socket_init            = palmld_pcmcia_socket_init,
-       .socket_suspend         = palmld_pcmcia_socket_suspend,
 };
 
 static struct platform_device *palmld_pcmcia_device;
index d0ad6a7..9c6a04b 100644 (file)
@@ -117,14 +117,6 @@ static int palmtc_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return ret;
 }
 
-static void palmtc_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void palmtc_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level palmtc_pcmcia_ops = {
        .owner                  = THIS_MODULE,
 
@@ -136,9 +128,6 @@ static struct pcmcia_low_level palmtc_pcmcia_ops = {
 
        .socket_state           = palmtc_pcmcia_socket_state,
        .configure_socket       = palmtc_pcmcia_configure_socket,
-
-       .socket_init            = palmtc_pcmcia_socket_init,
-       .socket_suspend         = palmtc_pcmcia_socket_suspend,
 };
 
 static struct platform_device *palmtc_pcmcia_device;
index 1a25804..80645a6 100644 (file)
@@ -67,14 +67,6 @@ palmtx_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void palmtx_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void palmtx_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level palmtx_pcmcia_ops = {
        .owner                  = THIS_MODULE,
 
@@ -86,9 +78,6 @@ static struct pcmcia_low_level palmtx_pcmcia_ops = {
 
        .socket_state           = palmtx_pcmcia_socket_state,
        .configure_socket       = palmtx_pcmcia_configure_socket,
-
-       .socket_init            = palmtx_pcmcia_socket_init,
-       .socket_suspend         = palmtx_pcmcia_socket_suspend,
 };
 
 static struct platform_device *palmtx_pcmcia_device;
index d08802f..9396222 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "soc_common.h"
 
-#define SG2_S0_BUFF_CTL                120
 #define SG2_S0_POWER_CTL       108
 #define SG2_S0_GPIO_RESET      82
 #define SG2_S0_GPIO_DETECT     53
@@ -38,6 +37,11 @@ static struct pcmcia_irqs irqs[] = {
        { 0, IRQ_GPIO(SG2_S0_GPIO_DETECT), "PCMCIA0 CD" },
 };
 
+static struct gpio sg2_pcmcia_gpios[] = {
+       { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },
+       { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" },
+};
+
 static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        skt->socket.pci_irq = IRQ_GPIO(SG2_S0_GPIO_READY);
@@ -122,37 +126,23 @@ static int __init sg2_pcmcia_init(void)
        if (!sg2_pcmcia_device)
                return -ENOMEM;
 
-       ret = gpio_request(SG2_S0_BUFF_CTL, "SG2 CF buff ctl");
+       ret = gpio_request_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
        if (ret)
                goto error_put_platform_device;
-       ret = gpio_request(SG2_S0_POWER_CTL, "SG2 CF power ctl");
-       if (ret)
-               goto error_free_gpio_buff_ctl;
-       ret = gpio_request(SG2_S0_GPIO_RESET, "SG2 CF reset");
-       if (ret)
-               goto error_free_gpio_power_ctl;
-       /* Set gpio directions */
-       gpio_direction_output(SG2_S0_BUFF_CTL, 0);
-       gpio_direction_output(SG2_S0_POWER_CTL, 1);
-       gpio_direction_output(SG2_S0_GPIO_RESET, 1);
 
        ret = platform_device_add_data(sg2_pcmcia_device,
                                       &sg2_pcmcia_ops,
                                       sizeof(sg2_pcmcia_ops));
        if (ret)
-               goto error_free_gpio_reset;
+               goto error_free_gpios;
 
        ret = platform_device_add(sg2_pcmcia_device);
        if (ret)
-               goto error_free_gpio_reset;
+               goto error_free_gpios;
 
        return 0;
-error_free_gpio_reset:
-       gpio_free(SG2_S0_GPIO_RESET);
-error_free_gpio_power_ctl:
-       gpio_free(SG2_S0_POWER_CTL);
-error_free_gpio_buff_ctl:
-       gpio_free(SG2_S0_BUFF_CTL);
+error_free_gpios:
+       gpio_free_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
 error_put_platform_device:
        platform_device_put(sg2_pcmcia_device);
 
@@ -162,9 +152,7 @@ error_put_platform_device:
 static void __exit sg2_pcmcia_exit(void)
 {
        platform_device_unregister(sg2_pcmcia_device);
-       gpio_free(SG2_S0_BUFF_CTL);
-       gpio_free(SG2_S0_POWER_CTL);
-       gpio_free(SG2_S0_GPIO_RESET);
+       gpio_free_array(sg2_pcmcia_gpios, ARRAY_SIZE(sg2_pcmcia_gpios));
 }
 
 fs_initcall(sg2_pcmcia_init);
index a51f207..1064b1c 100644 (file)
@@ -136,22 +136,12 @@ static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void viper_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void viper_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level viper_pcmcia_ops = {
        .owner                  = THIS_MODULE,
        .hw_init                = viper_pcmcia_hw_init,
        .hw_shutdown            = viper_pcmcia_hw_shutdown,
        .socket_state           = viper_pcmcia_socket_state,
        .configure_socket       = viper_pcmcia_configure_socket,
-       .socket_init            = viper_pcmcia_socket_init,
-       .socket_suspend         = viper_pcmcia_socket_suspend,
        .nr                     = 1,
 };
 
index 768f957..a0a9c2a 100644 (file)
@@ -186,8 +186,8 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
        struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
 
        debug(skt, 2, "initializing socket\n");
-
-       skt->ops->socket_init(skt);
+       if (skt->ops->socket_init)
+               skt->ops->socket_init(skt);
        return 0;
 }
 
@@ -207,7 +207,8 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
 
        debug(skt, 2, "suspending socket\n");
 
-       skt->ops->socket_suspend(skt);
+       if (skt->ops->socket_suspend)
+               skt->ops->socket_suspend(skt);
 
        return 0;
 }
index e57b50b..57de051 100644 (file)
@@ -235,4 +235,18 @@ config CHARGER_GPIO
          This driver can be build as a module. If so, the module will be
          called gpio-charger.
 
+config CHARGER_MAX8997
+       tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
+       depends on MFD_MAX8997 && REGULATOR_MAX8997
+       help
+         Say Y to enable support for the battery charger control sysfs and
+         platform data of MAX8997/LP3974 PMICs.
+
+config CHARGER_MAX8998
+       tristate "Maxim MAX8998/LP3974 PMIC battery charger driver"
+       depends on MFD_MAX8998 && REGULATOR_MAX8998
+       help
+         Say Y to enable support for the battery charger control sysfs and
+         platform data of MAX8998/LP3974 PMICs.
+
 endif # POWER_SUPPLY
index 009a90f..b4af13d 100644 (file)
@@ -36,3 +36,5 @@ obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
 obj-$(CONFIG_CHARGER_MAX8903)  += max8903_charger.o
 obj-$(CONFIG_CHARGER_TWL4030)  += twl4030_charger.o
 obj-$(CONFIG_CHARGER_GPIO)     += gpio-charger.o
+obj-$(CONFIG_CHARGER_MAX8997)  += max8997_charger.o
+obj-$(CONFIG_CHARGER_MAX8998)  += max8998_charger.o
index dc628cb..8a612de 100644 (file)
 #include <linux/apm-emulation.h>
 
 
-#define PSY_PROP(psy, prop, val) psy->get_property(psy, \
-                        POWER_SUPPLY_PROP_##prop, val)
+#define PSY_PROP(psy, prop, val) (psy->get_property(psy, \
+                        POWER_SUPPLY_PROP_##prop, val))
 
-#define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \
-                                                        prop, val)
+#define _MPSY_PROP(prop, val) (main_battery->get_property(main_battery, \
+                                                        prop, val))
 
 #define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val)
 
index 506585e..9c5e5be 100644 (file)
@@ -152,6 +152,10 @@ struct bq20z75_info {
        bool                            gpio_detect;
        bool                            enable_detection;
        int                             irq;
+       int                             last_state;
+       int                             poll_time;
+       struct delayed_work             work;
+       int                             ignore_changes;
 };
 
 static int bq20z75_read_word_data(struct i2c_client *client, u8 address)
@@ -279,6 +283,7 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
        int reg_offset, enum power_supply_property psp,
        union power_supply_propval *val)
 {
+       struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
        s32 ret;
 
        ret = bq20z75_read_word_data(client,
@@ -293,15 +298,24 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
        if (ret >= bq20z75_data[reg_offset].min_value &&
            ret <= bq20z75_data[reg_offset].max_value) {
                val->intval = ret;
-               if (psp == POWER_SUPPLY_PROP_STATUS) {
-                       if (ret & BATTERY_FULL_CHARGED)
-                               val->intval = POWER_SUPPLY_STATUS_FULL;
-                       else if (ret & BATTERY_FULL_DISCHARGED)
-                               val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
-                       else if (ret & BATTERY_DISCHARGING)
-                               val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
-                       else
-                               val->intval = POWER_SUPPLY_STATUS_CHARGING;
+               if (psp != POWER_SUPPLY_PROP_STATUS)
+                       return 0;
+
+               if (ret & BATTERY_FULL_CHARGED)
+                       val->intval = POWER_SUPPLY_STATUS_FULL;
+               else if (ret & BATTERY_FULL_DISCHARGED)
+                       val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+               else if (ret & BATTERY_DISCHARGING)
+                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+               else
+                       val->intval = POWER_SUPPLY_STATUS_CHARGING;
+
+               if (bq20z75_device->poll_time == 0)
+                       bq20z75_device->last_state = val->intval;
+               else if (bq20z75_device->last_state != val->intval) {
+                       cancel_delayed_work_sync(&bq20z75_device->work);
+                       power_supply_changed(&bq20z75_device->power_supply);
+                       bq20z75_device->poll_time = 0;
                }
        } else {
                if (psp == POWER_SUPPLY_PROP_STATUS)
@@ -545,6 +559,60 @@ static irqreturn_t bq20z75_irq(int irq, void *devid)
        return IRQ_HANDLED;
 }
 
+static void bq20z75_external_power_changed(struct power_supply *psy)
+{
+       struct bq20z75_info *bq20z75_device;
+
+       bq20z75_device = container_of(psy, struct bq20z75_info, power_supply);
+
+       if (bq20z75_device->ignore_changes > 0) {
+               bq20z75_device->ignore_changes--;
+               return;
+       }
+
+       /* cancel outstanding work */
+       cancel_delayed_work_sync(&bq20z75_device->work);
+
+       schedule_delayed_work(&bq20z75_device->work, HZ);
+       bq20z75_device->poll_time = bq20z75_device->pdata->poll_retry_count;
+}
+
+static void bq20z75_delayed_work(struct work_struct *work)
+{
+       struct bq20z75_info *bq20z75_device;
+       s32 ret;
+
+       bq20z75_device = container_of(work, struct bq20z75_info, work.work);
+
+       ret = bq20z75_read_word_data(bq20z75_device->client,
+                                    bq20z75_data[REG_STATUS].addr);
+       /* if the read failed, give up on this work */
+       if (ret < 0) {
+               bq20z75_device->poll_time = 0;
+               return;
+       }
+
+       if (ret & BATTERY_FULL_CHARGED)
+               ret = POWER_SUPPLY_STATUS_FULL;
+       else if (ret & BATTERY_FULL_DISCHARGED)
+               ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
+       else if (ret & BATTERY_DISCHARGING)
+               ret = POWER_SUPPLY_STATUS_DISCHARGING;
+       else
+               ret = POWER_SUPPLY_STATUS_CHARGING;
+
+       if (bq20z75_device->last_state != ret) {
+               bq20z75_device->poll_time = 0;
+               power_supply_changed(&bq20z75_device->power_supply);
+               return;
+       }
+       if (bq20z75_device->poll_time > 0) {
+               schedule_delayed_work(&bq20z75_device->work, HZ);
+               bq20z75_device->poll_time--;
+               return;
+       }
+}
+
 static int __devinit bq20z75_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
 {
@@ -566,6 +634,13 @@ static int __devinit bq20z75_probe(struct i2c_client *client,
        bq20z75_device->power_supply.num_properties =
                ARRAY_SIZE(bq20z75_properties);
        bq20z75_device->power_supply.get_property = bq20z75_get_property;
+       /* ignore first notification of external change, it is generated
+        * from the power_supply_register call back
+        */
+       bq20z75_device->ignore_changes = 1;
+       bq20z75_device->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
+       bq20z75_device->power_supply.external_power_changed =
+               bq20z75_external_power_changed;
 
        if (pdata) {
                bq20z75_device->gpio_detect =
@@ -625,6 +700,10 @@ skip_gpio:
        dev_info(&client->dev,
                "%s: battery gas gauge device registered\n", client->name);
 
+       INIT_DELAYED_WORK(&bq20z75_device->work, bq20z75_delayed_work);
+
+       bq20z75_device->enable_detection = true;
+
        return 0;
 
 exit_psupply:
@@ -648,6 +727,9 @@ static int __devexit bq20z75_remove(struct i2c_client *client)
                gpio_free(bq20z75_device->pdata->battery_detect);
 
        power_supply_unregister(&bq20z75_device->power_supply);
+
+       cancel_delayed_work_sync(&bq20z75_device->work);
+
        kfree(bq20z75_device);
        bq20z75_device = NULL;
 
@@ -661,6 +743,9 @@ static int bq20z75_suspend(struct i2c_client *client,
        struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
        s32 ret;
 
+       if (bq20z75_device->poll_time > 0)
+               cancel_delayed_work_sync(&bq20z75_device->work);
+
        /* write to manufacturer access with sleep command */
        ret = bq20z75_write_word_data(client,
                bq20z75_data[REG_MANUFACTURER_DATA].addr,
index 718f2c5..a64b885 100644 (file)
@@ -127,7 +127,7 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev)
                ret = request_any_context_irq(irq, gpio_charger_irq,
                                IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                                dev_name(&pdev->dev), charger);
-               if (ret)
+               if (ret < 0)
                        dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret);
                else
                        gpio_charger->irq = irq;
index c5c8805..98bfab3 100644 (file)
 #include <linux/power_supply.h>
 #include <linux/power/max17042_battery.h>
 
-enum max17042_register {
-       MAX17042_STATUS         = 0x00,
-       MAX17042_VALRT_Th       = 0x01,
-       MAX17042_TALRT_Th       = 0x02,
-       MAX17042_SALRT_Th       = 0x03,
-       MAX17042_AtRate         = 0x04,
-       MAX17042_RepCap         = 0x05,
-       MAX17042_RepSOC         = 0x06,
-       MAX17042_Age            = 0x07,
-       MAX17042_TEMP           = 0x08,
-       MAX17042_VCELL          = 0x09,
-       MAX17042_Current        = 0x0A,
-       MAX17042_AvgCurrent     = 0x0B,
-       MAX17042_Qresidual      = 0x0C,
-       MAX17042_SOC            = 0x0D,
-       MAX17042_AvSOC          = 0x0E,
-       MAX17042_RemCap         = 0x0F,
-       MAX17402_FullCAP        = 0x10,
-       MAX17042_TTE            = 0x11,
-       MAX17042_V_empty        = 0x12,
-
-       MAX17042_RSLOW          = 0x14,
-
-       MAX17042_AvgTA          = 0x16,
-       MAX17042_Cycles         = 0x17,
-       MAX17042_DesignCap      = 0x18,
-       MAX17042_AvgVCELL       = 0x19,
-       MAX17042_MinMaxTemp     = 0x1A,
-       MAX17042_MinMaxVolt     = 0x1B,
-       MAX17042_MinMaxCurr     = 0x1C,
-       MAX17042_CONFIG         = 0x1D,
-       MAX17042_ICHGTerm       = 0x1E,
-       MAX17042_AvCap          = 0x1F,
-       MAX17042_ManName        = 0x20,
-       MAX17042_DevName        = 0x21,
-       MAX17042_DevChem        = 0x22,
-
-       MAX17042_TempNom        = 0x24,
-       MAX17042_TempCold       = 0x25,
-       MAX17042_TempHot        = 0x26,
-       MAX17042_AIN            = 0x27,
-       MAX17042_LearnCFG       = 0x28,
-       MAX17042_SHFTCFG        = 0x29,
-       MAX17042_RelaxCFG       = 0x2A,
-       MAX17042_MiscCFG        = 0x2B,
-       MAX17042_TGAIN          = 0x2C,
-       MAx17042_TOFF           = 0x2D,
-       MAX17042_CGAIN          = 0x2E,
-       MAX17042_COFF           = 0x2F,
-
-       MAX17042_Q_empty        = 0x33,
-       MAX17042_T_empty        = 0x34,
-
-       MAX17042_RCOMP0         = 0x38,
-       MAX17042_TempCo         = 0x39,
-       MAX17042_Rx             = 0x3A,
-       MAX17042_T_empty0       = 0x3B,
-       MAX17042_TaskPeriod     = 0x3C,
-       MAX17042_FSTAT          = 0x3D,
-
-       MAX17042_SHDNTIMER      = 0x3F,
-
-       MAX17042_VFRemCap       = 0x4A,
-
-       MAX17042_QH             = 0x4D,
-       MAX17042_QL             = 0x4E,
-};
-
 struct max17042_chip {
        struct i2c_client *client;
        struct power_supply battery;
@@ -123,10 +55,27 @@ static int max17042_read_reg(struct i2c_client *client, u8 reg)
        return ret;
 }
 
+static void max17042_set_reg(struct i2c_client *client,
+                            struct max17042_reg_data *data, int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++)
+               max17042_write_reg(client, data[i].addr, data[i].data);
+}
+
 static enum power_supply_property max17042_battery_props[] = {
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_CYCLE_COUNT,
+       POWER_SUPPLY_PROP_VOLTAGE_MAX,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
        POWER_SUPPLY_PROP_VOLTAGE_AVG,
        POWER_SUPPLY_PROP_CAPACITY,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
+       POWER_SUPPLY_PROP_TEMP,
+       POWER_SUPPLY_PROP_CURRENT_NOW,
+       POWER_SUPPLY_PROP_CURRENT_AVG,
 };
 
 static int max17042_get_property(struct power_supply *psy,
@@ -137,6 +86,30 @@ static int max17042_get_property(struct power_supply *psy,
                                struct max17042_chip, battery);
 
        switch (psp) {
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = max17042_read_reg(chip->client,
+                               MAX17042_STATUS);
+               if (val->intval & MAX17042_STATUS_BattAbsent)
+                       val->intval = 0;
+               else
+                       val->intval = 1;
+               break;
+       case POWER_SUPPLY_PROP_CYCLE_COUNT:
+               val->intval = max17042_read_reg(chip->client,
+                               MAX17042_Cycles);
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+               val->intval = max17042_read_reg(chip->client,
+                               MAX17042_MinMaxVolt);
+               val->intval >>= 8;
+               val->intval *= 20000; /* Units of LSB = 20mV */
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+               val->intval = max17042_read_reg(chip->client,
+                               MAX17042_V_empty);
+               val->intval >>= 7;
+               val->intval *= 10000; /* Units of LSB = 10mV */
+               break;
        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
                val->intval = max17042_read_reg(chip->client,
                                MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */
@@ -149,6 +122,57 @@ static int max17042_get_property(struct power_supply *psy,
                val->intval = max17042_read_reg(chip->client,
                                MAX17042_SOC) / 256;
                break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+               val->intval = max17042_read_reg(chip->client,
+                               MAX17042_RepSOC);
+               if ((val->intval / 256) >= MAX17042_BATTERY_FULL)
+                       val->intval = 1;
+               else if (val->intval >= 0)
+                       val->intval = 0;
+               break;
+       case POWER_SUPPLY_PROP_TEMP:
+               val->intval = max17042_read_reg(chip->client,
+                               MAX17042_TEMP);
+               /* The value is signed. */
+               if (val->intval & 0x8000) {
+                       val->intval = (0x7fff & ~val->intval) + 1;
+                       val->intval *= -1;
+               }
+               /* The value is converted into deci-centigrade scale */
+               /* Units of LSB = 1 / 256 degree Celsius */
+               val->intval = val->intval * 10 / 256;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+               if (chip->pdata->enable_current_sense) {
+                       val->intval = max17042_read_reg(chip->client,
+                                       MAX17042_Current);
+                       if (val->intval & 0x8000) {
+                               /* Negative */
+                               val->intval = ~val->intval & 0x7fff;
+                               val->intval++;
+                               val->intval *= -1;
+                       }
+                       val->intval >>= 4;
+                       val->intval *= 1000000 * 25 / chip->pdata->r_sns;
+               } else {
+                       return -EINVAL;
+               }
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_AVG:
+               if (chip->pdata->enable_current_sense) {
+                       val->intval = max17042_read_reg(chip->client,
+                                       MAX17042_AvgCurrent);
+                       if (val->intval & 0x8000) {
+                               /* Negative */
+                               val->intval = ~val->intval & 0x7fff;
+                               val->intval++;
+                               val->intval *= -1;
+                       }
+                       val->intval *= 1562500 / chip->pdata->r_sns;
+               } else {
+                       return -EINVAL;
+               }
+               break;
        default:
                return -EINVAL;
        }
@@ -180,18 +204,30 @@ static int __devinit max17042_probe(struct i2c_client *client,
        chip->battery.properties        = max17042_battery_props;
        chip->battery.num_properties    = ARRAY_SIZE(max17042_battery_props);
 
+       /* When current is not measured,
+        * CURRENT_NOW and CURRENT_AVG properties should be invisible. */
+       if (!chip->pdata->enable_current_sense)
+               chip->battery.num_properties -= 2;
+
        ret = power_supply_register(&client->dev, &chip->battery);
        if (ret) {
                dev_err(&client->dev, "failed: power supply register\n");
-               i2c_set_clientdata(client, NULL);
                kfree(chip);
                return ret;
        }
 
+       /* Initialize registers according to values from the platform data */
+       if (chip->pdata->init_data)
+               max17042_set_reg(client, chip->pdata->init_data,
+                                chip->pdata->num_init_data);
+
        if (!chip->pdata->enable_current_sense) {
                max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
                max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
                max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
+       } else {
+               if (chip->pdata->r_sns == 0)
+                       chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
        }
 
        return 0;
@@ -202,7 +238,6 @@ static int __devexit max17042_remove(struct i2c_client *client)
        struct max17042_chip *chip = i2c_get_clientdata(client);
 
        power_supply_unregister(&chip->battery);
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index 33ff0e3..a9b0209 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/power/max8903_charger.h>
 
 struct max8903_data {
-       struct max8903_pdata *pdata;
+       struct max8903_pdata pdata;
        struct device *dev;
        struct power_supply psy;
        bool fault;
@@ -52,8 +52,8 @@ static int max8903_get_property(struct power_supply *psy,
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
                val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
-               if (data->pdata->chg) {
-                       if (gpio_get_value(data->pdata->chg) == 0)
+               if (data->pdata.chg) {
+                       if (gpio_get_value(data->pdata.chg) == 0)
                                val->intval = POWER_SUPPLY_STATUS_CHARGING;
                        else if (data->usb_in || data->ta_in)
                                val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
@@ -80,7 +80,7 @@ static int max8903_get_property(struct power_supply *psy,
 static irqreturn_t max8903_dcin(int irq, void *_data)
 {
        struct max8903_data *data = _data;
-       struct max8903_pdata *pdata = data->pdata;
+       struct max8903_pdata *pdata = &data->pdata;
        bool ta_in;
        enum power_supply_type old_type;
 
@@ -121,7 +121,7 @@ static irqreturn_t max8903_dcin(int irq, void *_data)
 static irqreturn_t max8903_usbin(int irq, void *_data)
 {
        struct max8903_data *data = _data;
-       struct max8903_pdata *pdata = data->pdata;
+       struct max8903_pdata *pdata = &data->pdata;
        bool usb_in;
        enum power_supply_type old_type;
 
@@ -160,7 +160,7 @@ static irqreturn_t max8903_usbin(int irq, void *_data)
 static irqreturn_t max8903_fault(int irq, void *_data)
 {
        struct max8903_data *data = _data;
-       struct max8903_pdata *pdata = data->pdata;
+       struct max8903_pdata *pdata = &data->pdata;
        bool fault;
 
        fault = gpio_get_value(pdata->flt) ? false : true;
@@ -193,7 +193,7 @@ static __devinit int max8903_probe(struct platform_device *pdev)
                dev_err(dev, "Cannot allocate memory.\n");
                return -ENOMEM;
        }
-       data->pdata = pdata;
+       memcpy(&data->pdata, pdata, sizeof(struct max8903_pdata));
        data->dev = dev;
        platform_set_drvdata(pdev, data);
 
@@ -349,7 +349,7 @@ static __devexit int max8903_remove(struct platform_device *pdev)
        struct max8903_data *data = platform_get_drvdata(pdev);
 
        if (data) {
-               struct max8903_pdata *pdata = data->pdata;
+               struct max8903_pdata *pdata = &data->pdata;
 
                if (pdata->flt)
                        free_irq(gpio_to_irq(pdata->flt), data);
diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c
new file mode 100644 (file)
index 0000000..7106b49
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * max8997_charger.c - Power supply consumer driver for the Maxim 8997/8966
+ *
+ *  Copyright (C) 2011 Samsung Electronics
+ *  MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+
+struct charger_data {
+       struct device *dev;
+       struct max8997_dev *iodev;
+       struct power_supply battery;
+};
+
+static enum power_supply_property max8997_battery_props[] = {
+       POWER_SUPPLY_PROP_STATUS, /* "FULL" or "NOT FULL" only. */
+       POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */
+       POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */
+};
+
+/* Note that the charger control is done by a current regulator "CHARGER" */
+static int max8997_battery_get_property(struct power_supply *psy,
+               enum power_supply_property psp,
+               union power_supply_propval *val)
+{
+       struct charger_data *charger = container_of(psy,
+                       struct charger_data, battery);
+       struct i2c_client *i2c = charger->iodev->i2c;
+       int ret;
+       u8 reg;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               val->intval = 0;
+               ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, &reg);
+               if (ret)
+                       return ret;
+               if ((reg & (1 << 0)) == 0x1)
+                       val->intval = POWER_SUPPLY_STATUS_FULL;
+
+               break;
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = 0;
+               ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, &reg);
+               if (ret)
+                       return ret;
+               if ((reg & (1 << 2)) == 0x0)
+                       val->intval = 1;
+
+               break;
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = 0;
+               ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, &reg);
+               if (ret)
+                       return ret;
+               /* DCINOK */
+               if (reg & (1 << 1))
+                       val->intval = 1;
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static __devinit int max8997_battery_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct charger_data *charger;
+       struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+       struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+
+       if (!pdata)
+               return -EINVAL;
+
+       if (pdata->eoc_mA) {
+               u8 val = (pdata->eoc_mA - 50) / 10;
+               if (val < 0)
+                       val = 0;
+               if (val > 0xf)
+                       val = 0xf;
+
+               ret = max8997_update_reg(iodev->i2c,
+                               MAX8997_REG_MBCCTRL5, val, 0xf);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "Cannot use i2c bus.\n");
+                       return ret;
+               }
+       }
+
+       switch (pdata->timeout) {
+       case 5:
+               ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
+                               0x2 << 4, 0x7 << 4);
+               break;
+       case 6:
+               ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
+                               0x3 << 4, 0x7 << 4);
+               break;
+       case 7:
+               ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
+                               0x4 << 4, 0x7 << 4);
+               break;
+       case 0:
+               ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
+                               0x7 << 4, 0x7 << 4);
+               break;
+       default:
+               dev_err(&pdev->dev, "incorrect timeout value (%d)\n",
+                               pdata->timeout);
+               return -EINVAL;
+       }
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Cannot use i2c bus.\n");
+               return ret;
+       }
+
+       charger = kzalloc(sizeof(struct charger_data), GFP_KERNEL);
+       if (charger == NULL) {
+               dev_err(&pdev->dev, "Cannot allocate memory.\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(pdev, charger);
+
+       charger->battery.name = "max8997_pmic";
+       charger->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+       charger->battery.get_property = max8997_battery_get_property;
+       charger->battery.properties = max8997_battery_props;
+       charger->battery.num_properties = ARRAY_SIZE(max8997_battery_props);
+
+       charger->dev = &pdev->dev;
+       charger->iodev = iodev;
+
+       ret = power_supply_register(&pdev->dev, &charger->battery);
+       if (ret) {
+               dev_err(&pdev->dev, "failed: power supply register\n");
+               goto err;
+       }
+
+       return 0;
+err:
+       kfree(charger);
+       return ret;
+}
+
+static int __devexit max8997_battery_remove(struct platform_device *pdev)
+{
+       struct charger_data *charger = platform_get_drvdata(pdev);
+
+       power_supply_unregister(&charger->battery);
+       kfree(charger);
+       return 0;
+}
+
+static const struct platform_device_id max8997_battery_id[] = {
+       { "max8997-battery", 0 },
+};
+
+static struct platform_driver max8997_battery_driver = {
+       .driver = {
+               .name = "max8997-battery",
+               .owner = THIS_MODULE,
+       },
+       .probe = max8997_battery_probe,
+       .remove = __devexit_p(max8997_battery_remove),
+       .id_table = max8997_battery_id,
+};
+
+static int __init max8997_battery_init(void)
+{
+       return platform_driver_register(&max8997_battery_driver);
+}
+subsys_initcall(max8997_battery_init);
+
+static void __exit max8997_battery_cleanup(void)
+{
+       platform_driver_unregister(&max8997_battery_driver);
+}
+module_exit(max8997_battery_cleanup);
+
+MODULE_DESCRIPTION("MAXIM 8997/8966 battery control driver");
+MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c
new file mode 100644 (file)
index 0000000..cc21fa2
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * max8998_charger.c - Power supply consumer driver for the Maxim 8998/LP3974
+ *
+ *  Copyright (C) 2009-2010 Samsung Electronics
+ *  MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/max8998.h>
+#include <linux/mfd/max8998-private.h>
+
+struct max8998_battery_data {
+       struct device *dev;
+       struct max8998_dev *iodev;
+       struct power_supply battery;
+};
+
+static enum power_supply_property max8998_battery_props[] = {
+       POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */
+       POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */
+};
+
+/* Note that the charger control is done by a current regulator "CHARGER" */
+static int max8998_battery_get_property(struct power_supply *psy,
+               enum power_supply_property psp,
+               union power_supply_propval *val)
+{
+       struct max8998_battery_data *max8998 = container_of(psy,
+                       struct max8998_battery_data, battery);
+       struct i2c_client *i2c = max8998->iodev->i2c;
+       int ret;
+       u8 reg;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_PRESENT:
+               ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, &reg);
+               if (ret)
+                       return ret;
+               if (reg & (1 << 4))
+                       val->intval = 0;
+               else
+                       val->intval = 1;
+               break;
+       case POWER_SUPPLY_PROP_ONLINE:
+               ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, &reg);
+               if (ret)
+                       return ret;
+               if (reg & (1 << 3))
+                       val->intval = 0;
+               else
+                       val->intval = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static __devinit int max8998_battery_probe(struct platform_device *pdev)
+{
+       struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+       struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
+       struct max8998_battery_data *max8998;
+       struct i2c_client *i2c;
+       int ret = 0;
+
+       if (!pdata) {
+               dev_err(pdev->dev.parent, "No platform init data supplied\n");
+               return -ENODEV;
+       }
+
+       max8998 = kzalloc(sizeof(struct max8998_battery_data), GFP_KERNEL);
+       if (!max8998)
+               return -ENOMEM;
+
+       max8998->dev = &pdev->dev;
+       max8998->iodev = iodev;
+       platform_set_drvdata(pdev, max8998);
+       i2c = max8998->iodev->i2c;
+
+       /* Setup "End of Charge" */
+       /* If EOC value equals 0,
+        * remain value set from bootloader or default value */
+       if (pdata->eoc >= 10 && pdata->eoc <= 45) {
+               max8998_update_reg(i2c, MAX8998_REG_CHGR1,
+                               (pdata->eoc / 5 - 2) << 5, 0x7 << 5);
+       } else if (pdata->eoc == 0) {
+               dev_dbg(max8998->dev,
+                       "EOC value not set: leave it unchanged.\n");
+       } else {
+               dev_err(max8998->dev, "Invalid EOC value\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Setup Charge Restart Level */
+       switch (pdata->restart) {
+       case 100:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x1 << 3, 0x3 << 3);
+               break;
+       case 150:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x0 << 3, 0x3 << 3);
+               break;
+       case 200:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x2 << 3, 0x3 << 3);
+               break;
+       case -1:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x3 << 3, 0x3 << 3);
+               break;
+       case 0:
+               dev_dbg(max8998->dev,
+                       "Restart Level not set: leave it unchanged.\n");
+               break;
+       default:
+               dev_err(max8998->dev, "Invalid Restart Level\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Setup Charge Full Timeout */
+       switch (pdata->timeout) {
+       case 5:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x0 << 4, 0x3 << 4);
+               break;
+       case 6:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x1 << 4, 0x3 << 4);
+               break;
+       case 7:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x2 << 4, 0x3 << 4);
+               break;
+       case -1:
+               max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x3 << 4, 0x3 << 4);
+               break;
+       case 0:
+               dev_dbg(max8998->dev,
+                       "Full Timeout not set: leave it unchanged.\n");
+       default:
+               dev_err(max8998->dev, "Invalid Full Timeout value\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       max8998->battery.name = "max8998_pmic";
+       max8998->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+       max8998->battery.get_property = max8998_battery_get_property;
+       max8998->battery.properties = max8998_battery_props;
+       max8998->battery.num_properties = ARRAY_SIZE(max8998_battery_props);
+
+       ret = power_supply_register(max8998->dev, &max8998->battery);
+       if (ret) {
+               dev_err(max8998->dev, "failed: power supply register\n");
+               goto err;
+       }
+
+       return 0;
+err:
+       kfree(max8998);
+       return ret;
+}
+
+static int __devexit max8998_battery_remove(struct platform_device *pdev)
+{
+       struct max8998_battery_data *max8998 = platform_get_drvdata(pdev);
+
+       power_supply_unregister(&max8998->battery);
+       kfree(max8998);
+
+       return 0;
+}
+
+static const struct platform_device_id max8998_battery_id[] = {
+       { "max8998-battery", TYPE_MAX8998 },
+};
+
+static struct platform_driver max8998_battery_driver = {
+       .driver = {
+               .name = "max8998-battery",
+               .owner = THIS_MODULE,
+       },
+       .probe = max8998_battery_probe,
+       .remove = __devexit_p(max8998_battery_remove),
+       .id_table = max8998_battery_id,
+};
+
+static int __init max8998_battery_init(void)
+{
+       return platform_driver_register(&max8998_battery_driver);
+}
+module_init(max8998_battery_init);
+
+static void __exit max8998_battery_cleanup(void)
+{
+       platform_driver_unregister(&max8998_battery_driver);
+}
+module_exit(max8998_battery_cleanup);
+
+MODULE_DESCRIPTION("MAXIM 8998 battery control driver");
+MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:max8998-battery");
index d36c289..a675e31 100644 (file)
@@ -266,7 +266,7 @@ static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int __init s3c_adc_bat_probe(struct platform_device *pdev)
+static int __devinit s3c_adc_bat_probe(struct platform_device *pdev)
 {
        struct s3c_adc_client   *client;
        struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data;
index 92c16e1..54b9198 100644 (file)
@@ -62,7 +62,7 @@
 #define TWL4030_MSTATEC_COMPLETE4      0x0e
 
 static bool allow_usb;
-module_param(allow_usb, bool, 1);
+module_param(allow_usb, bool, 0644);
 MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current");
 
 struct twl4030_bci {
@@ -425,7 +425,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
 {
        struct twl4030_bci *bci;
        int ret;
-       int reg;
+       u32 reg;
 
        bci = kzalloc(sizeof(*bci), GFP_KERNEL);
        if (bci == NULL)
@@ -486,7 +486,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
        }
 
        /* Enable interrupts now. */
-       reg = ~(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 |
+       reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 |
                TWL4030_TBATOR1 | TWL4030_BATSTS);
        ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
                               TWL4030_INTERRUPTS_BCIIMR1A);
@@ -495,7 +495,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
                goto fail_unmask_interrupts;
        }
 
-       reg = ~(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
+       reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
        ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
                               TWL4030_INTERRUPTS_BCIIMR2A);
        if (ret < 0)
@@ -572,7 +572,7 @@ static void __exit twl4030_bci_exit(void)
 }
 module_exit(twl4030_bci_exit);
 
-MODULE_AUTHOR("Gražydas Ignotas");
+MODULE_AUTHOR("Gražvydas Ignotas");
 MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:twl4030_bci");
index 0fd130d..e648cbe 100644 (file)
@@ -22,6 +22,7 @@
 struct wm831x_backup {
        struct wm831x *wm831x;
        struct power_supply backup;
+       char name[20];
 };
 
 static int wm831x_backup_read_voltage(struct wm831x *wm831x,
@@ -163,6 +164,7 @@ static enum power_supply_property wm831x_backup_props[] = {
 static __devinit int wm831x_backup_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+       struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
        struct wm831x_backup *devdata;
        struct power_supply *backup;
        int ret;
@@ -182,7 +184,14 @@ static __devinit int wm831x_backup_probe(struct platform_device *pdev)
         */
        wm831x_config_backup(wm831x);
 
-       backup->name = "wm831x-backup";
+       if (wm831x_pdata && wm831x_pdata->wm831x_num)
+               snprintf(devdata->name, sizeof(devdata->name),
+                        "wm831x-backup.%d", wm831x_pdata->wm831x_num);
+       else
+               snprintf(devdata->name, sizeof(devdata->name),
+                        "wm831x-backup");
+
+       backup->name = devdata->name;
        backup->type = POWER_SUPPLY_TYPE_BATTERY;
        backup->properties = wm831x_backup_props;
        backup->num_properties = ARRAY_SIZE(wm831x_backup_props);
@@ -203,6 +212,7 @@ static __devexit int wm831x_backup_remove(struct platform_device *pdev)
        struct wm831x_backup *devdata = platform_get_drvdata(pdev);
 
        power_supply_unregister(&devdata->backup);
+       kfree(devdata->backup.name);
        kfree(devdata);
 
        return 0;
index ddf8cf5..6cc2ca6 100644 (file)
@@ -24,6 +24,9 @@ struct wm831x_power {
        struct power_supply wall;
        struct power_supply usb;
        struct power_supply battery;
+       char wall_name[20];
+       char usb_name[20];
+       char battery_name[20];
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -486,6 +489,7 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data)
 static __devinit int wm831x_power_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+       struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
        struct wm831x_power *power;
        struct power_supply *usb;
        struct power_supply *battery;
@@ -503,12 +507,28 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
        battery = &power->battery;
        wall = &power->wall;
 
+       if (wm831x_pdata && wm831x_pdata->wm831x_num) {
+               snprintf(power->wall_name, sizeof(power->wall_name),
+                        "wm831x-wall.%d", wm831x_pdata->wm831x_num);
+               snprintf(power->battery_name, sizeof(power->wall_name),
+                        "wm831x-battery.%d", wm831x_pdata->wm831x_num);
+               snprintf(power->usb_name, sizeof(power->wall_name),
+                        "wm831x-usb.%d", wm831x_pdata->wm831x_num);
+       } else {
+               snprintf(power->wall_name, sizeof(power->wall_name),
+                        "wm831x-wall");
+               snprintf(power->battery_name, sizeof(power->wall_name),
+                        "wm831x-battery");
+               snprintf(power->usb_name, sizeof(power->wall_name),
+                        "wm831x-usb");
+       }
+
        /* We ignore configuration failures since we can still read back
         * the status without enabling the charger.
         */
        wm831x_config_battery(wm831x);
 
-       wall->name = "wm831x-wall";
+       wall->name = power->wall_name;
        wall->type = POWER_SUPPLY_TYPE_MAINS;
        wall->properties = wm831x_wall_props;
        wall->num_properties = ARRAY_SIZE(wm831x_wall_props);
@@ -517,7 +537,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
        if (ret)
                goto err_kmalloc;
 
-       battery->name = "wm831x-battery";
+       battery->name = power->battery_name;
        battery->properties = wm831x_bat_props;
        battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
        battery->get_property = wm831x_bat_get_prop;
@@ -526,7 +546,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
        if (ret)
                goto err_wall;
 
-       usb->name = "wm831x-usb",
+       usb->name = power->usb_name,
        usb->type = POWER_SUPPLY_TYPE_USB;
        usb->properties = wm831x_usb_props;
        usb->num_properties = ARRAY_SIZE(wm831x_usb_props);
index 60931d0..0bbd13d 100644 (file)
@@ -107,11 +107,16 @@ struct max8997_platform_data {
        unsigned int buck5_voltage[8];
        bool buck5_gpiodvs;
 
+       /* ---- Charger control ---- */
+       /* eoc stands for 'end of charge' */
+       int eoc_mA; /* 50 ~ 200mA by 10mA step */
+       /* charge Full Timeout */
+       int timeout; /* 0 (no timeout), 5, 6, 7 hours */
+
        /* MUIC: Not implemented */
        /* HAPTIC: Not implemented */
        /* RTC: Not implemented */
        /* Flash: Not implemented */
-       /* Charger control: Not implemented */
 };
 
 #endif /* __LINUX_MFD_MAX8998_H */
index 61daa16..f4f0dfa 100644 (file)
@@ -87,6 +87,15 @@ struct max8998_regulator_data {
  * @wakeup: Allow to wake up from suspend
  * @rtc_delay: LP3974 RTC chip bug that requires delay after a register
  * write before reading it.
+ * @eoc: End of Charge Level in percent: 10% ~ 45% by 5% step
+ *   If it equals 0, leave it unchanged.
+ *   Otherwise, it is a invalid value.
+ * @restart: Restart Level in mV: 100, 150, 200, and -1 for disable.
+ *   If it equals 0, leave it unchanged.
+ *   Otherwise, it is a invalid value.
+ * @timeout: Full Timeout in hours: 5, 6, 7, and -1 for disable.
+ *   If it equals 0, leave it unchanged.
+ *   Otherwise, leave it unchanged.
  */
 struct max8998_platform_data {
        struct max8998_regulator_data   *regulators;
@@ -107,6 +116,9 @@ struct max8998_platform_data {
        int                             buck2_default_idx;
        bool                            wakeup;
        bool                            rtc_delay;
+       int                             eoc;
+       int                             restart;
+       int                             timeout;
 };
 
 #endif /*  __LINUX_MFD_MAX8998_H */
index b0843b6..1398eb0 100644 (file)
  * @battery_detect:            GPIO which is used to detect battery presence
  * @battery_detect_present:    gpio state when battery is present (0 / 1)
  * @i2c_retry_count:           # of times to retry on i2c IO failure
+ * @poll_retry_count:          # of times to retry looking for new status after
+ *                             external change notification
  */
 struct bq20z75_platform_data {
        int battery_detect;
        int battery_detect_present;
        int i2c_retry_count;
+       int poll_retry_count;
 };
 
 #endif
index 7995deb..fe99211 100644 (file)
 #ifndef __MAX17042_BATTERY_H_
 #define __MAX17042_BATTERY_H_
 
+#define MAX17042_STATUS_BattAbsent     (1 << 3)
+#define MAX17042_BATTERY_FULL  (100)
+#define MAX17042_DEFAULT_SNS_RESISTOR  (10000)
+
+enum max17042_register {
+       MAX17042_STATUS         = 0x00,
+       MAX17042_VALRT_Th       = 0x01,
+       MAX17042_TALRT_Th       = 0x02,
+       MAX17042_SALRT_Th       = 0x03,
+       MAX17042_AtRate         = 0x04,
+       MAX17042_RepCap         = 0x05,
+       MAX17042_RepSOC         = 0x06,
+       MAX17042_Age            = 0x07,
+       MAX17042_TEMP           = 0x08,
+       MAX17042_VCELL          = 0x09,
+       MAX17042_Current        = 0x0A,
+       MAX17042_AvgCurrent     = 0x0B,
+       MAX17042_Qresidual      = 0x0C,
+       MAX17042_SOC            = 0x0D,
+       MAX17042_AvSOC          = 0x0E,
+       MAX17042_RemCap         = 0x0F,
+       MAX17402_FullCAP        = 0x10,
+       MAX17042_TTE            = 0x11,
+       MAX17042_V_empty        = 0x12,
+
+       MAX17042_RSLOW          = 0x14,
+
+       MAX17042_AvgTA          = 0x16,
+       MAX17042_Cycles         = 0x17,
+       MAX17042_DesignCap      = 0x18,
+       MAX17042_AvgVCELL       = 0x19,
+       MAX17042_MinMaxTemp     = 0x1A,
+       MAX17042_MinMaxVolt     = 0x1B,
+       MAX17042_MinMaxCurr     = 0x1C,
+       MAX17042_CONFIG         = 0x1D,
+       MAX17042_ICHGTerm       = 0x1E,
+       MAX17042_AvCap          = 0x1F,
+       MAX17042_ManName        = 0x20,
+       MAX17042_DevName        = 0x21,
+       MAX17042_DevChem        = 0x22,
+
+       MAX17042_TempNom        = 0x24,
+       MAX17042_TempCold       = 0x25,
+       MAX17042_TempHot        = 0x26,
+       MAX17042_AIN            = 0x27,
+       MAX17042_LearnCFG       = 0x28,
+       MAX17042_SHFTCFG        = 0x29,
+       MAX17042_RelaxCFG       = 0x2A,
+       MAX17042_MiscCFG        = 0x2B,
+       MAX17042_TGAIN          = 0x2C,
+       MAx17042_TOFF           = 0x2D,
+       MAX17042_CGAIN          = 0x2E,
+       MAX17042_COFF           = 0x2F,
+
+       MAX17042_Q_empty        = 0x33,
+       MAX17042_T_empty        = 0x34,
+
+       MAX17042_RCOMP0         = 0x38,
+       MAX17042_TempCo         = 0x39,
+       MAX17042_Rx             = 0x3A,
+       MAX17042_T_empty0       = 0x3B,
+       MAX17042_TaskPeriod     = 0x3C,
+       MAX17042_FSTAT          = 0x3D,
+
+       MAX17042_SHDNTIMER      = 0x3F,
+
+       MAX17042_VFRemCap       = 0x4A,
+
+       MAX17042_QH             = 0x4D,
+       MAX17042_QL             = 0x4E,
+};
+
+/*
+ * used for setting a register to a desired value
+ * addr : address for a register
+ * data : setting value for the register
+ */
+struct max17042_reg_data {
+       u8 addr;
+       u16 data;
+};
+
 struct max17042_platform_data {
+       struct max17042_reg_data *init_data;
+       int num_init_data; /* Number of enties in init_data array */
        bool enable_current_sense;
+
+       /*
+        * R_sns in micro-ohms.
+        * default 10000 (if r_sns = 0) as it is the recommended value by
+        * the datasheet although it can be changed by board designers.
+        */
+       unsigned int r_sns;
 };
 
 #endif /* __MAX17042_BATTERY_H_ */
index 63e5b8f..00dbfac 100644 (file)
        .prod_id = { (v1), NULL, NULL, NULL }, \
        .prod_id_hash = { (vh1), 0, 0, 0 }, }
 
+#define PCMCIA_DEVICE_MANF_CARD_PROD_ID3(manf, card, v3, vh3) { \
+       .match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
+                       PCMCIA_DEV_ID_MATCH_CARD_ID| \
+                       PCMCIA_DEV_ID_MATCH_PROD_ID3, \
+       .manf_id = (manf), \
+       .card_id = (card), \
+       .prod_id = { NULL, NULL, (v3), NULL }, \
+       .prod_id_hash = { 0, 0, (vh3), 0 }, }
+
 
 /* multi-function devices */
 
diff --git a/tools/power/cpupower/.gitignore b/tools/power/cpupower/.gitignore
new file mode 100644 (file)
index 0000000..8a83dd2
--- /dev/null
@@ -0,0 +1,22 @@
+.libs
+libcpupower.so
+libcpupower.so.0
+libcpupower.so.0.0.0
+build/ccdv
+cpufreq-info
+cpufreq-set
+cpufreq-aperf
+lib/.libs
+lib/cpufreq.lo
+lib/cpufreq.o
+lib/proc.lo
+lib/proc.o
+lib/sysfs.lo
+lib/sysfs.o
+po/cpupowerutils.pot
+po/*.gmo
+utils/cpufreq-info.o
+utils/cpufreq-set.o
+utils/cpufreq-aperf.o
+cpupower
+bench/cpufreq-bench
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
new file mode 100644 (file)
index 0000000..94c2cf0
--- /dev/null
@@ -0,0 +1,279 @@
+# Makefile for cpupower
+#
+# Copyright (C) 2005,2006 Dominik Brodowski <linux@dominikbrodowski.net>
+#
+# Based largely on the Makefile for udev by:
+#
+# Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+# --- CONFIGURATION BEGIN ---
+
+# Set the following to `true' to make a unstripped, unoptimized
+# binary. Leave this set to `false' for production use.
+DEBUG ?=       false
+
+# make the build silent. Set this to something else to make it noisy again.
+V ?=           false
+
+# Internationalization support (output in different languages).
+# Requires gettext.
+NLS ?=         true
+
+# Set the following to 'true' to build/install the
+# cpufreq-bench benchmarking tool
+CPUFRQ_BENCH ?= true
+
+# Prefix to the directories we're installing to
+DESTDIR ?=
+
+# --- CONFIGURATION END ---
+
+
+
+# Package-related definitions. Distributions can modify the version
+# and _should_ modify the PACKAGE_BUGREPORT definition
+
+VERSION=                       $(shell ./utils/version-gen.sh)
+LIB_MAJ=                       0.0.0
+LIB_MIN=                       0
+
+PACKAGE =                      cpupower
+PACKAGE_BUGREPORT =            cpufreq@vger.kernel.org
+LANGUAGES =                    de fr it cs pt
+
+
+# Directory definitions. These are default and most probably
+# do not need to be changed. Please note that DESTDIR is
+# added in front of any of them
+
+bindir ?=      /usr/bin
+sbindir ?=     /usr/sbin
+mandir ?=      /usr/man
+includedir ?=  /usr/include
+libdir ?=      /usr/lib
+localedir ?=   /usr/share/locale
+docdir ?=       /usr/share/doc/packages/cpupower
+confdir ?=      /etc/
+
+# Toolchain: what tools do we use, and what options do they need:
+
+CP = cp -fpR
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+# If you are running a cross compiler, you may want to set this
+# to something more interesting, like "arm-linux-".  If you want
+# to compile vs uClibc, that can be done here as well.
+CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
+CC = $(CROSS)gcc
+LD = $(CROSS)gcc
+AR = $(CROSS)ar
+STRIP = $(CROSS)strip
+RANLIB = $(CROSS)ranlib
+HOSTCC = gcc
+
+
+# Now we set up the build system
+#
+
+# 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;}
+
+export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
+
+# check if compiler option is supported
+cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
+
+# use '-Os' optimization if available, else use -O2
+OPTIMIZATION := $(call cc-supports,-Os,-O2)
+
+WARNINGS := -Wall -Wchar-subscripts -Wpointer-arith -Wsign-compare
+WARNINGS += $(call cc-supports,-Wno-pointer-sign)
+WARNINGS += $(call cc-supports,-Wdeclaration-after-statement)
+WARNINGS += -Wshadow
+
+CFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \
+               -DPACKAGE_BUGREPORT=\"$(PACKAGE_BUGREPORT)\" -D_GNU_SOURCE
+
+UTIL_OBJS =  utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \
+       utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \
+       utils/helpers/pci.o utils/helpers/bitmask.o \
+       utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \
+       utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \
+       utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.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_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
+
+CFLAGS +=      -pipe
+
+ifeq ($(strip $(NLS)),true)
+       INSTALL_NLS += install-gmo
+       COMPILE_NLS += create-gmo
+endif
+
+ifeq ($(strip $(CPUFRQ_BENCH)),true)
+       INSTALL_BENCH += install-bench
+       COMPILE_BENCH += compile-bench
+endif
+
+CFLAGS += $(WARNINGS)
+
+ifeq ($(strip $(V)),false)
+       QUIET=@
+       ECHO=@echo
+else
+       QUIET=
+       ECHO=@\#
+endif
+export QUIET ECHO
+
+# if DEBUG is enabled, then we do not strip or optimize
+ifeq ($(strip $(DEBUG)),true)
+       CFLAGS += -O1 -g -DDEBUG
+       STRIPCMD = /bin/true -Since_we_are_debugging
+else
+       CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer
+       STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
+endif
+
+
+# the actual make rules
+
+all: libcpupower cpupower $(COMPILE_NLS) $(COMPILE_BENCH)
+
+lib/%.o: $(LIB_SRC) $(LIB_HEADERS)
+       $(ECHO) "  CC      " $@
+       $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
+
+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)
+
+libcpupower: 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:
+       $(ECHO) "  CC      " $@
+       $(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c
+
+cpupower: $(UTIL_OBJS) libcpupower.so.$(LIB_MAJ)
+       $(ECHO) "  CC      " $@
+       $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) -lcpupower -lrt -lpci -L. -o $@ $(UTIL_OBJS)
+       $(QUIET) $(STRIPCMD) $@
+
+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
+
+po/%.gmo: po/%.po
+       $(ECHO) "  MSGFMT  " $@
+       $(QUIET) msgfmt -o $@ po/$*.po
+
+create-gmo: ${GMO_FILES}
+
+update-po: 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; \
+               else \
+                       echo "msgmerge for $$HLANG failed!"; \
+                       rm -f po/$$HLANG.new.po; \
+               fi; \
+       done;
+
+compile-bench: libcpupower.so.$(LIB_MAJ)
+       @V=$(V) confdir=$(confdir) $(MAKE) -C bench
+
+clean:
+       -find . \( -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
+
+
+install-lib:
+       $(INSTALL) -d $(DESTDIR)${libdir}
+       $(CP) 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-man:
+       $(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-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.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-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
+
+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; \
+       done;
+
+install-bench:
+       @#DESTDIR must be set from outside to survive
+       @sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench install
+
+install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH)
+
+uninstall:
+       - rm -f $(DESTDIR)${libdir}/libcpupower.*
+       - rm -f $(DESTDIR)${includedir}/cpufreq.h
+       - rm -f $(DESTDIR)${bindir}/utils/cpupower
+       - rm -f $(DESTDIR)${mandir}/man1/cpufreq-set.1
+       - rm -f $(DESTDIR)${mandir}/man1/cpufreq-info.1
+       - for HLANG in $(LANGUAGES); do \
+               rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
+         done;
+
+.PHONY: all utils libcpupower update-po create-gmo install-lib install-tools install-man install-gmo install uninstall clean
diff --git a/tools/power/cpupower/README b/tools/power/cpupower/README
new file mode 100644 (file)
index 0000000..fd9d4c0
--- /dev/null
@@ -0,0 +1,49 @@
+The cpufrequtils package (homepage: 
+http://www.kernel.org/pub/linux/utils/kernel/cpufreq/cpufrequtils.html ) 
+consists of the following elements:
+
+requirements
+------------
+
+On x86 pciutils is needed at runtime (-lpci).
+For compilation pciutils-devel (pci/pci.h) and a gcc version
+providing cpuid.h is needed.
+For both it's not explicitly checked for (yet).
+
+
+libcpufreq
+----------
+
+"libcpufreq" 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
+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
+interfaces [depending on configuration, see below].
+
+
+compilation and installation
+----------------------------
+
+make
+su
+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.
+
+
+THANKS
+------
+Many thanks to Mattia Dongili who wrote the autotoolization and
+libtoolization, the manpages and the italian language file for cpufrequtils;
+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;
+and to various others commenting on the previous (pre-)releases of 
+cpufrequtils.
+
+
+        Dominik Brodowski
diff --git a/tools/power/cpupower/ToDo b/tools/power/cpupower/ToDo
new file mode 100644 (file)
index 0000000..874b78b
--- /dev/null
@@ -0,0 +1,11 @@
+ToDos sorted by priority:
+
+- Use bitmask functions to parse CPU topology more robust
+  (current implementation has issues on AMD)
+- Try to read out boost states and frequencies on Intel
+- Adjust README
+- Somewhere saw the ability to read power consumption of
+  RAM from HW on Intel SandyBridge -> another monitor?
+- Add another c1e debug idle monitor
+  -> Is by design racy with BIOS, but could be added
+     with a --force option and some "be careful" messages
diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile
new file mode 100644 (file)
index 0000000..2b67606
--- /dev/null
@@ -0,0 +1,29 @@
+LIBS = -L../ -lm -lcpupower
+
+OBJS = main.o parse.o system.o benchmark.o
+CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\"
+
+%.o : %.c
+       $(ECHO) "  CC      " $@
+       $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
+
+cpufreq-bench: $(OBJS)
+       $(ECHO) "  CC      " $@
+       $(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS)
+
+all: 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 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
diff --git a/tools/power/cpupower/bench/README-BENCH b/tools/power/cpupower/bench/README-BENCH
new file mode 100644 (file)
index 0000000..8093ec7
--- /dev/null
@@ -0,0 +1,124 @@
+This is cpufreq-bench, a microbenchmark for the cpufreq framework.
+
+Purpose
+=======
+
+What is this benchmark for:
+  - Identify worst case performance loss when doing dynamic frequency
+    scaling using Linux kernel governors
+  - Identify average reaction time of a governor to CPU load changes
+  - (Stress) Testing whether a cpufreq low level driver or governor works
+    as expected
+  - Identify cpufreq related performance regressions between kernels
+  - Possibly Real time priority testing? -> what happens if there are
+    processes with a higher prio than the governor's kernel thread
+  - ...
+
+What this benchmark does *not* cover:
+  - Power saving related regressions (In fact as better the performance
+    throughput is, the worse the power savings will be, but the first should
+    mostly count more...)
+  - Real world (workloads)
+
+
+Description
+===========
+
+cpufreq-bench helps to test the condition of a given cpufreq governor.
+For that purpose, it compares the performance governor to a configured
+powersave module.
+
+
+How it works
+============
+You can specify load (100% CPU load) and sleep (0% CPU load) times in us which
+will be run X time in a row (cycles):
+
+         sleep=25000
+         load=25000
+         cycles=20
+
+This part of the configuration file will create 25ms load/sleep turns,
+repeated 20 times.
+
+Adding this:
+         sleep_step=25000
+         load_step=25000
+         rounds=5
+Will increase load and sleep time by 25ms 5 times.
+Together you get following test:
+25ms  load/sleep time repeated 20 times (cycles).
+50ms  load/sleep time repeated 20 times (cycles).
+..
+100ms load/sleep time repeated 20 times (cycles).
+
+First it is calibrated how long a specific CPU intensive calculation
+takes on this machine and needs to be run in a loop using the performance
+governor.
+Then the above test runs are processed using the performance governor
+and the governor to test. The time the calculation really needed
+with the dynamic freq scaling governor is compared with the time needed
+on full performance and you get the overall performance loss.
+
+
+Example of expected results with ondemand governor:
+
+This shows expected results of the first two test run rounds from
+above config, you there have:
+
+100% CPU load (load) | 0 % CPU load (sleep)  | round
+   25 ms             |    25 ms              |   1
+   50 ms             |    50 ms              |   2
+
+For example if ondemand governor is configured to have a 50ms
+sampling rate you get:
+
+In round 1, ondemand should have rather static 50% load and probably
+won't ever switch up (as long as up_threshold is above).
+
+In round 2, if the ondemand sampling times exactly match the load/sleep
+trigger of the cpufreq-bench, you will see no performance loss (compare with
+below possible ondemand sample kick ins (1)):
+
+But if ondemand always kicks in in the middle of the load sleep cycles, it
+will always see 50% loads and you get worst performance impact never
+switching up (compare with below possible ondemand sample kick ins (2))::
+
+      50     50   50   50ms ->time
+load -----|     |-----|     |-----|     |-----|
+          |     |     |     |     |     |     |
+sleep     |-----|     |-----|     |-----|     |----
+    |-----|-----|-----|-----|-----|-----|-----|----  ondemand sampling (1)
+         100    0    100    0    100    0    100     load seen by ondemand(%)
+       |-----|-----|-----|-----|-----|-----|-----|--   ondemand sampling (2)
+      50     50    50    50    50    50    50        load seen by ondemand(%)
+
+You can easily test all kind of load/sleep times and check whether your
+governor in average behaves as expected.
+
+
+ToDo
+====
+
+Provide a gnuplot utility script for easy generation of plots to present
+the outcome nicely.
+
+
+cpufreq-bench Command Usage
+===========================
+-l, --load=<long int>           initial load time in us
+-s, --sleep=<long int>          initial sleep time in us
+-x, --load-step=<long int>      time to be added to load time, in us
+-y, --sleep-step=<long int>     time to be added to sleep time, in us
+-c, --cpu=<unsigned int>        CPU Number to use, starting at 0
+-p, --prio=<priority>           scheduler priority, HIGH, LOW or DEFAULT
+-g, --governor=<governor>       cpufreq governor to test
+-n, --cycles=<int>              load/sleep cycles to get an avarage value to compare
+-r, --rounds<int>               load/sleep rounds
+-f, --file=<configfile>         config file to use
+-o, --output=<dir>              output dir, must exist
+-v, --verbose                   verbose output on/off
+
+Due to the high priority, the application may not be responsible for some time.
+After the benchmark, the logfile is saved in OUTPUTDIR/benchmark_TIMESTAMP.log
+
diff --git a/tools/power/cpupower/bench/benchmark.c b/tools/power/cpupower/bench/benchmark.c
new file mode 100644 (file)
index 0000000..81b1c48
--- /dev/null
@@ -0,0 +1,194 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "config.h"
+#include "system.h"
+#include "benchmark.h"
+
+/* Print out progress if we log into a file */
+#define show_progress(total_time, progress_time)       \
+if (config->output != stdout) {                                \
+       fprintf(stdout, "Progress: %02lu %%\r",         \
+               (progress_time * 100) / total_time);    \
+       fflush(stdout);                                 \
+}
+
+/**
+ * compute how many rounds of calculation we should do
+ * to get the given load time
+ *
+ * @param load aimed load time in µs
+ *
+ * @retval rounds of calculation
+ **/
+
+unsigned int calculate_timespace(long load, struct config *config)
+{
+       int i;
+       long long now, then;
+       unsigned int estimated = GAUGECOUNT;
+       unsigned int rounds = 0;
+       unsigned int timed = 0;
+
+       if (config->verbose)
+               printf("calibrating load of %lius, please wait...\n", load);
+
+       /* get the initial calculation time for a specific number of rounds */
+       now = get_time();
+       ROUNDS(estimated);
+       then = get_time();
+
+       timed = (unsigned int)(then - now);
+
+       /* approximation of the wanted load time by comparing with the
+        * initial calculation time */
+       for (i = 0; i < 4; i++) {
+               rounds = (unsigned int)(load * estimated / timed);
+               dprintf("calibrating with %u rounds\n", rounds);
+               now = get_time();
+               ROUNDS(rounds);
+               then = get_time();
+
+               timed = (unsigned int)(then - now);
+               estimated = rounds;
+       }
+       if (config->verbose)
+               printf("calibration done\n");
+
+       return estimated;
+}
+
+/**
+ * benchmark
+ * generates a specific sleep an load time with the performance
+ * governor and compares the used time for same calculations done
+ * with the configured powersave governor
+ *
+ * @param config config values for the benchmark
+ *
+ **/
+
+void start_benchmark(struct config *config)
+{
+       unsigned int _round, cycle;
+       long long now, then;
+       long sleep_time = 0, load_time = 0;
+       long performance_time = 0, powersave_time = 0;
+       unsigned int calculations;
+       unsigned long total_time = 0, progress_time = 0;
+
+       sleep_time = config->sleep;
+       load_time = config->load;
+
+       /* For the progress bar */
+       for (_round = 1; _round <= config->rounds; _round++)
+               total_time += _round * (config->sleep + config->load);
+       total_time *= 2; /* powersave and performance cycles */
+
+       for (_round = 0; _round < config->rounds; _round++) {
+               performance_time = 0LL;
+               powersave_time = 0LL;
+
+               show_progress(total_time, progress_time);
+
+               /* set the cpufreq governor to "performance" which disables
+                * P-State switching. */
+               if (set_cpufreq_governor("performance", config->cpu) != 0)
+                       return;
+
+               /* calibrate the calculation time. the resulting calculation
+                * _rounds should produce a load which matches the configured
+                * load time */
+               calculations = calculate_timespace(load_time, config);
+
+               if (config->verbose)
+                       printf("_round %i: doing %u cycles with %u calculations"
+                              " for %lius\n", _round + 1, config->cycles,
+                              calculations, load_time);
+
+               fprintf(config->output, "%u %li %li ",
+                       _round, load_time, sleep_time);
+
+               if (config->verbose)
+                       printf("avarage: %lius, rps:%li\n",
+                               load_time / calculations,
+                               1000000 * calculations / load_time);
+
+               /* do some sleep/load cycles with the performance governor */
+               for (cycle = 0; cycle < config->cycles; cycle++) {
+                       now = get_time();
+                       usleep(sleep_time);
+                       ROUNDS(calculations);
+                       then = get_time();
+                       performance_time += then - now - sleep_time;
+                       if (config->verbose)
+                               printf("performance cycle took %lius, "
+                                       "sleep: %lius, "
+                                       "load: %lius, rounds: %u\n",
+                                       (long)(then - now), sleep_time,
+                                       load_time, calculations);
+               }
+               fprintf(config->output, "%li ",
+                       performance_time / config->cycles);
+
+               progress_time += sleep_time + load_time;
+               show_progress(total_time, progress_time);
+
+               /* set the powersave governor which activates P-State switching
+                * again */
+               if (set_cpufreq_governor(config->governor, config->cpu) != 0)
+                       return;
+
+               /* again, do some sleep/load cycles with the
+                * powersave governor */
+               for (cycle = 0; cycle < config->cycles; cycle++) {
+                       now = get_time();
+                       usleep(sleep_time);
+                       ROUNDS(calculations);
+                       then = get_time();
+                       powersave_time += then - now - sleep_time;
+                       if (config->verbose)
+                               printf("powersave cycle took %lius, "
+                                       "sleep: %lius, "
+                                       "load: %lius, rounds: %u\n",
+                                       (long)(then - now), sleep_time,
+                                       load_time, calculations);
+               }
+
+               progress_time += sleep_time + load_time;
+
+               /* compare the avarage sleep/load cycles  */
+               fprintf(config->output, "%li ",
+                       powersave_time / config->cycles);
+               fprintf(config->output, "%.3f\n",
+                       performance_time * 100.0 / powersave_time);
+               fflush(config->output);
+
+               if (config->verbose)
+                       printf("performance is at %.2f%%\n",
+                               performance_time * 100.0 / powersave_time);
+
+               sleep_time += config->sleep_step;
+               load_time += config->load_step;
+       }
+}
diff --git a/tools/power/cpupower/bench/benchmark.h b/tools/power/cpupower/bench/benchmark.h
new file mode 100644 (file)
index 0000000..51d7f50
--- /dev/null
@@ -0,0 +1,29 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* load loop, this schould take about 1 to 2ms to complete */
+#define ROUNDS(x) {unsigned int rcnt;                         \
+               for (rcnt = 0; rcnt < x*1000; rcnt++) { \
+                       (void)(((int)(pow(rcnt, rcnt) * \
+                                     sqrt(rcnt*7230970)) ^ 7230716) ^ \
+                                     (int)atan2(rcnt, rcnt));         \
+               } }                                                     \
+
+
+void start_benchmark(struct config *config);
diff --git a/tools/power/cpupower/bench/config.h b/tools/power/cpupower/bench/config.h
new file mode 100644 (file)
index 0000000..ee6f258
--- /dev/null
@@ -0,0 +1,36 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* initial loop count for the load calibration */
+#define GAUGECOUNT     1500
+
+/* default scheduling policy SCHED_OTHER */
+#define SCHEDULER      SCHED_OTHER
+
+#define PRIORITY_DEFAULT 0
+#define PRIORITY_HIGH   sched_get_priority_max(SCHEDULER)
+#define PRIORITY_LOW    sched_get_priority_min(SCHEDULER)
+
+/* enable further debug messages */
+#ifdef DEBUG
+#define dprintf printf
+#else
+#define dprintf(...) do { } while (0)
+#endif
+
diff --git a/tools/power/cpupower/bench/cpufreq-bench_plot.sh b/tools/power/cpupower/bench/cpufreq-bench_plot.sh
new file mode 100644 (file)
index 0000000..410021a
--- /dev/null
@@ -0,0 +1,104 @@
+#!/bin/bash
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# Author/Copyright(c): 2009, Thomas Renninger <trenn@suse.de>, Novell Inc.
+
+# Helper script to easily create nice plots of your cpufreq-bench results
+
+dir=`mktemp -d`
+output_file="cpufreq-bench.png"
+global_title="cpufreq-bench plot"
+picture_type="jpeg"
+file[0]=""
+
+function usage()
+{
+    echo "cpufreq-bench_plot.sh [OPTIONS] logfile [measure_title] [logfile [measure_title]] ...]"
+    echo
+    echo "Options"
+    echo "   -o output_file"
+    echo "   -t global_title"
+    echo "   -p picture_type [jpeg|gif|png|postscript|...]"
+    exit 1
+}
+
+if [ $# -eq 0 ];then
+       echo "No benchmark results file provided"
+       echo
+       usage
+fi
+
+while getopts o:t:p: name ; do
+    case $name in
+       o)
+           output_file="$OPTARG".$picture_type
+           ;;
+       t)
+           global_title="$OPTARG"
+           ;;
+       p)
+           picture_type="$OPTARG"
+           ;;
+        ?)
+           usage
+           ;;
+    esac
+done
+shift $(($OPTIND -1))
+
+plots=0
+while [ "$1" ];do
+    if [ ! -f "$1" ];then
+       echo "File $1 does not exist"
+       usage
+    fi
+    file[$plots]="$1"
+    title[$plots]="$2"
+    # echo "File: ${file[$plots]} - ${title[plots]}"
+    shift;shift
+    plots=$((plots + 1))
+done
+
+echo "set terminal $picture_type"      >> $dir/plot_script.gpl
+echo "set output \"$output_file\""     >> $dir/plot_script.gpl
+echo "set title \"$global_title\""     >> $dir/plot_script.gpl
+echo "set xlabel \"sleep/load time\""  >> $dir/plot_script.gpl
+echo "set ylabel \"Performance (%)\""  >> $dir/plot_script.gpl
+
+for((plot=0;plot<$plots;plot++));do
+
+    # Sanity check
+    ###### I am to dump to get this redirected to stderr/stdout in one awk call... #####
+    cat ${file[$plot]} |grep -v "^#" |awk '{if ($2 != $3) printf("Error in measure %d:Load time %s does not equal sleep time %s, plot will not be correct\n", $1, $2, $3); ERR=1}'
+    ###### I am to dump to get this redirected in one awk call... #####
+
+    # Parse out load time (which must be equal to sleep time for a plot), divide it by 1000
+    # to get ms and parse out the performance in percentage and write it to a temp file for plotting
+    cat ${file[$plot]} |grep -v "^#" |awk '{printf "%lu %.1f\n",$2/1000, $6}' >$dir/data_$plot
+
+    if [ $plot -eq 0 ];then
+       echo -n "plot " >> $dir/plot_script.gpl
+    fi
+    echo -n "\"$dir/data_$plot\" title \"${title[$plot]}\" with lines" >> $dir/plot_script.gpl
+    if [ $(($plot + 1)) -ne $plots ];then
+       echo -n ", " >> $dir/plot_script.gpl
+    fi
+done
+echo >> $dir/plot_script.gpl
+
+gnuplot $dir/plot_script.gpl
+rm -r $dir
\ No newline at end of file
diff --git a/tools/power/cpupower/bench/cpufreq-bench_script.sh b/tools/power/cpupower/bench/cpufreq-bench_script.sh
new file mode 100644 (file)
index 0000000..de20d2a
--- /dev/null
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# Author/Copyright(c): 2009, Thomas Renninger <trenn@suse.de>, Novell Inc.
+
+# Ondemand up_threshold and sampling rate test script for cpufreq-bench
+# mircobenchmark.
+# Modify the general variables at the top or extend or copy out parts
+# if you want to test other things
+#
+
+# Default with latest kernels is 95, before micro account patches
+# it was 80, cmp. with git commit 808009131046b62ac434dbc796
+UP_THRESHOLD="60 80 95"
+# Depending on the kernel and the HW sampling rate could be restricted
+# and cannot be set that low...
+# E.g. before git commit cef9615a853ebc4972084f7 one could only set
+# min sampling rate of 80000 if CONFIG_HZ=250
+SAMPLING_RATE="20000 80000"
+
+function measure()
+{
+    local -i up_threshold_set
+    local -i sampling_rate_set
+
+    for up_threshold in $UP_THRESHOLD;do
+       for sampling_rate in $SAMPLING_RATE;do
+           # Set values in sysfs
+           echo $up_threshold >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold
+           echo $sampling_rate >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate
+           up_threshold_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold)
+           sampling_rate_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate)
+
+           # Verify set values in sysfs
+           if [ ${up_threshold_set} -eq ${up_threshold} ];then
+               echo "up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}"
+           else
+               echo "WARNING: Tried to set up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}"
+           fi
+           if [ ${sampling_rate_set} -eq ${sampling_rate} ];then
+               echo "sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}"
+           else
+               echo "WARNING: Tried to set sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}"
+           fi
+
+           # Benchmark
+           cpufreq-bench -o /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}
+       done
+    done
+}
+
+function create_plots()
+{
+    local command
+
+    for up_threshold in $UP_THRESHOLD;do
+       command="cpufreq-bench_plot.sh -o \"sampling_rate_${SAMPLING_RATE}_up_threshold_${up_threshold}\" -t \"Ondemand sampling_rate: ${SAMPLING_RATE} comparison - Up_threshold: $up_threshold %\""
+       for sampling_rate in $SAMPLING_RATE;do
+           command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"sampling_rate = $sampling_rate\""
+       done
+       echo $command
+       eval "$command"
+       echo
+    done
+
+    for sampling_rate in $SAMPLING_RATE;do
+       command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${sampling_rate}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} % comparison - sampling_rate: $sampling_rate\""
+       for up_threshold in $UP_THRESHOLD;do
+           command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold\""
+       done
+       echo $command
+       eval "$command"
+       echo
+    done
+
+    command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${SAMPLING_RATE}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} and sampling_rate ${SAMPLING_RATE} comparison\""
+    for sampling_rate in $SAMPLING_RATE;do
+       for up_threshold in $UP_THRESHOLD;do
+           command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold - sampling_rate = $sampling_rate\""
+       done
+    done
+    echo "$command"
+    eval "$command"
+}
+
+measure
+create_plots
\ No newline at end of file
diff --git a/tools/power/cpupower/bench/example.cfg b/tools/power/cpupower/bench/example.cfg
new file mode 100644 (file)
index 0000000..f91f643
--- /dev/null
@@ -0,0 +1,11 @@
+sleep = 50000
+load = 50000
+cpu = 0
+priority = LOW
+output = /var/log/cpufreq-bench
+sleep_step = 50000
+load_step = 50000
+cycles = 20
+rounds = 40
+verbose = 0
+governor = ondemand
diff --git a/tools/power/cpupower/bench/main.c b/tools/power/cpupower/bench/main.c
new file mode 100644 (file)
index 0000000..2491031
--- /dev/null
@@ -0,0 +1,202 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+
+#include "config.h"
+#include "system.h"
+#include "benchmark.h"
+
+static struct option long_options[] = {
+       {"output",      1,      0,      'o'},
+       {"sleep",       1,      0,      's'},
+       {"load",        1,      0,      'l'},
+       {"verbose",     0,      0,      'v'},
+       {"cpu",         1,      0,      'c'},
+       {"governor",    1,      0,      'g'},
+       {"prio",        1,      0,      'p'},
+       {"file",        1,      0,      'f'},
+       {"cycles",      1,      0,      'n'},
+       {"rounds",      1,      0,      'r'},
+       {"load-step",   1,      0,      'x'},
+       {"sleep-step",  1,      0,      'y'},
+       {"help",        0,      0,      'h'},
+       {0, 0, 0, 0}
+};
+
+/*******************************************************************
+ usage
+*******************************************************************/
+
+void usage()
+{
+       printf("usage: ./bench\n");
+       printf("Options:\n");
+       printf(" -l, --load=<long int>\t\tinitial load time in us\n");
+       printf(" -s, --sleep=<long int>\t\tinitial sleep time in us\n");
+       printf(" -x, --load-step=<long int>\ttime to be added to load time, in us\n");
+       printf(" -y, --sleep-step=<long int>\ttime to be added to sleep time, in us\n");
+       printf(" -c, --cpu=<cpu #>\t\t\tCPU Nr. to use, starting at 0\n");
+       printf(" -p, --prio=<priority>\t\t\tscheduler priority, HIGH, LOW or DEFAULT\n");
+       printf(" -g, --governor=<governor>\t\tcpufreq governor to test\n");
+       printf(" -n, --cycles=<int>\t\t\tload/sleep cycles\n");
+       printf(" -r, --rounds<int>\t\t\tload/sleep rounds\n");
+       printf(" -f, --file=<configfile>\t\tconfig file to use\n");
+       printf(" -o, --output=<dir>\t\t\toutput path. Filename will be OUTPUTPATH/benchmark_TIMESTAMP.log\n");
+       printf(" -v, --verbose\t\t\t\tverbose output on/off\n");
+       printf(" -h, --help\t\t\t\tPrint this help screen\n");
+       exit(1);
+}
+
+/*******************************************************************
+ main
+*******************************************************************/
+
+int main(int argc, char **argv)
+{
+       int c;
+       int option_index = 0;
+       struct config *config = NULL;
+
+       config = prepare_default_config();
+
+       if (config == NULL)
+               return EXIT_FAILURE;
+
+       while (1) {
+               c = getopt_long (argc, argv, "hg:o:s:l:vc:p:f:n:r:x:y:",
+                               long_options, &option_index);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 'o':
+                       if (config->output != NULL)
+                               fclose(config->output);
+
+                       config->output = prepare_output(optarg);
+
+                       if (config->output == NULL)
+                               return EXIT_FAILURE;
+
+                       dprintf("user output path -> %s\n", optarg);
+                       break;
+               case 's':
+                       sscanf(optarg, "%li", &config->sleep);
+                       dprintf("user sleep time -> %s\n", optarg);
+                       break;
+               case 'l':
+                       sscanf(optarg, "%li", &config->load);
+                       dprintf("user load time -> %s\n", optarg);
+                       break;
+               case 'c':
+                       sscanf(optarg, "%u", &config->cpu);
+                       dprintf("user cpu -> %s\n", optarg);
+                       break;
+               case 'g':
+                       strncpy(config->governor, optarg, 14);
+                       dprintf("user governor -> %s\n", optarg);
+                       break;
+               case 'p':
+                       if (string_to_prio(optarg) != SCHED_ERR) {
+                               config->prio = string_to_prio(optarg);
+                               dprintf("user prio -> %s\n", optarg);
+                       } else {
+                               if (config != NULL) {
+                                       if (config->output != NULL)
+                                               fclose(config->output);
+                                       free(config);
+                               }
+                               usage();
+                       }
+                       break;
+               case 'n':
+                       sscanf(optarg, "%u", &config->cycles);
+                       dprintf("user cycles -> %s\n", optarg);
+                       break;
+               case 'r':
+                       sscanf(optarg, "%u", &config->rounds);
+                       dprintf("user rounds -> %s\n", optarg);
+                       break;
+               case 'x':
+                       sscanf(optarg, "%li", &config->load_step);
+                       dprintf("user load_step -> %s\n", optarg);
+                       break;
+               case 'y':
+                       sscanf(optarg, "%li", &config->sleep_step);
+                       dprintf("user sleep_step -> %s\n", optarg);
+                       break;
+               case 'f':
+                       if (prepare_config(optarg, config))
+                               return EXIT_FAILURE;
+                       break;
+               case 'v':
+                       config->verbose = 1;
+                       dprintf("verbose output enabled\n");
+                       break;
+               case 'h':
+               case '?':
+               default:
+                       if (config != NULL) {
+                               if (config->output != NULL)
+                                       fclose(config->output);
+                               free(config);
+                       }
+                       usage();
+               }
+       }
+
+       if (config->verbose) {
+               printf("starting benchmark with parameters:\n");
+               printf("config:\n\t"
+                      "sleep=%li\n\t"
+                      "load=%li\n\t"
+                      "sleep_step=%li\n\t"
+                      "load_step=%li\n\t"
+                      "cpu=%u\n\t"
+                      "cycles=%u\n\t"
+                      "rounds=%u\n\t"
+                      "governor=%s\n\n",
+                      config->sleep,
+                      config->load,
+                      config->sleep_step,
+                      config->load_step,
+                      config->cpu,
+                      config->cycles,
+                      config->rounds,
+                      config->governor);
+       }
+
+       prepare_user(config);
+       prepare_system(config);
+       start_benchmark(config);
+
+       if (config->output != stdout)
+               fclose(config->output);
+
+       free(config);
+
+       return EXIT_SUCCESS;
+}
+
diff --git a/tools/power/cpupower/bench/parse.c b/tools/power/cpupower/bench/parse.c
new file mode 100644 (file)
index 0000000..543bba1
--- /dev/null
@@ -0,0 +1,225 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <dirent.h>
+
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "parse.h"
+#include "config.h"
+
+/**
+ * converts priority string to priority
+ *
+ * @param str string that represents a scheduler priority
+ *
+ * @retval priority
+ * @retval SCHED_ERR when the priority doesn't exit
+ **/
+
+enum sched_prio string_to_prio(const char *str)
+{
+       if (strncasecmp("high", str, strlen(str)) == 0)
+               return  SCHED_HIGH;
+       else if (strncasecmp("default", str, strlen(str)) == 0)
+               return SCHED_DEFAULT;
+       else if (strncasecmp("low", str, strlen(str)) == 0)
+               return SCHED_LOW;
+       else
+               return SCHED_ERR;
+}
+
+/**
+ * create and open logfile
+ *
+ * @param dir directory in which the logfile should be created
+ *
+ * @retval logfile on success
+ * @retval NULL when the file can't be created
+ **/
+
+FILE *prepare_output(const char *dirname)
+{
+       FILE *output = NULL;
+       int len;
+       char *filename;
+       struct utsname sysdata;
+       DIR *dir;
+
+       dir = opendir(dirname);
+       if (dir == NULL) {
+               if (mkdir(dirname, 0755)) {
+                       perror("mkdir");
+                       fprintf(stderr, "error: Cannot create dir %s\n",
+                               dirname);
+                       return NULL;
+               }
+       }
+
+       len = strlen(dirname) + 30;
+       filename = malloc(sizeof(char) * len);
+
+       if (uname(&sysdata) == 0) {
+               len += strlen(sysdata.nodename) + strlen(sysdata.release);
+               filename = realloc(filename, sizeof(char) * len);
+
+               if (filename == NULL) {
+                       perror("realloc");
+                       return NULL;
+               }
+
+               snprintf(filename, len - 1, "%s/benchmark_%s_%s_%li.log",
+                       dirname, sysdata.nodename, sysdata.release, time(NULL));
+       } else {
+               snprintf(filename, len - 1, "%s/benchmark_%li.log",
+                       dirname, time(NULL));
+       }
+
+       dprintf("logilename: %s\n", filename);
+
+       output = fopen(filename, "w+");
+       if (output == NULL) {
+               perror("fopen");
+               fprintf(stderr, "error: unable to open logfile\n");
+       }
+
+       fprintf(stdout, "Logfile: %s\n", filename);
+
+       free(filename);
+       fprintf(output, "#round load sleep performance powersave percentage\n");
+       return output;
+}
+
+/**
+ * returns the default config
+ *
+ * @retval default config on success
+ * @retval NULL when the output file can't be created
+ **/
+
+struct config *prepare_default_config()
+{
+       struct config *config = malloc(sizeof(struct config));
+
+       dprintf("loading defaults\n");
+
+       config->sleep = 500000;
+       config->load = 500000;
+       config->sleep_step = 500000;
+       config->load_step = 500000;
+       config->cycles = 5;
+       config->rounds = 50;
+       config->cpu = 0;
+       config->prio = SCHED_HIGH;
+       config->verbose = 0;
+       strncpy(config->governor, "ondemand", 8);
+
+       config->output = stdout;
+
+#ifdef DEFAULT_CONFIG_FILE
+       if (prepare_config(DEFAULT_CONFIG_FILE, config))
+               return NULL;
+#endif
+       return config;
+}
+
+/**
+ * parses config file and returns the config to the caller
+ *
+ * @param path config file name
+ *
+ * @retval 1 on error
+ * @retval 0 on success
+ **/
+
+int prepare_config(const char *path, struct config *config)
+{
+       size_t len = 0;
+       char *opt, *val, *line = NULL;
+       FILE *configfile = fopen(path, "r");
+
+       if (config == NULL) {
+               fprintf(stderr, "error: config is NULL\n");
+               return 1;
+       }
+
+       if (configfile == NULL) {
+               perror("fopen");
+               fprintf(stderr, "error: unable to read configfile\n");
+               free(config);
+               return 1;
+       }
+
+       while (getline(&line, &len, configfile) != -1) {
+               if (line[0] == '#' || line[0] == ' ')
+                       continue;
+
+               sscanf(line, "%as = %as", &opt, &val);
+
+               dprintf("parsing: %s -> %s\n", opt, val);
+
+               if (strncmp("sleep", opt, strlen(opt)) == 0)
+                       sscanf(val, "%li", &config->sleep);
+
+               else if (strncmp("load", opt, strlen(opt)) == 0)
+                       sscanf(val, "%li", &config->load);
+
+               else if (strncmp("load_step", opt, strlen(opt)) == 0)
+                       sscanf(val, "%li", &config->load_step);
+
+               else if (strncmp("sleep_step", opt, strlen(opt)) == 0)
+                       sscanf(val, "%li", &config->sleep_step);
+
+               else if (strncmp("cycles", opt, strlen(opt)) == 0)
+                       sscanf(val, "%u", &config->cycles);
+
+               else if (strncmp("rounds", opt, strlen(opt)) == 0)
+                       sscanf(val, "%u", &config->rounds);
+
+               else if (strncmp("verbose", opt, strlen(opt)) == 0)
+                       sscanf(val, "%u", &config->verbose);
+
+               else if (strncmp("output", opt, strlen(opt)) == 0)
+                       config->output = prepare_output(val); 
+
+               else if (strncmp("cpu", opt, strlen(opt)) == 0)
+                       sscanf(val, "%u", &config->cpu);
+
+               else if (strncmp("governor", opt, 14) == 0)
+                       strncpy(config->governor, val, 14);
+
+               else if (strncmp("priority", opt, strlen(opt)) == 0) {
+                       if (string_to_prio(val) != SCHED_ERR)
+                               config->prio = string_to_prio(val);
+               }
+       }
+
+       free(line);
+       free(opt);
+       free(val);
+
+       return 0;
+}
diff --git a/tools/power/cpupower/bench/parse.h b/tools/power/cpupower/bench/parse.h
new file mode 100644 (file)
index 0000000..a8dc632
--- /dev/null
@@ -0,0 +1,53 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* struct that holds the required config parameters */
+struct config
+{
+       long sleep;             /* sleep time in µs */
+       long load;              /* load time in µs */
+       long sleep_step;        /* time value which changes the
+                                * sleep time after every round in µs */
+       long load_step;         /* time value which changes the
+                                * load time after every round in µs */
+       unsigned int cycles;    /* calculation cycles with the same sleep/load time */
+       unsigned int rounds;    /* calculation rounds with iterated sleep/load time */
+       unsigned int cpu;       /* cpu for which the affinity is set */
+       char governor[15];      /* cpufreq governor */
+       enum sched_prio         /* possible scheduler priorities */
+       {
+               SCHED_ERR = -1,
+               SCHED_HIGH,
+               SCHED_DEFAULT,
+               SCHED_LOW
+       } prio;
+
+       unsigned int verbose;   /* verbose output */
+       FILE *output;           /* logfile */
+       char *output_filename;  /* logfile name, must be freed at the end
+                                  if output != NULL and output != stdout*/
+};
+
+enum sched_prio string_to_prio(const char *str);
+
+FILE *prepare_output(const char *dir);
+
+int prepare_config(const char *path, struct config *config);
+struct config *prepare_default_config();
+
diff --git a/tools/power/cpupower/bench/system.c b/tools/power/cpupower/bench/system.c
new file mode 100644 (file)
index 0000000..f01e3f4
--- /dev/null
@@ -0,0 +1,191 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <sched.h>
+
+#include <cpufreq.h>
+
+#include "config.h"
+#include "system.h"
+
+/**
+ * returns time since epoch in µs
+ *
+ * @retval time
+ **/
+
+long long int get_time()
+{
+       struct timeval now;
+
+       gettimeofday(&now, NULL);
+
+       return (long long int)(now.tv_sec * 1000000LL + now.tv_usec);
+}
+
+/**
+ * sets the cpufreq governor
+ *
+ * @param governor cpufreq governor name
+ * @param cpu cpu for which the governor should be set
+ *
+ * @retval 0 on success
+ * @retval -1 when failed
+ **/
+
+int set_cpufreq_governor(char *governor, unsigned int cpu)
+{
+
+       dprintf("set %s as cpufreq governor\n", governor);
+
+       if (cpufreq_cpu_exists(cpu) != 0) {
+               perror("cpufreq_cpu_exists");
+               fprintf(stderr, "error: cpu %u does not exist\n", cpu);
+               return -1;
+       }
+
+       if (cpufreq_modify_policy_governor(cpu, governor) != 0) {
+               perror("cpufreq_modify_policy_governor");
+               fprintf(stderr, "error: unable to set %s governor\n", governor);
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * sets cpu affinity for the process
+ *
+ * @param cpu cpu# to which the affinity should be set
+ *
+ * @retval 0 on success
+ * @retval -1 when setting the affinity failed
+ **/
+
+int set_cpu_affinity(unsigned int cpu)
+{
+       cpu_set_t cpuset;
+
+       CPU_ZERO(&cpuset);
+       CPU_SET(cpu, &cpuset);
+
+       dprintf("set affinity to cpu #%u\n", cpu);
+
+       if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) < 0) {
+               perror("sched_setaffinity");
+               fprintf(stderr, "warning: unable to set cpu affinity\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * sets the process priority parameter
+ *
+ * @param priority priority value
+ *
+ * @retval 0 on success
+ * @retval -1 when setting the priority failed
+ **/
+
+int set_process_priority(int priority)
+{
+       struct sched_param param;
+
+       dprintf("set scheduler priority to %i\n", priority);
+
+       param.sched_priority = priority;
+
+       if (sched_setscheduler(0, SCHEDULER, &param) < 0) {
+               perror("sched_setscheduler");
+               fprintf(stderr, "warning: unable to set scheduler priority\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * notifies the user that the benchmark may run some time
+ *
+ * @param config benchmark config values
+ *
+ **/
+
+void prepare_user(const struct config *config)
+{
+       unsigned long sleep_time = 0;
+       unsigned long load_time = 0;
+       unsigned int round;
+
+       for (round = 0; round < config->rounds; round++) {
+               sleep_time +=  2 * config->cycles *
+                       (config->sleep + config->sleep_step * round);
+               load_time += 2 * config->cycles *
+                       (config->load + config->load_step * round) +
+                       (config->load + config->load_step * round * 4);
+       }
+
+       if (config->verbose || config->output != stdout)
+               printf("approx. test duration: %im\n",
+                      (int)((sleep_time + load_time) / 60000000));
+}
+
+/**
+ * sets up the cpu affinity and scheduler priority
+ *
+ * @param config benchmark config values
+ *
+ **/
+
+void prepare_system(const struct config *config)
+{
+       if (config->verbose)
+               printf("set cpu affinity to cpu #%u\n", config->cpu);
+
+       set_cpu_affinity(config->cpu);
+
+       switch (config->prio) {
+       case SCHED_HIGH:
+               if (config->verbose)
+                       printf("high priority condition requested\n");
+
+               set_process_priority(PRIORITY_HIGH);
+               break;
+       case SCHED_LOW:
+               if (config->verbose)
+                       printf("low priority condition requested\n");
+
+               set_process_priority(PRIORITY_LOW);
+               break;
+       default:
+               if (config->verbose)
+                       printf("default priority condition requested\n");
+
+               set_process_priority(PRIORITY_DEFAULT);
+       }
+}
+
diff --git a/tools/power/cpupower/bench/system.h b/tools/power/cpupower/bench/system.h
new file mode 100644 (file)
index 0000000..3a8c858
--- /dev/null
@@ -0,0 +1,29 @@
+/*  cpufreq-bench CPUFreq microbenchmark
+ *
+ *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "parse.h"
+
+long long get_time();
+
+int set_cpufreq_governor(char *governor, unsigned int cpu);
+int set_cpu_affinity(unsigned int cpu);
+int set_process_priority(int priority);
+
+void prepare_user(const struct config *config);
+void prepare_system(const struct config *config);
diff --git a/tools/power/cpupower/debug/i386/Makefile b/tools/power/cpupower/debug/i386/Makefile
new file mode 100644 (file)
index 0000000..d08cc1e
--- /dev/null
@@ -0,0 +1,20 @@
+default: all
+
+centrino-decode: centrino-decode.c
+       $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c
+
+dump_psb: dump_psb.c
+       $(CC) $(CFLAGS) -o dump_psb dump_psb.c
+
+intel_gsic: intel_gsic.c
+       $(CC) $(CFLAGS) -o intel_gsic -llrmi intel_gsic.c
+
+powernow-k8-decode: powernow-k8-decode.c
+       $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c
+
+all: centrino-decode dump_psb intel_gsic powernow-k8-decode
+
+clean:
+       rm -rf centrino-decode dump_psb intel_gsic powernow-k8-decode
+
+.PHONY: all default clean
diff --git a/tools/power/cpupower/debug/i386/centrino-decode.c b/tools/power/cpupower/debug/i386/centrino-decode.c
new file mode 100644 (file)
index 0000000..7ef24cc
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  (C) 2003 - 2004  Dominik Brodowski <linux@dominikbrodowski.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ * Based on code found in
+ * linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+ * and originally developed by Jeremy Fitzhardinge.
+ *
+ * USAGE: simply run it to decode the current settings on CPU 0,
+ *       or pass the CPU number as argument, or pass the MSR content
+ *       as argument.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define MCPU   32
+
+#define MSR_IA32_PERF_STATUS   0x198
+
+static int rdmsr(unsigned int cpu, unsigned int msr,
+                unsigned int *lo, unsigned int *hi)
+{
+       int fd;
+       char file[20];
+       unsigned long long val;
+       int retval = -1;
+
+       *lo = *hi = 0;
+
+       if (cpu > MCPU)
+               goto err1;
+
+       sprintf(file, "/dev/cpu/%d/msr", cpu);
+       fd = open(file, O_RDONLY);
+
+       if (fd < 0)
+               goto err1;
+
+       if (lseek(fd, msr, SEEK_CUR) == -1)
+               goto err2;
+
+       if (read(fd, &val, 8) != 8)
+               goto err2;
+
+       *lo = (uint32_t )(val & 0xffffffffull);
+       *hi = (uint32_t )(val>>32 & 0xffffffffull);
+
+       retval = 0;
+err2:
+       close(fd);
+err1:
+       return retval;
+}
+
+static void decode (unsigned int msr)
+{
+       unsigned int multiplier;
+       unsigned int mv;
+
+       multiplier = ((msr >> 8) & 0xFF);
+
+       mv = (((msr & 0xFF) * 16) + 700);
+
+       printf("0x%x means multiplier %d @ %d mV\n", msr, multiplier, mv);
+}
+
+static int decode_live(unsigned int cpu)
+{
+       unsigned int lo, hi;
+       int err;
+
+       err = rdmsr(cpu, MSR_IA32_PERF_STATUS, &lo, &hi);
+
+       if (err) {
+               printf("can't get MSR_IA32_PERF_STATUS for cpu %d\n", cpu);
+               printf("Possible trouble: you don't run an Enhanced SpeedStep capable cpu\n");
+               printf("or you are not root, or the msr driver is not present\n");
+               return 1;
+       }
+
+       decode(lo);
+
+       return 0;
+}
+
+int main (int argc, char **argv)
+{
+       unsigned int cpu, mode = 0;
+
+       if (argc < 2)
+               cpu = 0;
+       else {
+               cpu = strtoul(argv[1], NULL, 0);
+               if (cpu >= MCPU)
+                       mode = 1;
+       }
+
+       if (mode)
+               decode(cpu);
+       else
+               decode_live(cpu);
+
+       return 0;
+}
diff --git a/tools/power/cpupower/debug/i386/dump_psb.c b/tools/power/cpupower/debug/i386/dump_psb.c
new file mode 100644 (file)
index 0000000..8d6a475
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * dump_psb. (c) 2004, Dave Jones, Red Hat Inc.
+ * Licensed under the GPL v2.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#include <sys/mman.h>
+
+#define LEN (0x100000 - 0xc0000)
+#define OFFSET (0xc0000)
+
+#ifndef __packed
+#define __packed __attribute((packed))
+#endif
+
+static long relevant;
+
+static const int fid_to_mult[32] = {
+       110, 115, 120, 125, 50, 55, 60, 65,
+       70, 75, 80, 85, 90, 95, 100, 105,
+       30, 190, 40, 200, 130, 135, 140, 210,
+       150, 225, 160, 165, 170, 180, -1, -1,
+};
+
+static const int vid_to_voltage[32] = {
+       2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
+       1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
+       1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
+       1075, 1050, 1024, 1000, 975, 950, 925, 0,
+};
+
+struct psb_header {
+       char signature[10];
+       u_char version;
+       u_char flags;
+       u_short settlingtime;
+       u_char res1;
+       u_char numpst;
+} __packed;
+
+struct pst_header {
+       u_int32_t cpuid;
+       u_char fsb;
+       u_char maxfid;
+       u_char startvid;
+       u_char numpstates;
+} __packed;
+
+static u_int fsb;
+static u_int sgtc;
+
+static int
+decode_pst(char *p, int npstates)
+{
+       int i;
+       int freq, fid, vid;
+
+       for (i = 0; i < npstates; ++i) {
+               fid = *p++;
+               vid = *p++;
+               freq = 100 * fid_to_mult[fid] * fsb;
+
+               printf("   %2d %8dkHz  FID %02x (%2d.%01d)  VID %02x (%4dmV)\n",
+                      i,
+                      freq,
+                      fid, fid_to_mult[fid]/10, fid_to_mult[fid]%10,
+                      vid, vid_to_voltage[vid]);
+       }
+
+       return 0;
+}
+
+static
+void decode_psb(char *p, int numpst)
+{
+       int i;
+       struct psb_header *psb;
+       struct pst_header *pst;
+
+       psb = (struct psb_header*) p;
+
+       if (psb->version != 0x12)
+               return;
+
+       printf("PSB version: %hhx flags: %hhx settling time %hhuus res1 %hhx num pst %hhu\n",
+                       psb->version,
+                       psb->flags,
+                       psb->settlingtime,
+                       psb->res1,
+                       psb->numpst);
+       sgtc = psb->settlingtime * 100;
+
+       if (sgtc < 10000)
+               sgtc = 10000;
+
+       p = ((char *) psb) + sizeof(struct psb_header);
+
+       if (numpst < 0)
+               numpst = psb->numpst;
+       else
+               printf("Overriding number of pst :%d\n", numpst);
+
+       for (i = 0; i < numpst; i++) {
+               pst = (struct pst_header*) p;
+
+               if (relevant != 0) {
+                       if (relevant!= pst->cpuid)
+                               goto next_one;
+               }
+
+               printf("  PST %d  cpuid %.3x fsb %hhu mfid %hhx svid %hhx numberstates %hhu\n",
+                               i+1,
+                               pst->cpuid,
+                               pst->fsb,
+                               pst->maxfid,
+                               pst->startvid,
+                               pst->numpstates);
+
+               fsb = pst->fsb;
+               decode_pst(p + sizeof(struct pst_header), pst->numpstates);
+
+next_one:
+               p += sizeof(struct pst_header) + 2*pst->numpstates;
+       }
+
+}
+
+static struct option info_opts[] = {
+       {.name = "numpst",      .has_arg=no_argument,   .flag=NULL, .val='n'},
+};
+
+void print_help(void)
+{
+       printf ("Usage: dump_psb [options]\n");
+       printf ("Options:\n");
+       printf ("  -n, --numpst     Set number of PST tables to scan\n");
+       printf ("  -r, --relevant   Only display PSTs relevant to cpuid N\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+       int fd;
+       int numpst=-1;
+       int ret=0, cont=1;
+       char *mem = NULL;
+       char *p;
+
+       do {
+               ret = getopt_long(argc, argv, "hr:n:", info_opts, NULL);
+               switch (ret){
+               case '?':
+               case 'h':
+                       print_help();
+                       cont = 0;
+                       break;
+               case 'r':
+                       relevant = strtol(optarg, NULL, 16);
+                       break;
+               case 'n':
+                       numpst = strtol(optarg, NULL, 10);
+                       break;
+               case -1:
+                       cont = 0;
+                       break;
+               }
+
+       } while(cont);
+
+       fd = open("/dev/mem", O_RDONLY);
+       if (fd < 0) {
+               printf ("Couldn't open /dev/mem. Are you root?\n");
+               exit(1);
+       }
+
+       mem = mmap(mem, 0x100000 - 0xc0000, PROT_READ, MAP_SHARED, fd, 0xc0000);
+       close(fd);
+
+       for (p = mem; p - mem < LEN; p+=16) {
+               if (memcmp(p, "AMDK7PNOW!", 10) == 0) {
+                       decode_psb(p, numpst);
+                       break;
+               }
+       }
+
+       munmap(mem, LEN);
+       return 0;
+}
diff --git a/tools/power/cpupower/debug/i386/intel_gsic.c b/tools/power/cpupower/debug/i386/intel_gsic.c
new file mode 100644 (file)
index 0000000..53f5293
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *  (C) 2003  Bruno Ducrot
+ *  (C) 2004  Dominik Brodowski <linux@dominikbrodowski.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ * Based on code found in
+ * linux/include/asm-i386/ist.h and linux/arch/i386/kernel/setup.c
+ * and originally developed by Andy Grover <andrew.grover@intel.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <lrmi.h>
+
+int main (void)
+{
+       struct LRMI_regs        r;
+       int                     retval;
+
+       if (!LRMI_init())
+               return 0;
+
+       memset(&r, 0, sizeof(r));
+
+       r.eax = 0x0000E980;
+       r.edx = 0x47534943;
+
+       retval = LRMI_int(0x15, &r);
+
+       if (!retval) {
+               printf("Failed!\n");
+               return 0;
+       }
+       if (r.eax == 0x47534943) {
+               printf("BIOS supports GSIC call:\n");
+               printf("\tsignature: %c%c%c%c\n",
+                      (r.eax >> 24) & 0xff,
+                      (r.eax >> 16) & 0xff,
+                      (r.eax >> 8) & 0xff,
+                      (r.eax) & 0xff);
+               printf("\tcommand port = 0x%.4x\n",
+                      r.ebx & 0xffff);
+               printf("\tcommand =      0x%.4x\n",
+                      (r.ebx >> 16) & 0xffff);
+               printf("\tevent port =   0x%.8x\n", r.ecx);
+               printf("\tflags =        0x%.8x\n", r.edx);
+               if (((r.ebx >> 16) & 0xffff) != 0x82) {
+                       printf("non-default command value. If speedstep-smi "
+                              "doesn't work out of the box,\nyou may want to "
+                              "try out the default value by passing "
+                              "smi_cmd=0x82 to the module\n ON YOUR OWN "
+                              "RISK.\n");
+               }
+               if ((r.ebx & 0xffff) != 0xb2) {
+                       printf("non-default command port. If speedstep-smi "
+                              "doesn't work out of the box,\nyou may want to "
+                              "try out the default value by passing "
+                              "smi_port=0x82 to the module\n ON YOUR OWN "
+                              "RISK.\n");
+               }
+       } else {
+               printf("BIOS DOES NOT support GSIC call.  Dumping registers anyway:\n");
+               printf("eax = 0x%.8x\n", r.eax);
+               printf("ebx = 0x%.8x\n", r.ebx);
+               printf("ecx = 0x%.8x\n", r.ecx);
+               printf("edx = 0x%.8x\n", r.edx);
+               printf("Note also that some BIOS do not support the initial "
+                      "GSIC call, but the newer\nspeeedstep-smi driver may "
+                      "work.\nFor this, you need to pass some arguments to "
+                      "the speedstep-smi driver:\n");
+               printf("\tsmi_cmd=0x?? smi_port=0x?? smi_sig=1\n");
+               printf("\nUnfortunately, you have to know what exactly are "
+                      "smi_cmd and smi_port, and this\nis system "
+                      "dependant.\n");
+       }
+       return 1;
+}
diff --git a/tools/power/cpupower/debug/i386/powernow-k8-decode.c b/tools/power/cpupower/debug/i386/powernow-k8-decode.c
new file mode 100644 (file)
index 0000000..638a6b3
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *  (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ * Based on code found in
+ * linux/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+ * and originally developed by Paul Devriendt
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define MCPU 32
+
+#define MSR_FIDVID_STATUS      0xc0010042
+
+#define MSR_S_HI_CURRENT_VID   0x0000001f
+#define MSR_S_LO_CURRENT_FID   0x0000003f
+
+static int get_fidvid(uint32_t cpu, uint32_t *fid, uint32_t *vid)
+{
+       int err = 1;
+       uint64_t msr = 0;
+       int fd;
+       char file[20];
+
+       if (cpu > MCPU)
+               goto out;
+
+       sprintf(file, "/dev/cpu/%d/msr", cpu);
+
+       fd = open(file, O_RDONLY);
+       if (fd < 0)
+               goto out;
+       lseek(fd, MSR_FIDVID_STATUS, SEEK_CUR);
+       if (read(fd, &msr, 8) != 8)
+               goto err1;
+
+       *fid = ((uint32_t )(msr & 0xffffffffull)) & MSR_S_LO_CURRENT_FID;
+       *vid = ((uint32_t )(msr>>32 & 0xffffffffull)) & MSR_S_HI_CURRENT_VID;
+       err = 0;
+err1:
+       close(fd);
+out:
+       return err;
+}
+
+
+/* Return a frequency in MHz, given an input fid */
+static uint32_t find_freq_from_fid(uint32_t fid)
+{
+       return 800 + (fid * 100);
+}
+
+/* Return a voltage in miliVolts, given an input vid */
+static uint32_t find_millivolts_from_vid(uint32_t vid)
+{
+       return 1550-vid*25;
+}
+
+int main (int argc, char *argv[])
+{
+       int err;
+       int cpu;
+       uint32_t fid, vid;
+
+       if (argc < 2)
+               cpu = 0;
+       else
+               cpu = strtoul(argv[1], NULL, 0);
+
+       err = get_fidvid(cpu, &fid, &vid);
+
+       if (err) {
+               printf("can't get fid, vid from MSR\n");
+               printf("Possible trouble: you don't run a powernow-k8 capable cpu\n");
+               printf("or you are not root, or the msr driver is not present\n");
+               exit(1);
+       }
+
+       
+       printf("cpu %d currently at %d MHz and %d mV\n",
+                       cpu,
+                       find_freq_from_fid(fid),
+                       find_millivolts_from_vid(vid));
+       
+       return 0;
+}
diff --git a/tools/power/cpupower/debug/kernel/Makefile b/tools/power/cpupower/debug/kernel/Makefile
new file mode 100644 (file)
index 0000000..96b146f
--- /dev/null
@@ -0,0 +1,23 @@
+obj-m  :=
+
+KDIR   := /lib/modules/$(shell uname -r)/build
+PWD            := $(shell pwd)
+KMISC   := /lib/modules/$(shell uname -r)/cpufrequtils/
+
+ifeq ("$(CONFIG_X86_TSC)", "y")
+  obj-m         += cpufreq-test_tsc.o
+endif
+
+default:
+       $(MAKE) -C $(KDIR) M=$(PWD)
+
+clean:
+       - rm -rf *.o *.ko .tmp-versions .*.cmd .*.mod.* *.mod.c
+       - rm -rf .tmp_versions* Module.symvers modules.order
+
+install: default
+       install -d $(KMISC)
+       install -m 644 -c *.ko $(KMISC)
+       /sbin/depmod -a
+
+all:   default
diff --git a/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c
new file mode 100644 (file)
index 0000000..66cace6
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * test module to check whether the TSC-based delay routine continues
+ * to work properly after cpufreq transitions. Needs ACPI to work
+ * properly.
+ *
+ * Based partly on the Power Management Timer (PMTMR) code to be found
+ * in arch/i386/kernel/timers/timer_pm.c on recent 2.6. kernels, especially
+ * code written by John Stultz. The read_pmtmr function was copied verbatim
+ * from that file.
+ *
+ * (C) 2004 Dominik Brodowski
+ *
+ * To use:
+ * 1.) pass clock=tsc to the kernel on your bootloader
+ * 2.) modprobe this module (it'll fail)
+ * 3.) change CPU frequency
+ * 4.) modprobe this module again
+ * 5.) if the third value, "diff_pmtmr", changes between 2. and 4., the
+ *     TSC-based delay routine on the Linux kernel does not correctly
+ *     handle the cpufreq transition. Please report this to
+ *     cpufreq@vger.kernel.org
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+static int pm_tmr_ioport = 0;
+
+/*helper function to safely read acpi pm timesource*/
+static u32 read_pmtmr(void)
+{
+       u32 v1=0,v2=0,v3=0;
+       /* It has been reported that because of various broken
+        * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time
+        * source is not latched, so you must read it multiple
+        * times to insure a safe value is read.
+        */
+       do {
+               v1 = inl(pm_tmr_ioport);
+               v2 = inl(pm_tmr_ioport);
+               v3 = inl(pm_tmr_ioport);
+       } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+                || (v3 > v1 && v3 < v2));
+
+       /* mask the output to 24 bits */
+       return (v2 & 0xFFFFFF);
+}
+
+static int __init cpufreq_test_tsc(void)
+{
+       u32 now, then, diff;
+       u64 now_tsc, then_tsc, diff_tsc;
+       int i;
+
+       /* the following code snipped is copied from arch/x86/kernel/acpi/boot.c
+          of Linux v2.6.25. */
+
+       /* detect the location of the ACPI PM Timer */
+       if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) {
+               /* FADT rev. 2 */
+               if (acpi_gbl_FADT.xpm_timer_block.space_id !=
+                   ACPI_ADR_SPACE_SYSTEM_IO)
+                       return 0;
+
+               pm_tmr_ioport = acpi_gbl_FADT.xpm_timer_block.address;
+               /*
+                * "X" fields are optional extensions to the original V1.0
+                * fields, so we must selectively expand V1.0 fields if the
+                * corresponding X field is zero.
+                */
+               if (!pm_tmr_ioport)
+                       pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
+       } else {
+               /* FADT rev. 1 */
+               pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
+       }
+
+       printk(KERN_DEBUG "start--> \n");
+       then = read_pmtmr();
+        rdtscll(then_tsc);
+       for (i=0;i<20;i++) {
+               mdelay(100);
+               now = read_pmtmr();
+               rdtscll(now_tsc);
+               diff = (now - then) & 0xFFFFFF;
+               diff_tsc = now_tsc - then_tsc;
+               printk(KERN_DEBUG "t1: %08u t2: %08u diff_pmtmr: %08u diff_tsc: %016llu\n", then, now, diff, diff_tsc);
+               then = now;
+               then_tsc = now_tsc;
+       }
+       printk(KERN_DEBUG "<-- end \n");
+       return -ENODEV;
+}
+
+static void __exit cpufreq_none(void)
+{
+       return;
+}
+
+module_init(cpufreq_test_tsc)
+module_exit(cpufreq_none)
+
+
+MODULE_AUTHOR("Dominik Brodowski");
+MODULE_DESCRIPTION("Verify the TSC cpufreq notifier working correctly -- needs ACPI-enabled system");
+MODULE_LICENSE ("GPL");
diff --git a/tools/power/cpupower/debug/x86_64/Makefile b/tools/power/cpupower/debug/x86_64/Makefile
new file mode 100644 (file)
index 0000000..dbf1399
--- /dev/null
@@ -0,0 +1,14 @@
+default: all
+
+centrino-decode: centrino-decode.c
+       $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c
+
+powernow-k8-decode: powernow-k8-decode.c
+       $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c
+
+all: centrino-decode powernow-k8-decode
+
+clean:
+       rm -rf centrino-decode powernow-k8-decode
+
+.PHONY: all default clean
diff --git a/tools/power/cpupower/debug/x86_64/centrino-decode.c b/tools/power/cpupower/debug/x86_64/centrino-decode.c
new file mode 120000 (symlink)
index 0000000..26fb3f1
--- /dev/null
@@ -0,0 +1 @@
+../i386/centrino-decode.c
\ No newline at end of file
diff --git a/tools/power/cpupower/debug/x86_64/powernow-k8-decode.c b/tools/power/cpupower/debug/x86_64/powernow-k8-decode.c
new file mode 120000 (symlink)
index 0000000..eb30c79
--- /dev/null
@@ -0,0 +1 @@
+../i386/powernow-k8-decode.c
\ No newline at end of file
diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c
new file mode 100644 (file)
index 0000000..d961101
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cpufreq.h"
+#include "sysfs.h"
+
+int cpufreq_cpu_exists(unsigned int cpu)
+{
+       return sysfs_cpu_exists(cpu);
+}
+
+unsigned long cpufreq_get_freq_kernel(unsigned int cpu)
+{
+       return sysfs_get_freq_kernel(cpu);
+}
+
+unsigned long cpufreq_get_freq_hardware(unsigned int cpu)
+{
+       return sysfs_get_freq_hardware(cpu);
+}
+
+unsigned long cpufreq_get_transition_latency(unsigned int cpu)
+{
+       return sysfs_get_freq_transition_latency(cpu);
+}
+
+int cpufreq_get_hardware_limits(unsigned int cpu,
+                               unsigned long *min,
+                               unsigned long *max)
+{
+       if ((!min) || (!max))
+               return -EINVAL;
+       return sysfs_get_freq_hardware_limits(cpu, min, max);
+}
+
+char *cpufreq_get_driver(unsigned int cpu)
+{
+       return sysfs_get_freq_driver(cpu);
+}
+
+void cpufreq_put_driver(char *ptr)
+{
+       if (!ptr)
+               return;
+       free(ptr);
+}
+
+struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu)
+{
+       return sysfs_get_freq_policy(cpu);
+}
+
+void cpufreq_put_policy(struct cpufreq_policy *policy)
+{
+       if ((!policy) || (!policy->governor))
+               return;
+
+       free(policy->governor);
+       policy->governor = NULL;
+       free(policy);
+}
+
+struct cpufreq_available_governors *cpufreq_get_available_governors(unsigned
+                                                               int cpu)
+{
+       return sysfs_get_freq_available_governors(cpu);
+}
+
+void cpufreq_put_available_governors(struct cpufreq_available_governors *any)
+{
+       struct cpufreq_available_governors *tmp, *next;
+
+       if (!any)
+               return;
+
+       tmp = any->first;
+       while (tmp) {
+               next = tmp->next;
+               if (tmp->governor)
+                       free(tmp->governor);
+               free(tmp);
+               tmp = next;
+       }
+}
+
+
+struct cpufreq_available_frequencies
+*cpufreq_get_available_frequencies(unsigned int cpu)
+{
+       return sysfs_get_available_frequencies(cpu);
+}
+
+void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies
+                               *any) {
+       struct cpufreq_available_frequencies *tmp, *next;
+
+       if (!any)
+               return;
+
+       tmp = any->first;
+       while (tmp) {
+               next = tmp->next;
+               free(tmp);
+               tmp = next;
+       }
+}
+
+
+struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned int cpu)
+{
+       return sysfs_get_freq_affected_cpus(cpu);
+}
+
+void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *any)
+{
+       struct cpufreq_affected_cpus *tmp, *next;
+
+       if (!any)
+               return;
+
+       tmp = any->first;
+       while (tmp) {
+               next = tmp->next;
+               free(tmp);
+               tmp = next;
+       }
+}
+
+
+struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned int cpu)
+{
+       return sysfs_get_freq_related_cpus(cpu);
+}
+
+void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *any)
+{
+       cpufreq_put_affected_cpus(any);
+}
+
+
+int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy)
+{
+       if (!policy || !(policy->governor))
+               return -EINVAL;
+
+       return sysfs_set_freq_policy(cpu, policy);
+}
+
+
+int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq)
+{
+       return sysfs_modify_freq_policy_min(cpu, min_freq);
+}
+
+
+int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq)
+{
+       return sysfs_modify_freq_policy_max(cpu, max_freq);
+}
+
+
+int cpufreq_modify_policy_governor(unsigned int cpu, char *governor)
+{
+       if ((!governor) || (strlen(governor) > 19))
+               return -EINVAL;
+
+       return sysfs_modify_freq_policy_governor(cpu, governor);
+}
+
+int cpufreq_set_frequency(unsigned int cpu, unsigned long target_frequency)
+{
+       return sysfs_set_frequency(cpu, target_frequency);
+}
+
+struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu,
+                                       unsigned long long *total_time)
+{
+       return sysfs_get_freq_stats(cpu, total_time);
+}
+
+void cpufreq_put_stats(struct cpufreq_stats *any)
+{
+       struct cpufreq_stats *tmp, *next;
+
+       if (!any)
+               return;
+
+       tmp = any->first;
+       while (tmp) {
+               next = tmp->next;
+               free(tmp);
+               tmp = next;
+       }
+}
+
+unsigned long cpufreq_get_transitions(unsigned int cpu)
+{
+       return sysfs_get_freq_transitions(cpu);
+}
diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h
new file mode 100644 (file)
index 0000000..3aae8e7
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ *  cpufreq.h - definitions for libcpufreq
+ *
+ *  Copyright (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _CPUFREQ_H
+#define _CPUFREQ_H 1
+
+struct cpufreq_policy {
+       unsigned long min;
+       unsigned long max;
+       char *governor;
+};
+
+struct cpufreq_available_governors {
+       char *governor;
+       struct cpufreq_available_governors *next;
+       struct cpufreq_available_governors *first;
+};
+
+struct cpufreq_available_frequencies {
+       unsigned long frequency;
+       struct cpufreq_available_frequencies *next;
+       struct cpufreq_available_frequencies *first;
+};
+
+
+struct cpufreq_affected_cpus {
+       unsigned int cpu;
+       struct cpufreq_affected_cpus *next;
+       struct cpufreq_affected_cpus *first;
+};
+
+struct cpufreq_stats {
+       unsigned long frequency;
+       unsigned long long time_in_state;
+       struct cpufreq_stats *next;
+       struct cpufreq_stats *first;
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * returns 0 if the specified CPU is present (it doesn't say
+ * whether it is online!), and an error value if not.
+ */
+
+extern int cpufreq_cpu_exists(unsigned int cpu);
+
+/* determine current CPU frequency
+ * - _kernel variant means kernel's opinion of CPU frequency
+ * - _hardware variant means actual hardware CPU frequency,
+ *    which is only available to root.
+ *
+ * returns 0 on failure, else frequency in kHz.
+ */
+
+extern unsigned long cpufreq_get_freq_kernel(unsigned int cpu);
+
+extern unsigned long cpufreq_get_freq_hardware(unsigned int cpu);
+
+#define cpufreq_get(cpu) cpufreq_get_freq_kernel(cpu);
+
+
+/* determine CPU transition latency
+ *
+ * returns 0 on failure, else transition latency in 10^(-9) s = nanoseconds
+ */
+extern unsigned long cpufreq_get_transition_latency(unsigned int cpu);
+
+
+/* determine hardware CPU frequency limits
+ *
+ * These may be limited further by thermal, energy or other
+ * considerations by cpufreq policy notifiers in the kernel.
+ */
+
+extern int cpufreq_get_hardware_limits(unsigned int cpu,
+                               unsigned long *min,
+                               unsigned long *max);
+
+
+/* determine CPUfreq driver used
+ *
+ * Remember to call cpufreq_put_driver when no longer needed
+ * to avoid memory leakage, please.
+ */
+
+extern char *cpufreq_get_driver(unsigned int cpu);
+
+extern void cpufreq_put_driver(char *ptr);
+
+
+/* determine CPUfreq policy currently used
+ *
+ * Remember to call cpufreq_put_policy when no longer needed
+ * to avoid memory leakage, please.
+ */
+
+
+extern struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu);
+
+extern void cpufreq_put_policy(struct cpufreq_policy *policy);
+
+
+/* determine CPUfreq governors currently available
+ *
+ * may be modified by modprobe'ing or rmmod'ing other governors. Please
+ * free allocated memory by calling cpufreq_put_available_governors
+ * after use.
+ */
+
+
+extern struct cpufreq_available_governors
+*cpufreq_get_available_governors(unsigned int cpu);
+
+extern void cpufreq_put_available_governors(
+       struct cpufreq_available_governors *first);
+
+
+/* determine CPU frequency states available
+ *
+ * Only present on _some_ ->target() cpufreq drivers. For information purposes
+ * only. Please free allocated memory by calling
+ * cpufreq_put_available_frequencies after use.
+ */
+
+extern struct cpufreq_available_frequencies
+*cpufreq_get_available_frequencies(unsigned int cpu);
+
+extern void cpufreq_put_available_frequencies(
+               struct cpufreq_available_frequencies *first);
+
+
+/* determine affected CPUs
+ *
+ * Remember to call cpufreq_put_affected_cpus when no longer needed
+ * to avoid memory leakage, please.
+ */
+
+extern struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned
+                                                       int cpu);
+
+extern void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *first);
+
+
+/* determine related CPUs
+ *
+ * Remember to call cpufreq_put_related_cpus when no longer needed
+ * to avoid memory leakage, please.
+ */
+
+extern struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned
+                                                       int cpu);
+
+extern void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *first);
+
+
+/* determine stats for cpufreq subsystem
+ *
+ * This is not available in all kernel versions or configurations.
+ */
+
+extern struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu,
+                                       unsigned long long *total_time);
+
+extern void cpufreq_put_stats(struct cpufreq_stats *stats);
+
+extern unsigned long cpufreq_get_transitions(unsigned int cpu);
+
+
+/* set new cpufreq policy
+ *
+ * Tries to set the passed policy as new policy as close as possible,
+ * but results may differ depending e.g. on governors being available.
+ */
+
+extern int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy);
+
+
+/* modify a policy by only changing min/max freq or governor
+ *
+ * Does not check whether result is what was intended.
+ */
+
+extern int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq);
+extern int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq);
+extern int cpufreq_modify_policy_governor(unsigned int cpu, char *governor);
+
+
+/* set a specific frequency
+ *
+ * Does only work if userspace governor can be used and no external
+ * interference (other calls to this function or to set/modify_policy)
+ * occurs. Also does not work on ->range() cpufreq drivers.
+ */
+
+extern int cpufreq_set_frequency(unsigned int cpu,
+                               unsigned long target_frequency);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CPUFREQ_H */
diff --git a/tools/power/cpupower/lib/sysfs.c b/tools/power/cpupower/lib/sysfs.c
new file mode 100644 (file)
index 0000000..870713a
--- /dev/null
@@ -0,0 +1,672 @@
+/*
+ *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "cpufreq.h"
+
+#define PATH_TO_CPU "/sys/devices/system/cpu/"
+#define MAX_LINE_LEN 4096
+#define SYSFS_PATH_MAX 255
+
+
+static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
+{
+       int fd;
+       ssize_t numread;
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+               return 0;
+
+       numread = read(fd, buf, buflen - 1);
+       if (numread < 1) {
+               close(fd);
+               return 0;
+       }
+
+       buf[numread] = '\0';
+       close(fd);
+
+       return (unsigned int) numread;
+}
+
+
+/* CPUFREQ sysfs access **************************************************/
+
+/* helper function to read file from /sys into given buffer */
+/* fname is a relative path under "cpuX/cpufreq" dir */
+static unsigned int sysfs_cpufreq_read_file(unsigned int cpu, const char *fname,
+                                           char *buf, size_t buflen)
+{
+       char path[SYSFS_PATH_MAX];
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s",
+                        cpu, fname);
+       return sysfs_read_file(path, buf, buflen);
+}
+
+/* helper function to write a new value to a /sys file */
+/* fname is a relative path under "cpuX/cpufreq" dir */
+static unsigned int sysfs_cpufreq_write_file(unsigned int cpu,
+                                            const char *fname,
+                                            const char *value, size_t len)
+{
+       char path[SYSFS_PATH_MAX];
+       int fd;
+       ssize_t numwrite;
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s",
+                        cpu, fname);
+
+       fd = open(path, O_WRONLY);
+       if (fd == -1)
+               return 0;
+
+       numwrite = write(fd, value, len);
+       if (numwrite < 1) {
+               close(fd);
+               return 0;
+       }
+
+       close(fd);
+
+       return (unsigned int) numwrite;
+}
+
+/* read access to files which contain one numeric value */
+
+enum cpufreq_value {
+       CPUINFO_CUR_FREQ,
+       CPUINFO_MIN_FREQ,
+       CPUINFO_MAX_FREQ,
+       CPUINFO_LATENCY,
+       SCALING_CUR_FREQ,
+       SCALING_MIN_FREQ,
+       SCALING_MAX_FREQ,
+       STATS_NUM_TRANSITIONS,
+       MAX_CPUFREQ_VALUE_READ_FILES
+};
+
+static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = {
+       [CPUINFO_CUR_FREQ] = "cpuinfo_cur_freq",
+       [CPUINFO_MIN_FREQ] = "cpuinfo_min_freq",
+       [CPUINFO_MAX_FREQ] = "cpuinfo_max_freq",
+       [CPUINFO_LATENCY]  = "cpuinfo_transition_latency",
+       [SCALING_CUR_FREQ] = "scaling_cur_freq",
+       [SCALING_MIN_FREQ] = "scaling_min_freq",
+       [SCALING_MAX_FREQ] = "scaling_max_freq",
+       [STATS_NUM_TRANSITIONS] = "stats/total_trans"
+};
+
+
+static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu,
+                                                enum cpufreq_value which)
+{
+       unsigned long value;
+       unsigned int len;
+       char linebuf[MAX_LINE_LEN];
+       char *endp;
+
+       if (which >= MAX_CPUFREQ_VALUE_READ_FILES)
+               return 0;
+
+       len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which],
+                               linebuf, sizeof(linebuf));
+
+       if (len == 0)
+               return 0;
+
+       value = strtoul(linebuf, &endp, 0);
+
+       if (endp == linebuf || errno == ERANGE)
+               return 0;
+
+       return value;
+}
+
+/* read access to files which contain one string */
+
+enum cpufreq_string {
+       SCALING_DRIVER,
+       SCALING_GOVERNOR,
+       MAX_CPUFREQ_STRING_FILES
+};
+
+static const char *cpufreq_string_files[MAX_CPUFREQ_STRING_FILES] = {
+       [SCALING_DRIVER] = "scaling_driver",
+       [SCALING_GOVERNOR] = "scaling_governor",
+};
+
+
+static char *sysfs_cpufreq_get_one_string(unsigned int cpu,
+                                          enum cpufreq_string which)
+{
+       char linebuf[MAX_LINE_LEN];
+       char *result;
+       unsigned int len;
+
+       if (which >= MAX_CPUFREQ_STRING_FILES)
+               return NULL;
+
+       len = sysfs_cpufreq_read_file(cpu, cpufreq_string_files[which],
+                               linebuf, sizeof(linebuf));
+       if (len == 0)
+               return NULL;
+
+       result = strdup(linebuf);
+       if (result == NULL)
+               return NULL;
+
+       if (result[strlen(result) - 1] == '\n')
+               result[strlen(result) - 1] = '\0';
+
+       return result;
+}
+
+/* write access */
+
+enum cpufreq_write {
+       WRITE_SCALING_MIN_FREQ,
+       WRITE_SCALING_MAX_FREQ,
+       WRITE_SCALING_GOVERNOR,
+       WRITE_SCALING_SET_SPEED,
+       MAX_CPUFREQ_WRITE_FILES
+};
+
+static const char *cpufreq_write_files[MAX_CPUFREQ_WRITE_FILES] = {
+       [WRITE_SCALING_MIN_FREQ] = "scaling_min_freq",
+       [WRITE_SCALING_MAX_FREQ] = "scaling_max_freq",
+       [WRITE_SCALING_GOVERNOR] = "scaling_governor",
+       [WRITE_SCALING_SET_SPEED] = "scaling_setspeed",
+};
+
+static int sysfs_cpufreq_write_one_value(unsigned int cpu,
+                                        enum cpufreq_write which,
+                                        const char *new_value, size_t len)
+{
+       if (which >= MAX_CPUFREQ_WRITE_FILES)
+               return 0;
+
+       if (sysfs_cpufreq_write_file(cpu, cpufreq_write_files[which],
+                                       new_value, len) != len)
+               return -ENODEV;
+
+       return 0;
+};
+
+unsigned long sysfs_get_freq_kernel(unsigned int cpu)
+{
+       return sysfs_cpufreq_get_one_value(cpu, SCALING_CUR_FREQ);
+}
+
+unsigned long sysfs_get_freq_hardware(unsigned int cpu)
+{
+       return sysfs_cpufreq_get_one_value(cpu, CPUINFO_CUR_FREQ);
+}
+
+unsigned long sysfs_get_freq_transition_latency(unsigned int cpu)
+{
+       return sysfs_cpufreq_get_one_value(cpu, CPUINFO_LATENCY);
+}
+
+int sysfs_get_freq_hardware_limits(unsigned int cpu,
+                             unsigned long *min,
+                             unsigned long *max)
+{
+       if ((!min) || (!max))
+               return -EINVAL;
+
+       *min = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MIN_FREQ);
+       if (!*min)
+               return -ENODEV;
+
+       *max = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MAX_FREQ);
+       if (!*max)
+               return -ENODEV;
+
+       return 0;
+}
+
+char *sysfs_get_freq_driver(unsigned int cpu)
+{
+       return sysfs_cpufreq_get_one_string(cpu, SCALING_DRIVER);
+}
+
+struct cpufreq_policy *sysfs_get_freq_policy(unsigned int cpu)
+{
+       struct cpufreq_policy *policy;
+
+       policy = malloc(sizeof(struct cpufreq_policy));
+       if (!policy)
+               return NULL;
+
+       policy->governor = sysfs_cpufreq_get_one_string(cpu, SCALING_GOVERNOR);
+       if (!policy->governor) {
+               free(policy);
+               return NULL;
+       }
+       policy->min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ);
+       policy->max = sysfs_cpufreq_get_one_value(cpu, SCALING_MAX_FREQ);
+       if ((!policy->min) || (!policy->max)) {
+               free(policy->governor);
+               free(policy);
+               return NULL;
+       }
+
+       return policy;
+}
+
+struct cpufreq_available_governors *
+sysfs_get_freq_available_governors(unsigned int cpu) {
+       struct cpufreq_available_governors *first = NULL;
+       struct cpufreq_available_governors *current = NULL;
+       char linebuf[MAX_LINE_LEN];
+       unsigned int pos, i;
+       unsigned int len;
+
+       len = sysfs_cpufreq_read_file(cpu, "scaling_available_governors",
+                               linebuf, sizeof(linebuf));
+       if (len == 0)
+               return NULL;
+
+       pos = 0;
+       for (i = 0; i < len; i++) {
+               if (linebuf[i] == ' ' || linebuf[i] == '\n') {
+                       if (i - pos < 2)
+                               continue;
+                       if (current) {
+                               current->next = malloc(sizeof(*current));
+                               if (!current->next)
+                                       goto error_out;
+                               current = current->next;
+                       } else {
+                               first = malloc(sizeof(*first));
+                               if (!first)
+                                       goto error_out;
+                               current = first;
+                       }
+                       current->first = first;
+                       current->next = NULL;
+
+                       current->governor = malloc(i - pos + 1);
+                       if (!current->governor)
+                               goto error_out;
+
+                       memcpy(current->governor, linebuf + pos, i - pos);
+                       current->governor[i - pos] = '\0';
+                       pos = i + 1;
+               }
+       }
+
+       return first;
+
+ error_out:
+       while (first) {
+               current = first->next;
+               if (first->governor)
+                       free(first->governor);
+               free(first);
+               first = current;
+       }
+       return NULL;
+}
+
+
+struct cpufreq_available_frequencies *
+sysfs_get_available_frequencies(unsigned int cpu) {
+       struct cpufreq_available_frequencies *first = NULL;
+       struct cpufreq_available_frequencies *current = NULL;
+       char one_value[SYSFS_PATH_MAX];
+       char linebuf[MAX_LINE_LEN];
+       unsigned int pos, i;
+       unsigned int len;
+
+       len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies",
+                               linebuf, sizeof(linebuf));
+       if (len == 0)
+               return NULL;
+
+       pos = 0;
+       for (i = 0; i < len; i++) {
+               if (linebuf[i] == ' ' || linebuf[i] == '\n') {
+                       if (i - pos < 2)
+                               continue;
+                       if (i - pos >= SYSFS_PATH_MAX)
+                               goto error_out;
+                       if (current) {
+                               current->next = malloc(sizeof(*current));
+                               if (!current->next)
+                                       goto error_out;
+                               current = current->next;
+                       } else {
+                               first = malloc(sizeof(*first));
+                               if (!first)
+                                       goto error_out;
+                               current = first;
+                       }
+                       current->first = first;
+                       current->next = NULL;
+
+                       memcpy(one_value, linebuf + pos, i - pos);
+                       one_value[i - pos] = '\0';
+                       if (sscanf(one_value, "%lu", &current->frequency) != 1)
+                               goto error_out;
+
+                       pos = i + 1;
+               }
+       }
+
+       return first;
+
+ error_out:
+       while (first) {
+               current = first->next;
+               free(first);
+               first = current;
+       }
+       return NULL;
+}
+
+static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu,
+                                                       const char *file)
+{
+       struct cpufreq_affected_cpus *first = NULL;
+       struct cpufreq_affected_cpus *current = NULL;
+       char one_value[SYSFS_PATH_MAX];
+       char linebuf[MAX_LINE_LEN];
+       unsigned int pos, i;
+       unsigned int len;
+
+       len = sysfs_cpufreq_read_file(cpu, file, linebuf, sizeof(linebuf));
+       if (len == 0)
+               return NULL;
+
+       pos = 0;
+       for (i = 0; i < len; i++) {
+               if (i == len || linebuf[i] == ' ' || linebuf[i] == '\n') {
+                       if (i - pos  < 1)
+                               continue;
+                       if (i - pos >= SYSFS_PATH_MAX)
+                               goto error_out;
+                       if (current) {
+                               current->next = malloc(sizeof(*current));
+                               if (!current->next)
+                                       goto error_out;
+                               current = current->next;
+                       } else {
+                               first = malloc(sizeof(*first));
+                               if (!first)
+                                       goto error_out;
+                               current = first;
+                       }
+                       current->first = first;
+                       current->next = NULL;
+
+                       memcpy(one_value, linebuf + pos, i - pos);
+                       one_value[i - pos] = '\0';
+
+                       if (sscanf(one_value, "%u", &current->cpu) != 1)
+                               goto error_out;
+
+                       pos = i + 1;
+               }
+       }
+
+       return first;
+
+ error_out:
+       while (first) {
+               current = first->next;
+               free(first);
+               first = current;
+       }
+       return NULL;
+}
+
+struct cpufreq_affected_cpus *sysfs_get_freq_affected_cpus(unsigned int cpu)
+{
+       return sysfs_get_cpu_list(cpu, "affected_cpus");
+}
+
+struct cpufreq_affected_cpus *sysfs_get_freq_related_cpus(unsigned int cpu)
+{
+       return sysfs_get_cpu_list(cpu, "related_cpus");
+}
+
+struct cpufreq_stats *sysfs_get_freq_stats(unsigned int cpu,
+                                       unsigned long long *total_time) {
+       struct cpufreq_stats *first = NULL;
+       struct cpufreq_stats *current = NULL;
+       char one_value[SYSFS_PATH_MAX];
+       char linebuf[MAX_LINE_LEN];
+       unsigned int pos, i;
+       unsigned int len;
+
+       len = sysfs_cpufreq_read_file(cpu, "stats/time_in_state",
+                               linebuf, sizeof(linebuf));
+       if (len == 0)
+               return NULL;
+
+       *total_time = 0;
+       pos = 0;
+       for (i = 0; i < len; i++) {
+               if (i == strlen(linebuf) || linebuf[i] == '\n') {
+                       if (i - pos < 2)
+                               continue;
+                       if ((i - pos) >= SYSFS_PATH_MAX)
+                               goto error_out;
+                       if (current) {
+                               current->next = malloc(sizeof(*current));
+                               if (!current->next)
+                                       goto error_out;
+                               current = current->next;
+                       } else {
+                               first = malloc(sizeof(*first));
+                               if (!first)
+                                       goto error_out;
+                               current = first;
+                       }
+                       current->first = first;
+                       current->next = NULL;
+
+                       memcpy(one_value, linebuf + pos, i - pos);
+                       one_value[i - pos] = '\0';
+                       if (sscanf(one_value, "%lu %llu",
+                                       &current->frequency,
+                                       &current->time_in_state) != 2)
+                               goto error_out;
+
+                       *total_time = *total_time + current->time_in_state;
+                       pos = i + 1;
+               }
+       }
+
+       return first;
+
+ error_out:
+       while (first) {
+               current = first->next;
+               free(first);
+               first = current;
+       }
+       return NULL;
+}
+
+unsigned long sysfs_get_freq_transitions(unsigned int cpu)
+{
+       return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS);
+}
+
+static int verify_gov(char *new_gov, char *passed_gov)
+{
+       unsigned int i, j = 0;
+
+       if (!passed_gov || (strlen(passed_gov) > 19))
+               return -EINVAL;
+
+       strncpy(new_gov, passed_gov, 20);
+       for (i = 0; i < 20; i++) {
+               if (j) {
+                       new_gov[i] = '\0';
+                       continue;
+               }
+               if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z'))
+                       continue;
+
+               if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z'))
+                       continue;
+
+               if (new_gov[i] == '-')
+                       continue;
+
+               if (new_gov[i] == '_')
+                       continue;
+
+               if (new_gov[i] == '\0') {
+                       j = 1;
+                       continue;
+               }
+               return -EINVAL;
+       }
+       new_gov[19] = '\0';
+       return 0;
+}
+
+int sysfs_modify_freq_policy_governor(unsigned int cpu, char *governor)
+{
+       char new_gov[SYSFS_PATH_MAX];
+
+       if (!governor)
+               return -EINVAL;
+
+       if (verify_gov(new_gov, governor))
+               return -EINVAL;
+
+       return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR,
+                                            new_gov, strlen(new_gov));
+};
+
+int sysfs_modify_freq_policy_max(unsigned int cpu, unsigned long max_freq)
+{
+       char value[SYSFS_PATH_MAX];
+
+       snprintf(value, SYSFS_PATH_MAX, "%lu", max_freq);
+
+       return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ,
+                                            value, strlen(value));
+};
+
+
+int sysfs_modify_freq_policy_min(unsigned int cpu, unsigned long min_freq)
+{
+       char value[SYSFS_PATH_MAX];
+
+       snprintf(value, SYSFS_PATH_MAX, "%lu", min_freq);
+
+       return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ,
+                                            value, strlen(value));
+};
+
+
+int sysfs_set_freq_policy(unsigned int cpu, struct cpufreq_policy *policy)
+{
+       char min[SYSFS_PATH_MAX];
+       char max[SYSFS_PATH_MAX];
+       char gov[SYSFS_PATH_MAX];
+       int ret;
+       unsigned long old_min;
+       int write_max_first;
+
+       if (!policy || !(policy->governor))
+               return -EINVAL;
+
+       if (policy->max < policy->min)
+               return -EINVAL;
+
+       if (verify_gov(gov, policy->governor))
+               return -EINVAL;
+
+       snprintf(min, SYSFS_PATH_MAX, "%lu", policy->min);
+       snprintf(max, SYSFS_PATH_MAX, "%lu", policy->max);
+
+       old_min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ);
+       write_max_first = (old_min && (policy->max < old_min) ? 0 : 1);
+
+       if (write_max_first) {
+               ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ,
+                                                   max, strlen(max));
+               if (ret)
+                       return ret;
+       }
+
+       ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, min,
+                                           strlen(min));
+       if (ret)
+               return ret;
+
+       if (!write_max_first) {
+               ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ,
+                                                   max, strlen(max));
+               if (ret)
+                       return ret;
+       }
+
+       return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR,
+                                            gov, strlen(gov));
+}
+
+int sysfs_set_frequency(unsigned int cpu, unsigned long target_frequency)
+{
+       struct cpufreq_policy *pol = sysfs_get_freq_policy(cpu);
+       char userspace_gov[] = "userspace";
+       char freq[SYSFS_PATH_MAX];
+       int ret;
+
+       if (!pol)
+               return -ENODEV;
+
+       if (strncmp(pol->governor, userspace_gov, 9) != 0) {
+               ret = sysfs_modify_freq_policy_governor(cpu, userspace_gov);
+               if (ret) {
+                       cpufreq_put_policy(pol);
+                       return ret;
+               }
+       }
+
+       cpufreq_put_policy(pol);
+
+       snprintf(freq, SYSFS_PATH_MAX, "%lu", target_frequency);
+
+       return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_SET_SPEED,
+                                            freq, strlen(freq));
+}
+
+/* CPUFREQ sysfs access **************************************************/
+
+/* General sysfs access **************************************************/
+int sysfs_cpu_exists(unsigned int cpu)
+{
+       char file[SYSFS_PATH_MAX];
+       struct stat statbuf;
+
+       snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/", cpu);
+
+       if (stat(file, &statbuf) != 0)
+               return -ENOSYS;
+
+       return S_ISDIR(statbuf.st_mode) ? 0 : -ENOSYS;
+}
+
+/* General sysfs access **************************************************/
diff --git a/tools/power/cpupower/lib/sysfs.h b/tools/power/cpupower/lib/sysfs.h
new file mode 100644 (file)
index 0000000..c76a5e0
--- /dev/null
@@ -0,0 +1,31 @@
+/* General */
+extern unsigned int sysfs_cpu_exists(unsigned int cpu);
+
+/* CPUfreq */
+extern unsigned long sysfs_get_freq_kernel(unsigned int cpu);
+extern unsigned long sysfs_get_freq_hardware(unsigned int cpu);
+extern unsigned long sysfs_get_freq_transition_latency(unsigned int cpu);
+extern int sysfs_get_freq_hardware_limits(unsigned int cpu,
+                                       unsigned long *min, unsigned long *max);
+extern char *sysfs_get_freq_driver(unsigned int cpu);
+extern struct cpufreq_policy *sysfs_get_freq_policy(unsigned int cpu);
+extern struct cpufreq_available_governors *sysfs_get_freq_available_governors(
+       unsigned int cpu);
+extern struct cpufreq_available_frequencies *sysfs_get_available_frequencies(
+       unsigned int cpu);
+extern struct cpufreq_affected_cpus *sysfs_get_freq_affected_cpus(
+       unsigned int cpu);
+extern struct cpufreq_affected_cpus *sysfs_get_freq_related_cpus(
+       unsigned int cpu);
+extern struct cpufreq_stats *sysfs_get_freq_stats(unsigned int cpu,
+                                               unsigned long long *total_time);
+extern unsigned long sysfs_get_freq_transitions(unsigned int cpu);
+extern int sysfs_set_freq_policy(unsigned int cpu,
+                               struct cpufreq_policy *policy);
+extern int sysfs_modify_freq_policy_min(unsigned int cpu,
+                                       unsigned long min_freq);
+extern int sysfs_modify_freq_policy_max(unsigned int cpu,
+                                       unsigned long max_freq);
+extern int sysfs_modify_freq_policy_governor(unsigned int cpu, char *governor);
+extern int sysfs_set_frequency(unsigned int cpu,
+                       unsigned long target_frequency);
diff --git a/tools/power/cpupower/man/cpupower-frequency-info.1 b/tools/power/cpupower/man/cpupower-frequency-info.1
new file mode 100644 (file)
index 0000000..3194811
--- /dev/null
@@ -0,0 +1,76 @@
+.TH "cpufreq-info" "1" "0.1" "Mattia Dongili" ""
+.SH "NAME"
+.LP 
+cpufreq\-info \- Utility to retrieve cpufreq kernel information
+.SH "SYNTAX"
+.LP 
+cpufreq\-info [\fIoptions\fP]
+.SH "DESCRIPTION"
+.LP 
+A small tool which prints out cpufreq information helpful to developers and interested users.
+.SH "OPTIONS"
+.LP 
+.TP  
+\fB\-e\fR \fB\-\-debug\fR
+Prints out debug information.
+.TP  
+\fB\-f\fR \fB\-\-freq\fR
+Get frequency the CPU currently runs at, according to the cpufreq core.
+.TP  
+\fB\-w\fR \fB\-\-hwfreq\fR
+Get frequency the CPU currently runs at, by reading it from hardware (only available to root).
+.TP  
+\fB\-l\fR \fB\-\-hwlimits\fR
+Determine the minimum and maximum CPU frequency allowed.
+.TP  
+\fB\-d\fR \fB\-\-driver\fR
+Determines the used cpufreq kernel driver.
+.TP  
+\fB\-p\fR \fB\-\-policy\fR
+Gets the currently used cpufreq policy.
+.TP  
+\fB\-g\fR \fB\-\-governors\fR
+Determines available cpufreq governors.
+.TP  
+\fB\-a\fR \fB\-\-related\-cpus\fR
+Determines which CPUs run at the same hardware frequency.
+.TP  
+\fB\-a\fR \fB\-\-affected\-cpus\fR
+Determines which CPUs need to have their frequency coordinated by software.
+.TP  
+\fB\-s\fR \fB\-\-stats\fR
+Shows cpufreq statistics if available.
+.TP  
+\fB\-y\fR \fB\-\-latency\fR
+Determines the maximum latency on CPU frequency changes.
+.TP  
+\fB\-o\fR \fB\-\-proc\fR
+Prints out information like provided by the /proc/cpufreq interface in 2.4. and early 2.6. kernels.
+.TP  
+\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
+other cores is described in the cpupower(1) manpage in the \-\-cpu option section.
+.LP 
+You can't specify more than one of the output specific options \-o \-e \-a \-g \-p \-d \-l \-w \-f \-y.
+.LP 
+You also can't specify the \-o option combined with the \-c option.
+.SH "FILES"
+.nf 
+\fI/sys/devices/system/cpu/cpu*/cpufreq/\fP  
+\fI/proc/cpufreq\fP (deprecated) 
+\fI/proc/sys/cpu/\fP (deprecated)
+.fi 
+.SH "AUTHORS"
+.nf
+Dominik Brodowski <linux@brodo.de> \- author 
+Mattia Dongili<malattia@gmail.com> \- first autolibtoolization
+.fi
+.SH "SEE ALSO"
+.LP 
+cpupower\-frequency\-set(1), cpupower(1)
diff --git a/tools/power/cpupower/man/cpupower-frequency-set.1 b/tools/power/cpupower/man/cpupower-frequency-set.1
new file mode 100644 (file)
index 0000000..26e3e13
--- /dev/null
@@ -0,0 +1,54 @@
+.TH "cpufreq-set" "1" "0.1" "Mattia Dongili" ""
+.SH "NAME"
+.LP 
+cpufreq\-set \- A small tool which allows to modify cpufreq settings.
+.SH "SYNTAX"
+.LP 
+cpufreq\-set [\fIoptions\fP]
+.SH "DESCRIPTION"
+.LP 
+cpufreq\-set allows you to modify cpufreq settings without having to type e.g. "/sys/devices/system/cpu/cpu0/cpufreq/scaling_set_speed" all the time.
+.SH "OPTIONS"
+.LP 
+.TP 
+\fB\-d\fR \fB\-\-min\fR <FREQ>
+new minimum CPU frequency the governor may select.
+.TP 
+\fB\-u\fR \fB\-\-max\fR <FREQ>
+new maximum CPU frequency the governor may select.
+.TP 
+\fB\-g\fR \fB\-\-governor\fR <GOV>
+new cpufreq governor.
+.TP 
+\fB\-f\fR \fB\-\-freq\fR <FREQ>
+specific frequency to be set. Requires userspace governor to be available and loaded.
+.TP 
+\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
+configurations is described in the cpupower(1) manpage in the \-\-cpu option section.
+.LP 
+The \-f FREQ, \-\-freq FREQ parameter cannot be combined with any other parameter.
+.LP 
+FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz by postfixing the value with the wanted unit name, without any space (frequency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).
+.LP 
+On Linux kernels up to 2.6.29, the \-r or \-\-related parameter is ignored.
+.SH "FILES" 
+.nf
+\fI/sys/devices/system/cpu/cpu*/cpufreq/\fP  
+\fI/proc/cpufreq\fP (deprecated) 
+\fI/proc/sys/cpu/\fP (deprecated)
+.fi 
+.SH "AUTHORS"
+.nf 
+Dominik Brodowski <linux@brodo.de> \- author 
+Mattia Dongili<malattia@gmail.com> \- first autolibtoolization
+.fi
+.SH "SEE ALSO"
+.LP 
+cpupower\-frequency\-info(1), cpupower(1)
diff --git a/tools/power/cpupower/man/cpupower-info.1 b/tools/power/cpupower/man/cpupower-info.1
new file mode 100644 (file)
index 0000000..58e2119
--- /dev/null
@@ -0,0 +1,19 @@
+.TH CPUPOWER\-INFO "1" "22/02/2011" "" "cpupower Manual"
+.SH NAME
+cpupower\-info \- Shows processor power related kernel or hardware configurations
+.SH SYNOPSIS
+.ft B
+.B cpupower info [ \-b ] [ \-s ] [ \-m ]
+
+.SH DESCRIPTION
+\fBcpupower info \fP shows kernel configurations or processor hardware
+registers affecting processor power saving policies.
+
+Some options are platform wide, some affect single cores. By default values
+of core zero are displayed only. cpupower --cpu all cpuinfo will show the
+settings of all cores, see cpupower(1) how to choose specific cores.
+
+.SH "SEE ALSO"
+Options are described in detail in:
+
+cpupower(1), cpupower-set(1)
diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1
new file mode 100644 (file)
index 0000000..d5cfa26
--- /dev/null
@@ -0,0 +1,179 @@
+.TH CPUPOWER\-MONITOR "1" "22/02/2011" "" "cpupower Manual"
+.SH NAME
+cpupower\-monitor \- Report processor frequency and idle statistics
+.SH SYNOPSIS
+.ft B
+.B cpupower monitor
+.RB "\-l"
+
+.B cpupower monitor
+.RB [ "\-m <mon1>," [ "<mon2>,..." ] ]
+.RB [ "\-i seconds" ]
+.br
+.B cpupower monitor
+.RB [ "\-m <mon1>," [ "<mon2>,..." ] ]
+.RB command
+.br
+.SH DESCRIPTION
+\fBcpupower-monitor \fP reports processor topology, frequency and idle power
+state statistics. Either \fBcommand\fP is forked and
+statistics are printed upon its completion, or statistics are printed periodically.
+
+\fBcpupower-monitor \fP implements independent processor sleep state and
+frequency counters. Some are retrieved from kernel statistics, some are
+directly reading out hardware registers. Use \-l to get an overview which are
+supported on your system.
+
+.SH Options
+.PP
+\-l
+.RS 4
+List available monitors on your system. Additional details about each monitor
+are shown:
+.RS 2
+.IP \(bu
+The name in quotation marks which can be passed to the \-m parameter.
+.IP \(bu
+The number of different counters the monitor supports in brackets.
+.IP \(bu
+The amount of time in seconds the counters might overflow, due to
+implementation constraints.
+.IP \(bu
+The name and a description of each counter and its processor hierarchy level
+coverage in square brackets:
+.RS 4
+.IP \(bu
+[T] \-> Thread
+.IP \(bu
+[C] \-> Core
+.IP \(bu
+[P] \-> Processor Package (Socket)
+.IP \(bu
+[M] \-> Machine/Platform wide counter
+.RE
+.RE
+.RE
+.PP
+\-m <mon1>,<mon2>,...
+.RS 4
+Only display specific monitors. Use the monitor string(s) provided by \-l option.
+.RE
+.PP
+\-i seconds
+.RS 4
+Measure intervall.
+.RE
+.PP
+command
+.RS 4
+Measure idle and frequency characteristics of an arbitrary command/workload.
+The executable \fBcommand\fP is forked and upon its exit, statistics gathered since it was
+forked are displayed.
+.RE
+.PP
+\-v
+.RS 4
+Increase verbosity if the binary was compiled with the DEBUG option set.
+.RE
+
+.SH MONITOR DESCRIPTIONS
+.SS "Idle_Stats"
+Shows statistics of the cpuidle kernel subsystem. Values are retrieved from
+/sys/devices/system/cpu/cpu*/cpuidle/state*/.
+The kernel updates these values every time an idle state is entered or
+left. Therefore there can be some inaccuracy when cores are in an idle
+state for some time when the measure starts or ends. In worst case it can happen
+that one core stayed in an idle state for the whole measure time and the idle
+state usage time as exported by the kernel did not get updated. In this case
+a state residency of 0 percent is shown while it was 100.
+
+.SS "Mperf"
+The name comes from the aperf/mperf (average and maximum) MSR registers used
+which are available on recent X86 processors. It shows the average frequency
+(including boost frequencies).
+The fact that on all recent hardware the mperf timer stops ticking in any idle
+state it is also used to show C0 (processor is active) and Cx (processor is in
+any sleep state) times. These counters do not have the inaccuracy restrictions
+the "Idle_Stats" counters may show.
+May work poorly on Linux-2.6.20 through 2.6.29, as the \fBacpi-cpufreq \fP
+kernel frequency driver periodically cleared aperf/mperf registers in those
+kernels.
+
+.SS "Nehalem" "SandyBridge"
+Intel Core and Package sleep state counters.
+Threads (hyperthreaded cores) may not be able to enter deeper core states if
+its sibling is utilized.
+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"
+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.
+
+There is one special counter: NBP1 (North Bridge P1).
+This one always returns 0 or 1, depending on whether the North Bridge P1
+power state got entered at least once during measure time.
+Being able to enter NBP1 state also depends on graphics power management.
+Therefore this counter can be used to verify whether the graphics' driver
+power management is working as expected.
+
+.SH EXAMPLES
+
+cpupower monitor -l" may show:
+.RS 4
+Monitor "Mperf" (3 states) \- Might overflow after 922000000 s
+
+   ...
+
+Monitor "Idle_Stats" (3 states) \- Might overflow after 4294967295 s
+
+   ...
+
+.RE
+cpupower monitor \-m "Idle_Stats,Mperf" scp /tmp/test /nfs/tmp
+
+Monitor the scp command, show both Mperf and Idle_Stats states counter
+statistics, but in exchanged order.
+
+
+
+.RE
+Be careful that the typical command to fully utilize one CPU by doing:
+
+cpupower monitor cat /dev/zero >/dev/null
+
+Does not work as expected, because the measured output is redirected to
+/dev/null. This could get workarounded by putting the line into an own, tiny
+shell script. Hit CTRL\-c to terminate the command and get the measure output
+displayed.
+
+.SH REFERENCES
+"BIOS and Kernel Developer’s Guide (BKDG) for AMD Family 14h Processors"
+http://support.amd.com/us/Processor_TechDocs/43170.pdf
+
+"Intel® Turbo Boost Technology
+in Intel® Core™ Microarchitecture (Nehalem) Based Processors"
+http://download.intel.com/design/processor/applnots/320354.pdf
+
+"Intel® 64 and IA-32 Architectures Software Developer's Manual
+Volume 3B: System Programming Guide"
+http://www.intel.com/products/processor/manuals
+
+.SH FILES
+.ta
+.nf
+/dev/cpu/*/msr
+/sys/devices/system/cpu/cpu*/cpuidle/state*/.
+.fi
+
+.SH "SEE ALSO"
+powertop(8), msr(4), vmstat(8)
+.PP
+.SH AUTHORS
+.nf
+Written by Thomas Renninger <trenn@suse.de>
+
+Nehalem, SandyBridge monitors and command passing
+based on turbostat.8 from Len Brown <len.brown@intel.com>
diff --git a/tools/power/cpupower/man/cpupower-set.1 b/tools/power/cpupower/man/cpupower-set.1
new file mode 100644 (file)
index 0000000..c4954a9
--- /dev/null
@@ -0,0 +1,103 @@
+.TH CPUPOWER\-SET "1" "22/02/2011" "" "cpupower Manual"
+.SH NAME
+cpupower\-set \- Set processor power related kernel or hardware configurations
+.SH SYNOPSIS
+.ft B
+.B cpupower set [ \-b VAL ] [ \-s VAL ] [ \-m VAL ]
+
+
+.SH DESCRIPTION
+\fBcpupower set \fP sets kernel configurations or directly accesses hardware
+registers affecting processor power saving policies.
+
+Some options are platform wide, some affect single cores. By default values
+are applied on all cores. How to modify single core configurations is
+described in the cpupower(1) manpage in the \-\-cpu option section. Whether an
+option affects the whole system or can be applied to individual cores is
+described in the Options sections.
+
+Use \fBcpupower info \fP to read out current settings and whether they are
+supported on the system at all.
+
+.SH Options
+.PP
+\-\-perf-bias, \-b
+.RS 4
+Sets a register on supported Intel processore which allows software to convey
+its policy for the relative importance of performance versus energy savings to
+the  processor.
+
+The range of valid numbers is 0-15, where 0 is maximum
+performance and 15 is maximum energy efficiency.
+
+The processor uses this information in model-specific ways
+when it must select trade-offs between performance and
+energy efficiency.
+
+This policy hint does not supersede Processor Performance states
+(P-states) or CPU Idle power states (C-states), but allows
+software to have influence where it would otherwise be unable
+to express a preference.
+
+For example, this setting may tell the hardware how
+aggressively or conservatively to control frequency
+in the "turbo range" above the explicitly OS-controlled
+P-state frequency range.  It may also tell the hardware
+how aggressively it should enter the OS requested C-states.
+
+This option can be applied to individual cores only via the \-\-cpu option,
+cpupower(1).
+
+Setting the performance bias value on one CPU can modify the setting on
+related CPUs as well (for example all CPUs on one socket), because of
+hardware restrictions.
+Use \fBcpupower -c all info -b\fP to verify.
+
+This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
+.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
+
+sched_mc_power_savings is dependent upon SCHED_MC, which is
+itself architecture dependent.
+
+sched_smt_power_savings is dependent upon SCHED_SMT, which
+is itself architecture dependent.
+
+The two files are independent of each other. It is possible
+that one file may be present without the other.
+
+.SH "SEE ALSO"
+cpupower-info(1), cpupower-monitor(1), powertop(1)
+.PP
+.SH AUTHORS
+.nf
+\-\-perf\-bias parts written by Len Brown <len.brown@intel.com>
+Thomas Renninger <trenn@suse.de>
diff --git a/tools/power/cpupower/man/cpupower.1 b/tools/power/cpupower/man/cpupower.1
new file mode 100644 (file)
index 0000000..78c20fe
--- /dev/null
@@ -0,0 +1,72 @@
+.TH CPUPOWER "1" "07/03/2011" "" "cpupower Manual"
+.SH NAME
+cpupower \- Shows and sets processor power related values
+.SH SYNOPSIS
+.ft B
+.B cpupower [ \-c cpulist ] subcommand [ARGS]
+
+.B cpupower \-v|\-\-version
+
+.B cpupower \-h|\-\-help
+
+.SH DESCRIPTION
+\fBcpupower \fP is a collection of tools to examine and tune power saving
+related features of your processor.
+
+The manpages of the subcommands (cpupower\-<subcommand>(1)) provide detailed
+descriptions of supported features. Run \fBcpupower help\fP to get an overview
+of supported subcommands.
+
+.SH Options
+.PP
+\-\-help, \-h
+.RS 4
+Shows supported subcommands and general usage.
+.RE
+.PP
+\-\-cpu cpulist,  \-c cpulist
+.RS 4
+Only show or set values for specific cores.
+This option is not supported by all subcommands, details can be found in the
+manpages of the subcommands.
+
+Some subcommands access all cores (typically the *\-set commands), some only
+the first core (typically the *\-info commands) by default.
+
+The syntax for <cpulist> is based on how the kernel exports CPU bitmasks via
+sysfs files. Some examples:
+.RS 4
+.TP 16
+Input
+Equivalent to
+.TP
+all
+all cores
+.TP
+0\-3
+0,1,2,3
+.TP
+0\-7:2
+0,2,4,6
+.TP
+1,3,5-7
+1,3,5,6,7
+.TP
+0\-3:2,8\-15:4
+0,2,8,12       
+.RE
+.RE
+.PP
+\-\-version,  \-v
+.RS 4
+Print the package name and version number.
+
+.SH "SEE ALSO"
+cpupower-set(1), cpupower-info(1), cpupower-idle(1),
+cpupower-frequency-set(1), cpupower-frequency-info(1), cpupower-monitor(1),
+powertop(1)
+.PP
+.SH AUTHORS
+.nf
+\-\-perf\-bias parts written by Len Brown <len.brown@intel.com>
+Thomas Renninger <trenn@suse.de>
diff --git a/tools/power/cpupower/po/cs.po b/tools/power/cpupower/po/cs.po
new file mode 100644 (file)
index 0000000..cb22c45
--- /dev/null
@@ -0,0 +1,944 @@
+# translation of cs.po to Czech
+# Czech translation for cpufrequtils package
+# Czech messages for cpufrequtils.
+# Copyright (C) 2007 kavol
+# This file is distributed under the same license as the cpufrequtils package.
+#
+# Karel Volný <kavol@seznam.cz>, 2007, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: cs\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-03-08 17:03+0100\n"
+"PO-Revision-Date: 2008-06-11 16:26+0200\n"
+"Last-Translator: Karel Volný <kavol@seznam.cz>\n"
+"Language-Team: Czech <diskuze@lists.l10n.cz>\n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms:  nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: utils/idle_monitor/nhm_idle.c:36
+msgid "Processor Core C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:43
+msgid "Processor Core C6"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:51
+msgid "Processor Package C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
+msgid "Processor Package C6"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:33
+msgid "Processor Core C7"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:40
+msgid "Processor Package C2"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:47
+msgid "Processor Package C7"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:56
+msgid "Package in sleep state (PC1 or deeper)"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:63
+msgid "Processor Package C1"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:77
+msgid "North Bridge P1 boolean counter (returns 0 or 1)"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:35
+msgid "Processor Core not idle"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:42
+msgid "Processor Core in an idle state"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:50
+msgid "Average Frequency (including boost) in MHz"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:66
+#, c-format
+msgid ""
+"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:69
+#, c-format
+msgid ""
+"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:71
+#, c-format
+msgid "\t -v: be more verbose\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:73
+#, c-format
+msgid "\t -h: print this help\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:74
+#, c-format
+msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:75
+#, c-format
+msgid "\t -t: show CPU topology/hierarchy\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:76
+#, c-format
+msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:77
+#, c-format
+msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:79
+#, c-format
+msgid ""
+"only one of: -t, -l, -m are allowed\n"
+"If none of them is passed,"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:80
+#, c-format
+msgid " all supported monitors are shown\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:197
+#, c-format
+msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:207
+#, c-format
+msgid " *is offline\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:236
+#, c-format
+msgid "%s: max monitor name length (%d) exceeded\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:250
+#, c-format
+msgid "No matching monitor found in %s, try -l option\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:266
+#, c-format
+msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:319
+#, c-format
+msgid "%s took %.5f seconds and exited with status %d\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:406
+#, c-format
+msgid "Cannot read number of available processors\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:417
+#, c-format
+msgid "Available monitor %s needs root access\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:428
+#, c-format
+msgid "No HW Cstate monitors found\n"
+msgstr ""
+
+#: utils/cpupower.c:78
+#, c-format
+msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
+msgstr ""
+
+#: utils/cpupower.c:79
+#, c-format
+msgid "cpupower --version\n"
+msgstr ""
+
+#: utils/cpupower.c:80
+#, c-format
+msgid "Supported subcommands are:\n"
+msgstr ""
+
+#: utils/cpupower.c:83
+#, c-format
+msgid ""
+"\n"
+"Some subcommands can make use of the -c cpulist option.\n"
+msgstr ""
+
+#: utils/cpupower.c:84
+#, c-format
+msgid "Look at the general cpupower manpage how to use it\n"
+msgstr ""
+
+#: utils/cpupower.c:85
+#, c-format
+msgid "and read up the subcommand's manpage whether it is supported.\n"
+msgstr ""
+
+#: utils/cpupower.c:86
+#, c-format
+msgid ""
+"\n"
+"Use cpupower help subcommand for getting help for above subcommands.\n"
+msgstr ""
+
+#: utils/cpupower.c:91
+#, c-format
+msgid "Report errors and bugs to %s, please.\n"
+msgstr ""
+"Chyby v programu prosím hlaste na %s (anglicky).\n"
+"Chyby v překladu prosím hlaste na kavol@seznam.cz (česky ;-)\n"
+
+#: utils/cpupower.c:114
+#, c-format
+msgid "Error parsing cpu list\n"
+msgstr ""
+
+#: utils/cpupower.c:172
+#, c-format
+msgid "Subcommand %s needs root privileges\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:31
+#, c-format
+msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
+msgstr "Nelze zjistit počet CPU (%s: %s), předpokládá se 1.\n"
+
+#: utils/cpufreq-info.c:63
+#, c-format
+msgid ""
+"          minimum CPU frequency  -  maximum CPU frequency  -  governor\n"
+msgstr ""
+"         minimální frekvence CPU - maximální frekvence CPU -  regulátor\n"
+
+#: utils/cpufreq-info.c:151
+#, c-format
+msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
+msgstr ""
+
+#. P state changes via MSR are identified via cpuid 80000007
+#. on Intel and AMD, but we assume boost capable machines can do that
+#. if (cpuid_eax(0x80000000) >= 0x80000007
+#. && (cpuid_edx(0x80000007) & (1 << 7)))
+#.
+#: utils/cpufreq-info.c:161
+#, c-format
+msgid "  boost state support: \n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163
+#, c-format
+msgid "    Supported: %s\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "yes"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "no"
+msgstr ""
+
+#: utils/cpufreq-info.c:164
+#, fuzzy, c-format
+msgid "    Active: %s\n"
+msgstr "  ovladač: %s\n"
+
+#: utils/cpufreq-info.c:177
+#, c-format
+msgid "    Boost States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:178
+#, c-format
+msgid "    Total States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:181
+#, c-format
+msgid "    Pstate-Pb%d: %luMHz (boost state)\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:184
+#, c-format
+msgid "    Pstate-P%d:  %luMHz\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:211
+#, c-format
+msgid "  no or unknown cpufreq driver is active on this CPU\n"
+msgstr "  pro tento CPU není aktivní žádný známý ovladač cpufreq\n"
+
+#: utils/cpufreq-info.c:213
+#, c-format
+msgid "  driver: %s\n"
+msgstr "  ovladač: %s\n"
+
+#: utils/cpufreq-info.c:219
+#, fuzzy, c-format
+msgid "  CPUs which run at the same hardware frequency: "
+msgstr "  CPU, které musí měnit frekvenci zároveň: "
+
+#: utils/cpufreq-info.c:230
+#, fuzzy, c-format
+msgid "  CPUs which need to have their frequency coordinated by software: "
+msgstr "  CPU, které musí měnit frekvenci zároveň: "
+
+#: utils/cpufreq-info.c:241
+#, c-format
+msgid "  maximum transition latency: "
+msgstr ""
+
+#: utils/cpufreq-info.c:247
+#, c-format
+msgid "  hardware limits: "
+msgstr "  hardwarové meze: "
+
+#: utils/cpufreq-info.c:256
+#, c-format
+msgid "  available frequency steps: "
+msgstr "  dostupné frekvence: "
+
+#: utils/cpufreq-info.c:269
+#, c-format
+msgid "  available cpufreq governors: "
+msgstr "  dostupné regulátory: "
+
+#: utils/cpufreq-info.c:280
+#, c-format
+msgid "  current policy: frequency should be within "
+msgstr "  současná taktika: frekvence by měla být mezi "
+
+#: utils/cpufreq-info.c:282
+#, c-format
+msgid " and "
+msgstr " a "
+
+#: utils/cpufreq-info.c:286
+#, c-format
+msgid ""
+"The governor \"%s\" may decide which speed to use\n"
+"                  within this range.\n"
+msgstr ""
+"  Regulátor \"%s\" může rozhodnout jakou frekvenci použít\n"
+"                    v těchto mezích.\n"
+
+#: utils/cpufreq-info.c:293
+#, c-format
+msgid "  current CPU frequency is "
+msgstr "  současná frekvence CPU je "
+
+#: utils/cpufreq-info.c:296
+#, c-format
+msgid " (asserted by call to hardware)"
+msgstr "  (zjištěno hardwarovým voláním)"
+
+#: utils/cpufreq-info.c:304
+#, c-format
+msgid "  cpufreq stats: "
+msgstr "  statistika cpufreq: "
+
+#: utils/cpufreq-info.c:472
+#, fuzzy, c-format
+msgid "Usage: cpupower freqinfo [options]\n"
+msgstr "Užití: cpufreq-info [přepínače]\n"
+
+#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
+#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
+#, c-format
+msgid "Options:\n"
+msgstr "Přepínače:\n"
+
+#: utils/cpufreq-info.c:474
+#, fuzzy, c-format
+msgid "  -e, --debug          Prints out debug information [default]\n"
+msgstr "  -e, --debug          Vypíše ladicí informace\n"
+
+#: utils/cpufreq-info.c:475
+#, c-format
+msgid ""
+"  -f, --freq           Get frequency the CPU currently runs at, according\n"
+"                       to the cpufreq core *\n"
+msgstr ""
+"  -f, --freq           Zjistí aktuální frekvenci, na které CPU běží\n"
+"                       podle cpufreq *\n"
+
+#: utils/cpufreq-info.c:477
+#, c-format
+msgid ""
+"  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
+"                       it from hardware (only available to root) *\n"
+msgstr ""
+"  -w, --hwfreq         Zjistí aktuální frekvenci, na které CPU běží\n"
+"                       z hardware (dostupné jen uživateli root) *\n"
+
+#: utils/cpufreq-info.c:479
+#, c-format
+msgid ""
+"  -l, --hwlimits       Determine the minimum and maximum CPU frequency "
+"allowed *\n"
+msgstr ""
+"  -l, --hwlimits       Zjistí minimální a maximální dostupnou frekvenci CPU "
+"*\n"
+
+#: utils/cpufreq-info.c:480
+#, c-format
+msgid "  -d, --driver         Determines the used cpufreq kernel driver *\n"
+msgstr "  -d, --driver         Zjistí aktivní ovladač cpufreq *\n"
+
+#: utils/cpufreq-info.c:481
+#, c-format
+msgid "  -p, --policy         Gets the currently used cpufreq policy *\n"
+msgstr "  -p, --policy         Zjistí aktuální taktiku cpufreq *\n"
+
+#: utils/cpufreq-info.c:482
+#, c-format
+msgid "  -g, --governors      Determines available cpufreq governors *\n"
+msgstr "  -g, --governors      Zjistí dostupné regulátory cpufreq *\n"
+
+#: utils/cpufreq-info.c:483
+#, fuzzy, c-format
+msgid ""
+"  -r, --related-cpus   Determines which CPUs run at the same hardware "
+"frequency *\n"
+msgstr ""
+"  -a, --affected-cpus  Zjistí, které CPU musí měnit frekvenci zároveň *\n"
+
+#: utils/cpufreq-info.c:484
+#, fuzzy, c-format
+msgid ""
+"  -a, --affected-cpus  Determines which CPUs need to have their frequency\n"
+"                       coordinated by software *\n"
+msgstr ""
+"  -a, --affected-cpus  Zjistí, které CPU musí měnit frekvenci zároveň *\n"
+
+#: utils/cpufreq-info.c:486
+#, c-format
+msgid "  -s, --stats          Shows cpufreq statistics if available\n"
+msgstr "  -s, --stats          Zobrazí statistiku cpufreq, je-li dostupná\n"
+
+#: utils/cpufreq-info.c:487
+#, fuzzy, c-format
+msgid ""
+"  -y, --latency        Determines the maximum latency on CPU frequency "
+"changes *\n"
+msgstr ""
+"  -l, --hwlimits       Zjistí minimální a maximální dostupnou frekvenci CPU "
+"*\n"
+
+#: utils/cpufreq-info.c:488
+#, c-format
+msgid "  -b, --boost          Checks for turbo or boost modes  *\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:489
+#, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"cpufreq\n"
+"                       interface in 2.4. and early 2.6. kernels\n"
+msgstr ""
+"  -o, --proc           Vypíše informace ve formátu, jaký používalo rozhraní\n"
+"                       /proc/cpufreq v kernelech řady 2.4 a časné 2.6\n"
+
+#: utils/cpufreq-info.c:491
+#, fuzzy, c-format
+msgid ""
+"  -m, --human          human-readable output for the -f, -w, -s and -y "
+"parameters\n"
+msgstr ""
+"  -m, --human          Výstup parametrů -f, -w a -s v „lidmi čitelném“ "
+"formátu\n"
+
+#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
+#, c-format
+msgid "  -h, --help           Prints out this screen\n"
+msgstr "  -h, --help           Vypíše tuto nápovědu\n"
+
+#: utils/cpufreq-info.c:495
+#, c-format
+msgid ""
+"If no argument or only the -c, --cpu parameter is given, debug output about\n"
+"cpufreq is printed which is useful e.g. for reporting bugs.\n"
+msgstr ""
+"Není-li zadán žádný parametr nebo je-li zadán pouze přepínač -c, --cpu, "
+"jsou\n"
+"vypsány ladicí informace, což může být užitečné například při hlášení chyb.\n"
+
+#: utils/cpufreq-info.c:497
+#, c-format
+msgid ""
+"For the arguments marked with *, omitting the -c or --cpu argument is\n"
+"equivalent to setting it to zero\n"
+msgstr ""
+"Není-li při použití přepínačů označených * zadán parametr -c nebo --cpu,\n"
+"předpokládá se jeho hodnota 0.\n"
+
+#: utils/cpufreq-info.c:580
+#, c-format
+msgid ""
+"The argument passed to this tool can't be combined with passing a --cpu "
+"argument\n"
+msgstr "Zadaný parametr nemůže být použit zároveň s přepínačem -c nebo --cpu\n"
+
+#: utils/cpufreq-info.c:596
+#, c-format
+msgid ""
+"You can't specify more than one --cpu parameter and/or\n"
+"more than one output-specific argument\n"
+msgstr ""
+"Nelze zadat více než jeden parametr -c nebo --cpu\n"
+"anebo více než jeden parametr určující výstup\n"
+
+#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
+#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
+#, c-format
+msgid "invalid or unknown argument\n"
+msgstr "neplatný nebo neznámý parametr\n"
+
+#: utils/cpufreq-info.c:617
+#, c-format
+msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
+msgstr "nelze analyzovat CPU %d, vypadá to, že není přítomen\n"
+
+#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
+#, c-format
+msgid "analyzing CPU %d:\n"
+msgstr "analyzuji CPU %d:\n"
+
+#: utils/cpufreq-set.c:25
+#, fuzzy, c-format
+msgid "Usage: cpupower frequency-set [options]\n"
+msgstr "Užití: cpufreq-set [přepínače]\n"
+
+#: utils/cpufreq-set.c:27
+#, c-format
+msgid ""
+"  -d FREQ, --min FREQ      new minimum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -d FREQ, --min FREQ      Nová nejnižší frekvence, kterou může regulátor "
+"vybrat\n"
+
+#: utils/cpufreq-set.c:28
+#, c-format
+msgid ""
+"  -u FREQ, --max FREQ      new maximum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -u FREQ, --max FREQ      Nová nejvyšší frekvence, kterou může regulátor "
+"zvolit\n"
+
+#: utils/cpufreq-set.c:29
+#, c-format
+msgid "  -g GOV, --governor GOV   new cpufreq governor\n"
+msgstr "  -g GOV, --governors GOV  Nový regulátor cpufreq\n"
+
+#: utils/cpufreq-set.c:30
+#, c-format
+msgid ""
+"  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
+"                           governor to be available and loaded\n"
+msgstr ""
+"  -f FREQ, --freq FREQ     Frekvence, která má být nastavena. Vyžaduje, aby "
+"byl\n"
+"                           v jádře nahrán regulátor ‚userspace‘.\n"
+
+#: utils/cpufreq-set.c:32
+#, c-format
+msgid "  -r, --related            Switches all hardware-related CPUs\n"
+msgstr ""
+
+#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
+#, fuzzy, c-format
+msgid "  -h, --help               Prints out this screen\n"
+msgstr "  -h, --help           Vypíše tuto nápovědu\n"
+
+#: utils/cpufreq-set.c:35
+#, fuzzy, c-format
+msgid ""
+"Notes:\n"
+"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
+msgstr ""
+"Není-li při použití přepínačů označených * zadán parametr -c nebo --cpu,\n"
+"předpokládá se jeho hodnota 0.\n"
+
+#: utils/cpufreq-set.c:37
+#, fuzzy, c-format
+msgid ""
+"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
+"parameter\n"
+"   except the -c CPU, --cpu CPU parameter\n"
+"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
+"   by postfixing the value with the wanted unit name, without any space\n"
+"   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+msgstr ""
+"Poznámky:\n"
+"1. Vynechání parametru -c nebo --cpu je ekvivalentní jeho nastavení na 0\n"
+"2. Přepínač -f nebo --freq nemůže být použit zároveň s žádným jiným vyjma -"
+"c\n"
+"   nebo --cpu\n"
+"3. Frekvence (FREQ) mohou být zadány v Hz, kHz (výchozí), MHz, GHz nebo THz\n"
+"   připojením názvu jednotky bez mezery mezi číslem a jednotkou\n"
+"   (FREQ v kHz =^ Hz * 0,001 = ^ MHz * 1000 =^ GHz * 1000000)\n"
+
+#: utils/cpufreq-set.c:57
+#, c-format
+msgid ""
+"Error setting new values. Common errors:\n"
+"- Do you have proper administration rights? (super-user?)\n"
+"- Is the governor you requested available and modprobed?\n"
+"- Trying to set an invalid policy?\n"
+"- Trying to set a specific frequency, but userspace governor is not "
+"available,\n"
+"   for example because of hardware which cannot be set to a specific "
+"frequency\n"
+"   or because the userspace governor isn't loaded?\n"
+msgstr ""
+"Chyba při nastavování nových hodnot. Obvyklé problémy:\n"
+"- Máte patřičná administrátorská práva? (root?)\n"
+"- Je požadovaný regulátor dostupný v jádře? (modprobe?)\n"
+"- Snažíte se nastavit neplatnou taktiku?\n"
+"- Snažíte se nastavit určitou frekvenci, ale není dostupný\n"
+"  regulátor ‚userspace‘, například protože není nahrán v jádře,\n"
+"  nebo nelze na tomto hardware nastavit určitou frekvenci?\n"
+
+#: utils/cpufreq-set.c:170
+#, c-format
+msgid "wrong, unknown or unhandled CPU?\n"
+msgstr "neznámý nebo nepodporovaný CPU?\n"
+
+#: utils/cpufreq-set.c:302
+#, c-format
+msgid ""
+"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
+"-g/--governor parameters\n"
+msgstr ""
+"přepínač -f/--freq nemůže být použit zároveň\n"
+"s přepínačem -d/--min, -u/--max nebo -g/--governor\n"
+
+#: utils/cpufreq-set.c:308
+#, c-format
+msgid ""
+"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
+"-g/--governor must be passed\n"
+msgstr ""
+"Musí být zadán alespoň jeden přepínač\n"
+"-f/--freq, -d/--min, -u/--max nebo -g/--governor\n"
+
+#: utils/cpufreq-set.c:347
+#, c-format
+msgid "Setting cpu: %d\n"
+msgstr ""
+
+#: utils/cpupower-set.c:22
+#, c-format
+msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:24
+#, c-format
+msgid ""
+"  -b, --perf-bias [VAL]    Sets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-set.c:26
+#, c-format
+msgid ""
+"  -m, --sched-mc  [VAL]    Sets the kernel's multi core scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:27
+#, c-format
+msgid ""
+"  -s, --sched-smt [VAL]    Sets the kernel's thread sibling scheduler "
+"policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:80
+#, c-format
+msgid "--perf-bias param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:91
+#, c-format
+msgid "--sched-mc param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:102
+#, c-format
+msgid "--sched-smt param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:121
+#, c-format
+msgid "Error setting sched-mc %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:127
+#, c-format
+msgid "Error setting sched-smt %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:146
+#, c-format
+msgid "Error setting perf-bias value on CPU %d\n"
+msgstr ""
+
+#: utils/cpupower-info.c:21
+#, c-format
+msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
+msgstr ""
+
+#: utils/cpupower-info.c:23
+#, c-format
+msgid ""
+"  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-info.c:25
+#, fuzzy, c-format
+msgid "  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"
+msgstr "  -p, --policy         Zjistí aktuální taktiku cpufreq *\n"
+
+#: utils/cpupower-info.c:26
+#, c-format
+msgid ""
+"  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-info.c:28
+#, c-format
+msgid ""
+"\n"
+"Passing no option will show all info, by default only on core 0\n"
+msgstr ""
+
+#: utils/cpupower-info.c:102
+#, c-format
+msgid "System's multi core scheduler setting: "
+msgstr ""
+
+#. if sysfs file is missing it's: errno == ENOENT
+#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
+#, c-format
+msgid "not supported\n"
+msgstr ""
+
+#: utils/cpupower-info.c:111
+#, c-format
+msgid "System's thread sibling scheduler setting: "
+msgstr ""
+
+#: utils/cpupower-info.c:126
+#, c-format
+msgid "Intel's performance bias setting needs root privileges\n"
+msgstr ""
+
+#: utils/cpupower-info.c:128
+#, c-format
+msgid "System does not support Intel's performance bias setting\n"
+msgstr ""
+
+#: utils/cpupower-info.c:147
+#, c-format
+msgid "Could not read perf-bias value\n"
+msgstr ""
+
+#: utils/cpupower-info.c:150
+#, c-format
+msgid "perf-bias: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:28
+#, fuzzy, c-format
+msgid "Analyzing CPU %d:\n"
+msgstr "analyzuji CPU %d:\n"
+
+#: utils/cpuidle-info.c:32
+#, c-format
+msgid "CPU %u: No idle states\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:36
+#, c-format
+msgid "CPU %u: Can't read idle state info\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:41
+#, c-format
+msgid "Could not determine max idle state %u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:46
+#, c-format
+msgid "Number of idle states: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:48
+#, fuzzy, c-format
+msgid "Available idle states:"
+msgstr "  dostupné frekvence: "
+
+#: utils/cpuidle-info.c:71
+#, c-format
+msgid "Flags/Description: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:74
+#, c-format
+msgid "Latency: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:76
+#, c-format
+msgid "Usage: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:78
+#, c-format
+msgid "Duration: %llu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:90
+#, c-format
+msgid "Could not determine cpuidle driver\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:94
+#, fuzzy, c-format
+msgid "CPUidle driver: %s\n"
+msgstr "  ovladač: %s\n"
+
+#: utils/cpuidle-info.c:99
+#, c-format
+msgid "Could not determine cpuidle governor\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:103
+#, c-format
+msgid "CPUidle governor: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:122
+#, c-format
+msgid "CPU %u: Can't read C-state info\n"
+msgstr ""
+
+#. printf("Cstates: %d\n", cstates);
+#: utils/cpuidle-info.c:127
+#, c-format
+msgid "active state:            C0\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:128
+#, c-format
+msgid "max_cstate:              C%u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:129
+#, c-format
+msgid "maximum allowed latency: %lu usec\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:130
+#, c-format
+msgid "states:\t\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:132
+#, c-format
+msgid "    C%d:                  type[C%d] "
+msgstr ""
+
+#: utils/cpuidle-info.c:134
+#, c-format
+msgid "promotion[--] demotion[--] "
+msgstr ""
+
+#: utils/cpuidle-info.c:135
+#, c-format
+msgid "latency[%03lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:137
+#, c-format
+msgid "usage[%08lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:139
+#, c-format
+msgid "duration[%020Lu] \n"
+msgstr ""
+
+#: utils/cpuidle-info.c:147
+#, fuzzy, c-format
+msgid "Usage: cpupower idleinfo [options]\n"
+msgstr "Užití: cpufreq-info [přepínače]\n"
+
+#: utils/cpuidle-info.c:149
+#, fuzzy, c-format
+msgid "  -s, --silent         Only show general C-state information\n"
+msgstr "  -e, --debug          Vypíše ladicí informace\n"
+
+#: utils/cpuidle-info.c:150
+#, fuzzy, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"acpi/processor/*/power\n"
+"                       interface in older kernels\n"
+msgstr ""
+"  -o, --proc           Vypíše informace ve formátu, jaký používalo rozhraní\n"
+"                       /proc/cpufreq v kernelech řady 2.4 a časné 2.6\n"
+
+#: utils/cpuidle-info.c:209
+#, fuzzy, c-format
+msgid "You can't specify more than one output-specific argument\n"
+msgstr ""
+"Nelze zadat více než jeden parametr -c nebo --cpu\n"
+"anebo více než jeden parametr určující výstup\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU    CPU number which information shall be determined "
+#~ "about\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU    Číslo CPU, o kterém se mají zjistit informace\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU        number of CPU where cpufreq settings shall be "
+#~ "modified\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU        Číslo CPU pro který se má provést nastavení "
+#~ "cpufreq\n"
diff --git a/tools/power/cpupower/po/de.po b/tools/power/cpupower/po/de.po
new file mode 100644 (file)
index 0000000..78c09e5
--- /dev/null
@@ -0,0 +1,961 @@
+# German translations for cpufrequtils package
+# German messages for cpufrequtils.
+# Copyright (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.net>
+# This file is distributed under the same license as the cpufrequtils package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cpufrequtils 006\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-03-08 17:03+0100\n"
+"PO-Revision-Date: 2009-08-08 17:18+0100\n"
+"Last-Translator:  <linux@dominikbrodowski.net>\n"
+"Language-Team: NONE\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: utils/idle_monitor/nhm_idle.c:36
+msgid "Processor Core C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:43
+msgid "Processor Core C6"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:51
+msgid "Processor Package C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
+msgid "Processor Package C6"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:33
+msgid "Processor Core C7"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:40
+msgid "Processor Package C2"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:47
+msgid "Processor Package C7"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:56
+msgid "Package in sleep state (PC1 or deeper)"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:63
+msgid "Processor Package C1"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:77
+msgid "North Bridge P1 boolean counter (returns 0 or 1)"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:35
+msgid "Processor Core not idle"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:42
+msgid "Processor Core in an idle state"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:50
+msgid "Average Frequency (including boost) in MHz"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:66
+#, c-format
+msgid ""
+"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:69
+#, c-format
+msgid ""
+"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:71
+#, c-format
+msgid "\t -v: be more verbose\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:73
+#, c-format
+msgid "\t -h: print this help\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:74
+#, c-format
+msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:75
+#, c-format
+msgid "\t -t: show CPU topology/hierarchy\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:76
+#, c-format
+msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:77
+#, c-format
+msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:79
+#, c-format
+msgid ""
+"only one of: -t, -l, -m are allowed\n"
+"If none of them is passed,"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:80
+#, c-format
+msgid " all supported monitors are shown\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:197
+#, c-format
+msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:207
+#, c-format
+msgid " *is offline\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:236
+#, c-format
+msgid "%s: max monitor name length (%d) exceeded\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:250
+#, c-format
+msgid "No matching monitor found in %s, try -l option\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:266
+#, c-format
+msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:319
+#, c-format
+msgid "%s took %.5f seconds and exited with status %d\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:406
+#, c-format
+msgid "Cannot read number of available processors\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:417
+#, c-format
+msgid "Available monitor %s needs root access\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:428
+#, c-format
+msgid "No HW Cstate monitors found\n"
+msgstr ""
+
+#: utils/cpupower.c:78
+#, c-format
+msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
+msgstr ""
+
+#: utils/cpupower.c:79
+#, c-format
+msgid "cpupower --version\n"
+msgstr ""
+
+#: utils/cpupower.c:80
+#, c-format
+msgid "Supported subcommands are:\n"
+msgstr ""
+
+#: utils/cpupower.c:83
+#, c-format
+msgid ""
+"\n"
+"Some subcommands can make use of the -c cpulist option.\n"
+msgstr ""
+
+#: utils/cpupower.c:84
+#, c-format
+msgid "Look at the general cpupower manpage how to use it\n"
+msgstr ""
+
+#: utils/cpupower.c:85
+#, c-format
+msgid "and read up the subcommand's manpage whether it is supported.\n"
+msgstr ""
+
+#: utils/cpupower.c:86
+#, c-format
+msgid ""
+"\n"
+"Use cpupower help subcommand for getting help for above subcommands.\n"
+msgstr ""
+
+#: utils/cpupower.c:91
+#, c-format
+msgid "Report errors and bugs to %s, please.\n"
+msgstr "Bitte melden Sie Fehler an %s.\n"
+
+#: utils/cpupower.c:114
+#, c-format
+msgid "Error parsing cpu list\n"
+msgstr ""
+
+#: utils/cpupower.c:172
+#, c-format
+msgid "Subcommand %s needs root privileges\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:31
+#, c-format
+msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
+msgstr ""
+"Konnte nicht die Anzahl der CPUs herausfinden (%s : %s), nehme daher 1 an.\n"
+
+#: utils/cpufreq-info.c:63
+#, c-format
+msgid ""
+"          minimum CPU frequency  -  maximum CPU frequency  -  governor\n"
+msgstr ""
+"          minimale CPU-Taktfreq. -  maximale CPU-Taktfreq. -  Regler  \n"
+
+#: utils/cpufreq-info.c:151
+#, c-format
+msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
+msgstr ""
+
+#. P state changes via MSR are identified via cpuid 80000007
+#. on Intel and AMD, but we assume boost capable machines can do that
+#. if (cpuid_eax(0x80000000) >= 0x80000007
+#. && (cpuid_edx(0x80000007) & (1 << 7)))
+#.
+#: utils/cpufreq-info.c:161
+#, c-format
+msgid "  boost state support: \n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163
+#, c-format
+msgid "    Supported: %s\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "yes"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "no"
+msgstr ""
+
+#: utils/cpufreq-info.c:164
+#, fuzzy, c-format
+msgid "    Active: %s\n"
+msgstr "  Treiber: %s\n"
+
+#: utils/cpufreq-info.c:177
+#, c-format
+msgid "    Boost States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:178
+#, c-format
+msgid "    Total States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:181
+#, c-format
+msgid "    Pstate-Pb%d: %luMHz (boost state)\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:184
+#, c-format
+msgid "    Pstate-P%d:  %luMHz\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:211
+#, c-format
+msgid "  no or unknown cpufreq driver is active on this CPU\n"
+msgstr "  kein oder nicht bestimmbarer cpufreq-Treiber aktiv\n"
+
+#: utils/cpufreq-info.c:213
+#, c-format
+msgid "  driver: %s\n"
+msgstr "  Treiber: %s\n"
+
+#: utils/cpufreq-info.c:219
+#, c-format
+msgid "  CPUs which run at the same hardware frequency: "
+msgstr "  Folgende CPUs laufen mit der gleichen Hardware-Taktfrequenz: "
+
+#: utils/cpufreq-info.c:230
+#, c-format
+msgid "  CPUs which need to have their frequency coordinated by software: "
+msgstr "  Die Taktfrequenz folgender CPUs werden per Software koordiniert: "
+
+#: utils/cpufreq-info.c:241
+#, c-format
+msgid "  maximum transition latency: "
+msgstr "  Maximale Dauer eines Taktfrequenzwechsels: "
+
+#: utils/cpufreq-info.c:247
+#, c-format
+msgid "  hardware limits: "
+msgstr "  Hardwarebedingte Grenzen der Taktfrequenz: "
+
+#: utils/cpufreq-info.c:256
+#, c-format
+msgid "  available frequency steps: "
+msgstr "  mögliche Taktfrequenzen: "
+
+#: utils/cpufreq-info.c:269
+#, c-format
+msgid "  available cpufreq governors: "
+msgstr "  mögliche Regler: "
+
+#: utils/cpufreq-info.c:280
+#, c-format
+msgid "  current policy: frequency should be within "
+msgstr "  momentane Taktik: die Frequenz soll innerhalb "
+
+#: utils/cpufreq-info.c:282
+#, c-format
+msgid " and "
+msgstr " und "
+
+#: utils/cpufreq-info.c:286
+#, c-format
+msgid ""
+"The governor \"%s\" may decide which speed to use\n"
+"                  within this range.\n"
+msgstr ""
+"  liegen. Der Regler \"%s\" kann frei entscheiden,\n"
+"                    welche Taktfrequenz innerhalb dieser Grenze verwendet "
+"wird.\n"
+
+#: utils/cpufreq-info.c:293
+#, c-format
+msgid "  current CPU frequency is "
+msgstr "  momentane Taktfrequenz ist "
+
+#: utils/cpufreq-info.c:296
+#, c-format
+msgid " (asserted by call to hardware)"
+msgstr "  (verifiziert durch Nachfrage bei der Hardware)"
+
+#: utils/cpufreq-info.c:304
+#, c-format
+msgid "  cpufreq stats: "
+msgstr "  Statistik:"
+
+#: utils/cpufreq-info.c:472
+#, fuzzy, c-format
+msgid "Usage: cpupower freqinfo [options]\n"
+msgstr "Aufruf: cpufreq-info [Optionen]\n"
+
+#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
+#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
+#, c-format
+msgid "Options:\n"
+msgstr "Optionen:\n"
+
+#: utils/cpufreq-info.c:474
+#, fuzzy, c-format
+msgid "  -e, --debug          Prints out debug information [default]\n"
+msgstr ""
+"  -e, --debug          Erzeugt detaillierte Informationen, hilfreich\n"
+"                       zum Aufspüren von Fehlern\n"
+
+#: utils/cpufreq-info.c:475
+#, c-format
+msgid ""
+"  -f, --freq           Get frequency the CPU currently runs at, according\n"
+"                       to the cpufreq core *\n"
+msgstr ""
+"  -f, --freq           Findet die momentane CPU-Taktfrquenz heraus (nach\n"
+"                       Meinung des Betriebssystems) *\n"
+
+#: utils/cpufreq-info.c:477
+#, c-format
+msgid ""
+"  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
+"                       it from hardware (only available to root) *\n"
+msgstr ""
+"  -w, --hwfreq         Findet die momentane CPU-Taktfrequenz heraus\n"
+"                       (verifiziert durch Nachfrage bei der Hardware)\n"
+"                       [nur der Administrator kann dies tun] *\n"
+
+#: utils/cpufreq-info.c:479
+#, c-format
+msgid ""
+"  -l, --hwlimits       Determine the minimum and maximum CPU frequency "
+"allowed *\n"
+msgstr ""
+"  -l, --hwlimits       Findet die minimale und maximale Taktfrequenz heraus "
+"*\n"
+
+#: utils/cpufreq-info.c:480
+#, c-format
+msgid "  -d, --driver         Determines the used cpufreq kernel driver *\n"
+msgstr "  -d, --driver         Findet den momentanen Treiber heraus *\n"
+
+#: utils/cpufreq-info.c:481
+#, c-format
+msgid "  -p, --policy         Gets the currently used cpufreq policy *\n"
+msgstr "  -p, --policy         Findet die momentane Taktik heraus *\n"
+
+#: utils/cpufreq-info.c:482
+#, c-format
+msgid "  -g, --governors      Determines available cpufreq governors *\n"
+msgstr "  -g, --governors      Erzeugt eine Liste mit verfügbaren Reglern *\n"
+
+#: utils/cpufreq-info.c:483
+#, c-format
+msgid ""
+"  -r, --related-cpus   Determines which CPUs run at the same hardware "
+"frequency *\n"
+msgstr ""
+"  -r, --related-cpus   Findet heraus, welche CPUs mit derselben "
+"physikalischen\n"
+"                       Taktfrequenz laufen *\n"
+
+#: utils/cpufreq-info.c:484
+#, c-format
+msgid ""
+"  -a, --affected-cpus  Determines which CPUs need to have their frequency\n"
+"                       coordinated by software *\n"
+msgstr ""
+"  -a, --affected-cpus  Findet heraus, von welchen CPUs die Taktfrequenz "
+"durch\n"
+"                       Software koordiniert werden muss *\n"
+
+#: utils/cpufreq-info.c:486
+#, c-format
+msgid "  -s, --stats          Shows cpufreq statistics if available\n"
+msgstr ""
+"  -s, --stats          Zeigt, sofern möglich, Statistiken über cpufreq an.\n"
+
+#: utils/cpufreq-info.c:487
+#, c-format
+msgid ""
+"  -y, --latency        Determines the maximum latency on CPU frequency "
+"changes *\n"
+msgstr ""
+"  -y, --latency        Findet die maximale Dauer eines Taktfrequenzwechsels "
+"heraus *\n"
+
+#: utils/cpufreq-info.c:488
+#, c-format
+msgid "  -b, --boost          Checks for turbo or boost modes  *\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:489
+#, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"cpufreq\n"
+"                       interface in 2.4. and early 2.6. kernels\n"
+msgstr ""
+"  -o, --proc           Erzeugt Informationen in einem ähnlichem Format zu "
+"dem\n"
+"                       der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
+"                       Kernel-Versionen\n"
+
+#: utils/cpufreq-info.c:491
+#, c-format
+msgid ""
+"  -m, --human          human-readable output for the -f, -w, -s and -y "
+"parameters\n"
+msgstr ""
+"  -m, --human          Formatiert Taktfrequenz- und Zeitdauerangaben in "
+"besser\n"
+"                       lesbarer Form (MHz, GHz; us, ms)\n"
+
+#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
+#, c-format
+msgid "  -h, --help           Prints out this screen\n"
+msgstr "  -h, --help           Gibt diese Kurzübersicht aus\n"
+
+#: utils/cpufreq-info.c:495
+#, c-format
+msgid ""
+"If no argument or only the -c, --cpu parameter is given, debug output about\n"
+"cpufreq is printed which is useful e.g. for reporting bugs.\n"
+msgstr ""
+"Sofern kein anderer Parameter als '-c, --cpu' angegeben wird, liefert "
+"dieses\n"
+"Programm Informationen, die z.B. zum Berichten von Fehlern nützlich sind.\n"
+
+#: utils/cpufreq-info.c:497
+#, c-format
+msgid ""
+"For the arguments marked with *, omitting the -c or --cpu argument is\n"
+"equivalent to setting it to zero\n"
+msgstr ""
+"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n"
+"mittels -c oder --cpu etwas anderes angegeben wird\n"
+
+#: utils/cpufreq-info.c:580
+#, c-format
+msgid ""
+"The argument passed to this tool can't be combined with passing a --cpu "
+"argument\n"
+msgstr "Diese Option kann nicht mit der --cpu-Option kombiniert werden\n"
+
+#: utils/cpufreq-info.c:596
+#, c-format
+msgid ""
+"You can't specify more than one --cpu parameter and/or\n"
+"more than one output-specific argument\n"
+msgstr ""
+"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n"
+"informationsspezifischen Parameter gleichzeitig angeben\n"
+
+#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
+#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
+#, c-format
+msgid "invalid or unknown argument\n"
+msgstr "unbekannter oder falscher Parameter\n"
+
+#: utils/cpufreq-info.c:617
+#, c-format
+msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
+msgstr ""
+"Konnte nicht die CPU %d analysieren, da sie (scheinbar?) nicht existiert.\n"
+
+#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
+#, c-format
+msgid "analyzing CPU %d:\n"
+msgstr "analysiere CPU %d:\n"
+
+#: utils/cpufreq-set.c:25
+#, fuzzy, c-format
+msgid "Usage: cpupower frequency-set [options]\n"
+msgstr "Aufruf: cpufreq-set [Optionen]\n"
+
+#: utils/cpufreq-set.c:27
+#, c-format
+msgid ""
+"  -d FREQ, --min FREQ      new minimum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -d FREQ, --min FREQ      neue minimale Taktfrequenz, die der Regler\n"
+"                           auswählen darf\n"
+
+#: utils/cpufreq-set.c:28
+#, c-format
+msgid ""
+"  -u FREQ, --max FREQ      new maximum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -u FREQ, --max FREQ      neue maximale Taktfrequenz, die der Regler\n"
+"                           auswählen darf\n"
+
+#: utils/cpufreq-set.c:29
+#, c-format
+msgid "  -g GOV, --governor GOV   new cpufreq governor\n"
+msgstr "  -g GOV, --governors GOV  wechsle zu Regler GOV\n"
+
+#: utils/cpufreq-set.c:30
+#, c-format
+msgid ""
+"  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
+"                           governor to be available and loaded\n"
+msgstr ""
+"  -f FREQ, --freq FREQ     setze exakte Taktfrequenz. Benötigt den Regler\n"
+"                           'userspace'.\n"
+
+#: utils/cpufreq-set.c:32
+#, c-format
+msgid "  -r, --related            Switches all hardware-related CPUs\n"
+msgstr ""
+"  -r, --related            Setze Werte für alle CPUs, deren Taktfrequenz\n"
+"                           hardwarebedingt identisch ist.\n"
+
+#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
+#, c-format
+msgid "  -h, --help               Prints out this screen\n"
+msgstr "  -h, --help               Gibt diese Kurzübersicht aus\n"
+
+#: utils/cpufreq-set.c:35
+#, fuzzy, c-format
+msgid ""
+"Notes:\n"
+"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
+msgstr ""
+"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n"
+"mittels -c oder --cpu etwas anderes angegeben wird\n"
+
+#: utils/cpufreq-set.c:37
+#, fuzzy, c-format
+msgid ""
+"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
+"parameter\n"
+"   except the -c CPU, --cpu CPU parameter\n"
+"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
+"   by postfixing the value with the wanted unit name, without any space\n"
+"   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+msgstr ""
+"Hinweise:\n"
+"1. Sofern kein -c oder --cpu-Parameter angegeben ist, wird '--cpu 0'\n"
+"   angenommen\n"
+"2. Der Parameter -f bzw. --freq kann mit keinem anderen als dem Parameter\n"
+"   -c bzw. --cpu kombiniert werden\n"
+"3. FREQuenzen können in Hz, kHz (Standard), MHz, GHz oder THz eingegeben\n"
+"   werden, indem der Wert und unmittelbar anschließend (ohne Leerzeichen!)\n"
+"   die Einheit angegeben werden. (Bsp: 1GHz )\n"
+"   (FREQuenz in kHz =^ MHz * 1000 =^ GHz * 1000000).\n"
+
+#: utils/cpufreq-set.c:57
+#, c-format
+msgid ""
+"Error setting new values. Common errors:\n"
+"- Do you have proper administration rights? (super-user?)\n"
+"- Is the governor you requested available and modprobed?\n"
+"- Trying to set an invalid policy?\n"
+"- Trying to set a specific frequency, but userspace governor is not "
+"available,\n"
+"   for example because of hardware which cannot be set to a specific "
+"frequency\n"
+"   or because the userspace governor isn't loaded?\n"
+msgstr ""
+"Beim Einstellen ist ein Fehler aufgetreten. Typische Fehlerquellen sind:\n"
+"- nicht ausreichende Rechte (Administrator)\n"
+"- der Regler ist nicht verfügbar bzw. nicht geladen\n"
+"- die angegebene Taktik ist inkorrekt\n"
+"- eine spezifische Frequenz wurde angegeben, aber der Regler 'userspace'\n"
+"  kann entweder hardwarebedingt nicht genutzt werden oder ist nicht geladen\n"
+
+#: utils/cpufreq-set.c:170
+#, c-format
+msgid "wrong, unknown or unhandled CPU?\n"
+msgstr "unbekannte oder nicht regelbare CPU\n"
+
+#: utils/cpufreq-set.c:302
+#, c-format
+msgid ""
+"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
+"-g/--governor parameters\n"
+msgstr ""
+"Der -f bzw. --freq-Parameter kann nicht mit den Parametern -d/--min, -u/--"
+"max\n"
+"oder -g/--governor kombiniert werden\n"
+
+#: utils/cpufreq-set.c:308
+#, c-format
+msgid ""
+"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
+"-g/--governor must be passed\n"
+msgstr ""
+"Es muss mindestens ein Parameter aus -f/--freq, -d/--min, -u/--max oder\n"
+"-g/--governor angegeben werden.\n"
+
+#: utils/cpufreq-set.c:347
+#, c-format
+msgid "Setting cpu: %d\n"
+msgstr ""
+
+#: utils/cpupower-set.c:22
+#, c-format
+msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:24
+#, c-format
+msgid ""
+"  -b, --perf-bias [VAL]    Sets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-set.c:26
+#, c-format
+msgid ""
+"  -m, --sched-mc  [VAL]    Sets the kernel's multi core scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:27
+#, c-format
+msgid ""
+"  -s, --sched-smt [VAL]    Sets the kernel's thread sibling scheduler "
+"policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:80
+#, c-format
+msgid "--perf-bias param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:91
+#, c-format
+msgid "--sched-mc param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:102
+#, c-format
+msgid "--sched-smt param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:121
+#, c-format
+msgid "Error setting sched-mc %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:127
+#, c-format
+msgid "Error setting sched-smt %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:146
+#, c-format
+msgid "Error setting perf-bias value on CPU %d\n"
+msgstr ""
+
+#: utils/cpupower-info.c:21
+#, c-format
+msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
+msgstr ""
+
+#: utils/cpupower-info.c:23
+#, c-format
+msgid ""
+"  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-info.c:25
+#, fuzzy, c-format
+msgid "  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"
+msgstr "  -p, --policy         Findet die momentane Taktik heraus *\n"
+
+#: utils/cpupower-info.c:26
+#, c-format
+msgid ""
+"  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-info.c:28
+#, c-format
+msgid ""
+"\n"
+"Passing no option will show all info, by default only on core 0\n"
+msgstr ""
+
+#: utils/cpupower-info.c:102
+#, c-format
+msgid "System's multi core scheduler setting: "
+msgstr ""
+
+#. if sysfs file is missing it's: errno == ENOENT
+#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
+#, c-format
+msgid "not supported\n"
+msgstr ""
+
+#: utils/cpupower-info.c:111
+#, c-format
+msgid "System's thread sibling scheduler setting: "
+msgstr ""
+
+#: utils/cpupower-info.c:126
+#, c-format
+msgid "Intel's performance bias setting needs root privileges\n"
+msgstr ""
+
+#: utils/cpupower-info.c:128
+#, c-format
+msgid "System does not support Intel's performance bias setting\n"
+msgstr ""
+
+#: utils/cpupower-info.c:147
+#, c-format
+msgid "Could not read perf-bias value\n"
+msgstr ""
+
+#: utils/cpupower-info.c:150
+#, c-format
+msgid "perf-bias: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:28
+#, fuzzy, c-format
+msgid "Analyzing CPU %d:\n"
+msgstr "analysiere CPU %d:\n"
+
+#: utils/cpuidle-info.c:32
+#, c-format
+msgid "CPU %u: No idle states\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:36
+#, c-format
+msgid "CPU %u: Can't read idle state info\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:41
+#, c-format
+msgid "Could not determine max idle state %u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:46
+#, c-format
+msgid "Number of idle states: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:48
+#, fuzzy, c-format
+msgid "Available idle states:"
+msgstr "  mögliche Taktfrequenzen: "
+
+#: utils/cpuidle-info.c:71
+#, c-format
+msgid "Flags/Description: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:74
+#, c-format
+msgid "Latency: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:76
+#, c-format
+msgid "Usage: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:78
+#, c-format
+msgid "Duration: %llu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:90
+#, c-format
+msgid "Could not determine cpuidle driver\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:94
+#, fuzzy, c-format
+msgid "CPUidle driver: %s\n"
+msgstr "  Treiber: %s\n"
+
+#: utils/cpuidle-info.c:99
+#, c-format
+msgid "Could not determine cpuidle governor\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:103
+#, c-format
+msgid "CPUidle governor: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:122
+#, c-format
+msgid "CPU %u: Can't read C-state info\n"
+msgstr ""
+
+#. printf("Cstates: %d\n", cstates);
+#: utils/cpuidle-info.c:127
+#, c-format
+msgid "active state:            C0\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:128
+#, c-format
+msgid "max_cstate:              C%u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:129
+#, fuzzy, c-format
+msgid "maximum allowed latency: %lu usec\n"
+msgstr "  Maximale Dauer eines Taktfrequenzwechsels: "
+
+#: utils/cpuidle-info.c:130
+#, c-format
+msgid "states:\t\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:132
+#, c-format
+msgid "    C%d:                  type[C%d] "
+msgstr ""
+
+#: utils/cpuidle-info.c:134
+#, c-format
+msgid "promotion[--] demotion[--] "
+msgstr ""
+
+#: utils/cpuidle-info.c:135
+#, c-format
+msgid "latency[%03lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:137
+#, c-format
+msgid "usage[%08lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:139
+#, c-format
+msgid "duration[%020Lu] \n"
+msgstr ""
+
+#: utils/cpuidle-info.c:147
+#, fuzzy, c-format
+msgid "Usage: cpupower idleinfo [options]\n"
+msgstr "Aufruf: cpufreq-info [Optionen]\n"
+
+#: utils/cpuidle-info.c:149
+#, fuzzy, c-format
+msgid "  -s, --silent         Only show general C-state information\n"
+msgstr ""
+"  -e, --debug          Erzeugt detaillierte Informationen, hilfreich\n"
+"                       zum Aufspüren von Fehlern\n"
+
+#: utils/cpuidle-info.c:150
+#, fuzzy, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"acpi/processor/*/power\n"
+"                       interface in older kernels\n"
+msgstr ""
+"  -o, --proc           Erzeugt Informationen in einem ähnlichem Format zu "
+"dem\n"
+"                       der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
+"                       Kernel-Versionen\n"
+
+#: utils/cpuidle-info.c:209
+#, fuzzy, c-format
+msgid "You can't specify more than one output-specific argument\n"
+msgstr ""
+"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n"
+"informationsspezifischen Parameter gleichzeitig angeben\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU    CPU number which information shall be determined "
+#~ "about\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU    Nummer der CPU, über die Informationen "
+#~ "herausgefunden werden sollen\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU        number of CPU where cpufreq settings shall be "
+#~ "modified\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU        Nummer der CPU, deren Taktfrequenz-"
+#~ "Einstellung\n"
+#~ "                           werden soll\n"
diff --git a/tools/power/cpupower/po/fr.po b/tools/power/cpupower/po/fr.po
new file mode 100644 (file)
index 0000000..245ad20
--- /dev/null
@@ -0,0 +1,947 @@
+# French translations for cpufrequtils package
+# Copyright (C) 2004 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the cpufrequtils package.
+# Ducrot Bruno <ducrot@poupinou.org>, 2004.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: cpufrequtils 0.1-pre2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-03-08 17:03+0100\n"
+"PO-Revision-Date: 2004-11-17 15:53+1000\n"
+"Last-Translator: Bruno Ducrot <ducrot@poupinou.org>\n"
+"Language-Team: NONE\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: utils/idle_monitor/nhm_idle.c:36
+msgid "Processor Core C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:43
+msgid "Processor Core C6"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:51
+msgid "Processor Package C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
+msgid "Processor Package C6"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:33
+msgid "Processor Core C7"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:40
+msgid "Processor Package C2"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:47
+msgid "Processor Package C7"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:56
+msgid "Package in sleep state (PC1 or deeper)"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:63
+msgid "Processor Package C1"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:77
+msgid "North Bridge P1 boolean counter (returns 0 or 1)"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:35
+msgid "Processor Core not idle"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:42
+msgid "Processor Core in an idle state"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:50
+msgid "Average Frequency (including boost) in MHz"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:66
+#, c-format
+msgid ""
+"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:69
+#, c-format
+msgid ""
+"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:71
+#, c-format
+msgid "\t -v: be more verbose\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:73
+#, c-format
+msgid "\t -h: print this help\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:74
+#, c-format
+msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:75
+#, c-format
+msgid "\t -t: show CPU topology/hierarchy\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:76
+#, c-format
+msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:77
+#, c-format
+msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:79
+#, c-format
+msgid ""
+"only one of: -t, -l, -m are allowed\n"
+"If none of them is passed,"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:80
+#, c-format
+msgid " all supported monitors are shown\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:197
+#, c-format
+msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:207
+#, c-format
+msgid " *is offline\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:236
+#, c-format
+msgid "%s: max monitor name length (%d) exceeded\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:250
+#, c-format
+msgid "No matching monitor found in %s, try -l option\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:266
+#, c-format
+msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:319
+#, c-format
+msgid "%s took %.5f seconds and exited with status %d\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:406
+#, c-format
+msgid "Cannot read number of available processors\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:417
+#, c-format
+msgid "Available monitor %s needs root access\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:428
+#, c-format
+msgid "No HW Cstate monitors found\n"
+msgstr ""
+
+#: utils/cpupower.c:78
+#, c-format
+msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
+msgstr ""
+
+#: utils/cpupower.c:79
+#, c-format
+msgid "cpupower --version\n"
+msgstr ""
+
+#: utils/cpupower.c:80
+#, c-format
+msgid "Supported subcommands are:\n"
+msgstr ""
+
+#: utils/cpupower.c:83
+#, c-format
+msgid ""
+"\n"
+"Some subcommands can make use of the -c cpulist option.\n"
+msgstr ""
+
+#: utils/cpupower.c:84
+#, c-format
+msgid "Look at the general cpupower manpage how to use it\n"
+msgstr ""
+
+#: utils/cpupower.c:85
+#, c-format
+msgid "and read up the subcommand's manpage whether it is supported.\n"
+msgstr ""
+
+#: utils/cpupower.c:86
+#, c-format
+msgid ""
+"\n"
+"Use cpupower help subcommand for getting help for above subcommands.\n"
+msgstr ""
+
+#: utils/cpupower.c:91
+#, c-format
+msgid "Report errors and bugs to %s, please.\n"
+msgstr "Veuillez rapportez les erreurs et les bogues à %s, s'il vous plait.\n"
+
+#: utils/cpupower.c:114
+#, c-format
+msgid "Error parsing cpu list\n"
+msgstr ""
+
+#: utils/cpupower.c:172
+#, c-format
+msgid "Subcommand %s needs root privileges\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:31
+#, c-format
+msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
+msgstr "Détermination du nombre de CPUs (%s : %s) impossible.  Assume 1\n"
+
+#: utils/cpufreq-info.c:63
+#, c-format
+msgid ""
+"          minimum CPU frequency  -  maximum CPU frequency  -  governor\n"
+msgstr ""
+"         Fréquence CPU minimale - Fréquence CPU maximale  - régulateur\n"
+
+#: utils/cpufreq-info.c:151
+#, c-format
+msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
+msgstr ""
+
+#. P state changes via MSR are identified via cpuid 80000007
+#. on Intel and AMD, but we assume boost capable machines can do that
+#. if (cpuid_eax(0x80000000) >= 0x80000007
+#. && (cpuid_edx(0x80000007) & (1 << 7)))
+#.
+#: utils/cpufreq-info.c:161
+#, c-format
+msgid "  boost state support: \n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163
+#, c-format
+msgid "    Supported: %s\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "yes"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "no"
+msgstr ""
+
+#: utils/cpufreq-info.c:164
+#, fuzzy, c-format
+msgid "    Active: %s\n"
+msgstr "  pilote : %s\n"
+
+#: utils/cpufreq-info.c:177
+#, c-format
+msgid "    Boost States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:178
+#, c-format
+msgid "    Total States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:181
+#, c-format
+msgid "    Pstate-Pb%d: %luMHz (boost state)\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:184
+#, c-format
+msgid "    Pstate-P%d:  %luMHz\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:211
+#, c-format
+msgid "  no or unknown cpufreq driver is active on this CPU\n"
+msgstr "  pas de pilotes cpufreq reconnu pour ce CPU\n"
+
+#: utils/cpufreq-info.c:213
+#, c-format
+msgid "  driver: %s\n"
+msgstr "  pilote : %s\n"
+
+#: utils/cpufreq-info.c:219
+#, fuzzy, c-format
+msgid "  CPUs which run at the same hardware frequency: "
+msgstr "  CPUs qui doivent changer de fréquences en même temps : "
+
+#: utils/cpufreq-info.c:230
+#, fuzzy, c-format
+msgid "  CPUs which need to have their frequency coordinated by software: "
+msgstr "  CPUs qui doivent changer de fréquences en même temps : "
+
+#: utils/cpufreq-info.c:241
+#, c-format
+msgid "  maximum transition latency: "
+msgstr ""
+
+#: utils/cpufreq-info.c:247
+#, c-format
+msgid "  hardware limits: "
+msgstr "  limitation matérielle : "
+
+#: utils/cpufreq-info.c:256
+#, c-format
+msgid "  available frequency steps: "
+msgstr "  plage de fréquence : "
+
+#: utils/cpufreq-info.c:269
+#, c-format
+msgid "  available cpufreq governors: "
+msgstr "  régulateurs disponibles : "
+
+#: utils/cpufreq-info.c:280
+#, c-format
+msgid "  current policy: frequency should be within "
+msgstr "  tactique actuelle : la fréquence doit être comprise entre "
+
+#: utils/cpufreq-info.c:282
+#, c-format
+msgid " and "
+msgstr " et "
+
+#: utils/cpufreq-info.c:286
+#, c-format
+msgid ""
+"The governor \"%s\" may decide which speed to use\n"
+"                  within this range.\n"
+msgstr ""
+"Le régulateur \"%s\" est libre de choisir la vitesse\n"
+"                  dans cette plage de fréquences.\n"
+
+#: utils/cpufreq-info.c:293
+#, c-format
+msgid "  current CPU frequency is "
+msgstr "  la fréquence actuelle de ce CPU est "
+
+#: utils/cpufreq-info.c:296
+#, c-format
+msgid " (asserted by call to hardware)"
+msgstr " (vérifié par un appel direct du matériel)"
+
+#: utils/cpufreq-info.c:304
+#, c-format
+msgid "  cpufreq stats: "
+msgstr "  des statistique concernant cpufreq:"
+
+#: utils/cpufreq-info.c:472
+#, fuzzy, c-format
+msgid "Usage: cpupower freqinfo [options]\n"
+msgstr "Usage : cpufreq-info [options]\n"
+
+#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
+#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
+#, c-format
+msgid "Options:\n"
+msgstr "Options :\n"
+
+#: utils/cpufreq-info.c:474
+#, fuzzy, c-format
+msgid "  -e, --debug          Prints out debug information [default]\n"
+msgstr "  -e, --debug          Afficher les informations de déboguage\n"
+
+#: utils/cpufreq-info.c:475
+#, c-format
+msgid ""
+"  -f, --freq           Get frequency the CPU currently runs at, according\n"
+"                       to the cpufreq core *\n"
+msgstr ""
+"  -f, --freq           Obtenir la fréquence actuelle du CPU selon le point\n"
+"                       de vue du coeur du système de cpufreq *\n"
+
+#: utils/cpufreq-info.c:477
+#, c-format
+msgid ""
+"  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
+"                       it from hardware (only available to root) *\n"
+msgstr ""
+"  -w, --hwfreq         Obtenir la fréquence actuelle du CPU directement par\n"
+"                       le matériel (doit être root) *\n"
+
+#: utils/cpufreq-info.c:479
+#, c-format
+msgid ""
+"  -l, --hwlimits       Determine the minimum and maximum CPU frequency "
+"allowed *\n"
+msgstr ""
+"  -l, --hwlimits       Affiche les fréquences minimales et maximales du CPU "
+"*\n"
+
+#: utils/cpufreq-info.c:480
+#, c-format
+msgid "  -d, --driver         Determines the used cpufreq kernel driver *\n"
+msgstr "  -d, --driver         Affiche le pilote cpufreq utilisé *\n"
+
+#: utils/cpufreq-info.c:481
+#, c-format
+msgid "  -p, --policy         Gets the currently used cpufreq policy *\n"
+msgstr "  -p, --policy         Affiche la tactique actuelle de cpufreq *\n"
+
+#: utils/cpufreq-info.c:482
+#, c-format
+msgid "  -g, --governors      Determines available cpufreq governors *\n"
+msgstr ""
+"  -g, --governors      Affiche les régulateurs disponibles de cpufreq *\n"
+
+#: utils/cpufreq-info.c:483
+#, fuzzy, c-format
+msgid ""
+"  -r, --related-cpus   Determines which CPUs run at the same hardware "
+"frequency *\n"
+msgstr ""
+"  -a, --affected-cpus   Affiche quels sont les CPUs qui doivent changer de\n"
+"                        fréquences en même temps *\n"
+
+#: utils/cpufreq-info.c:484
+#, fuzzy, c-format
+msgid ""
+"  -a, --affected-cpus  Determines which CPUs need to have their frequency\n"
+"                       coordinated by software *\n"
+msgstr ""
+"  -a, --affected-cpus   Affiche quels sont les CPUs qui doivent changer de\n"
+"                        fréquences en même temps *\n"
+
+#: utils/cpufreq-info.c:486
+#, c-format
+msgid "  -s, --stats          Shows cpufreq statistics if available\n"
+msgstr ""
+"  -s, --stats          Indique des statistiques concernant cpufreq, si\n"
+"                       disponibles\n"
+
+#: utils/cpufreq-info.c:487
+#, fuzzy, c-format
+msgid ""
+"  -y, --latency        Determines the maximum latency on CPU frequency "
+"changes *\n"
+msgstr ""
+"  -l, --hwlimits       Affiche les fréquences minimales et maximales du CPU "
+"*\n"
+
+#: utils/cpufreq-info.c:488
+#, c-format
+msgid "  -b, --boost          Checks for turbo or boost modes  *\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:489
+#, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"cpufreq\n"
+"                       interface in 2.4. and early 2.6. kernels\n"
+msgstr ""
+"  -o, --proc           Affiche les informations en utilisant l'interface\n"
+"                       fournie par /proc/cpufreq, présente dans les "
+"versions\n"
+"                       2.4 et les anciennes versions 2.6 du noyau\n"
+
+#: utils/cpufreq-info.c:491
+#, fuzzy, c-format
+msgid ""
+"  -m, --human          human-readable output for the -f, -w, -s and -y "
+"parameters\n"
+msgstr ""
+"  -m, --human           affiche dans un format lisible pour un humain\n"
+"                        pour les options -f, -w et -s (MHz, GHz)\n"
+
+#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
+#, c-format
+msgid "  -h, --help           Prints out this screen\n"
+msgstr "  -h, --help           affiche l'aide-mémoire\n"
+
+#: utils/cpufreq-info.c:495
+#, c-format
+msgid ""
+"If no argument or only the -c, --cpu parameter is given, debug output about\n"
+"cpufreq is printed which is useful e.g. for reporting bugs.\n"
+msgstr ""
+"Par défaut, les informations de déboguage seront affichées si aucun\n"
+"argument, ou bien si seulement l'argument -c (--cpu) est donné, afin de\n"
+"faciliter les rapports de bogues par exemple\n"
+
+#: utils/cpufreq-info.c:497
+#, c-format
+msgid ""
+"For the arguments marked with *, omitting the -c or --cpu argument is\n"
+"equivalent to setting it to zero\n"
+msgstr "Les arguments avec un * utiliseront le CPU 0 si -c (--cpu) est omis\n"
+
+#: utils/cpufreq-info.c:580
+#, c-format
+msgid ""
+"The argument passed to this tool can't be combined with passing a --cpu "
+"argument\n"
+msgstr "Cette option est incompatible avec --cpu\n"
+
+#: utils/cpufreq-info.c:596
+#, c-format
+msgid ""
+"You can't specify more than one --cpu parameter and/or\n"
+"more than one output-specific argument\n"
+msgstr ""
+"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
+"spécifier plus d'un argument de formatage\n"
+
+#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
+#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
+#, c-format
+msgid "invalid or unknown argument\n"
+msgstr "option invalide\n"
+
+#: utils/cpufreq-info.c:617
+#, c-format
+msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
+msgstr "analyse du CPU %d impossible puisqu'il ne semble pas être présent\n"
+
+#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
+#, c-format
+msgid "analyzing CPU %d:\n"
+msgstr "analyse du CPU %d :\n"
+
+#: utils/cpufreq-set.c:25
+#, fuzzy, c-format
+msgid "Usage: cpupower frequency-set [options]\n"
+msgstr "Usage : cpufreq-set [options]\n"
+
+#: utils/cpufreq-set.c:27
+#, c-format
+msgid ""
+"  -d FREQ, --min FREQ      new minimum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -d FREQ, --min FREQ       nouvelle fréquence minimale du CPU à utiliser\n"
+"                            par le régulateur\n"
+
+#: utils/cpufreq-set.c:28
+#, c-format
+msgid ""
+"  -u FREQ, --max FREQ      new maximum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -u FREQ, --max FREQ       nouvelle fréquence maximale du CPU à utiliser\n"
+"                            par le régulateur\n"
+
+#: utils/cpufreq-set.c:29
+#, c-format
+msgid "  -g GOV, --governor GOV   new cpufreq governor\n"
+msgstr "  -g GOV, --governor GOV   active le régulateur GOV\n"
+
+#: utils/cpufreq-set.c:30
+#, c-format
+msgid ""
+"  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
+"                           governor to be available and loaded\n"
+msgstr ""
+"  -f FREQ, --freq FREQ     fixe la fréquence du processeur à FREQ. Il faut\n"
+"                           que le régulateur « userspace » soit disponible \n"
+"                           et activé.\n"
+
+#: utils/cpufreq-set.c:32
+#, c-format
+msgid "  -r, --related            Switches all hardware-related CPUs\n"
+msgstr ""
+
+#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
+#, fuzzy, c-format
+msgid "  -h, --help               Prints out this screen\n"
+msgstr "  -h, --help           affiche l'aide-mémoire\n"
+
+#: utils/cpufreq-set.c:35
+#, fuzzy, c-format
+msgid ""
+"Notes:\n"
+"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
+msgstr "Les arguments avec un * utiliseront le CPU 0 si -c (--cpu) est omis\n"
+
+#: utils/cpufreq-set.c:37
+#, fuzzy, c-format
+msgid ""
+"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
+"parameter\n"
+"   except the -c CPU, --cpu CPU parameter\n"
+"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
+"   by postfixing the value with the wanted unit name, without any space\n"
+"   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+msgstr ""
+"Remarque :\n"
+"1. Le CPU numéro 0 sera utilisé par défaut si -c (ou --cpu) est omis ;\n"
+"2. l'argument -f FREQ (ou --freq FREQ) ne peut être utilisé qu'avec --cpu ;\n"
+"3. on pourra préciser l'unité des fréquences en postfixant sans aucune "
+"espace\n"
+"   les valeurs par hz, kHz (par défaut), MHz, GHz ou THz\n"
+"   (kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+
+#: utils/cpufreq-set.c:57
+#, c-format
+msgid ""
+"Error setting new values. Common errors:\n"
+"- Do you have proper administration rights? (super-user?)\n"
+"- Is the governor you requested available and modprobed?\n"
+"- Trying to set an invalid policy?\n"
+"- Trying to set a specific frequency, but userspace governor is not "
+"available,\n"
+"   for example because of hardware which cannot be set to a specific "
+"frequency\n"
+"   or because the userspace governor isn't loaded?\n"
+msgstr ""
+"En ajustant les nouveaux paramètres, une erreur est apparue. Les sources\n"
+"d'erreur typique sont :\n"
+"- droit d'administration insuffisant (êtes-vous root ?) ;\n"
+"- le régulateur choisi n'est pas disponible, ou bien n'est pas disponible "
+"en\n"
+"  tant que module noyau ;\n"
+"- la tactique n'est pas disponible ;\n"
+"- vous voulez utiliser l'option -f/--freq, mais le régulateur « userspace »\n"
+"  n'est pas disponible, par exemple parce que le matériel ne le supporte\n"
+"  pas, ou bien n'est tout simplement pas chargé.\n"
+
+#: utils/cpufreq-set.c:170
+#, c-format
+msgid "wrong, unknown or unhandled CPU?\n"
+msgstr "CPU inconnu ou non supporté ?\n"
+
+#: utils/cpufreq-set.c:302
+#, c-format
+msgid ""
+"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
+"-g/--governor parameters\n"
+msgstr ""
+"l'option -f/--freq est incompatible avec les options -d/--min, -u/--max et\n"
+"-g/--governor\n"
+
+#: utils/cpufreq-set.c:308
+#, c-format
+msgid ""
+"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
+"-g/--governor must be passed\n"
+msgstr ""
+"L'un de ces paramètres est obligatoire : -f/--freq, -d/--min, -u/--max et\n"
+"-g/--governor\n"
+
+#: utils/cpufreq-set.c:347
+#, c-format
+msgid "Setting cpu: %d\n"
+msgstr ""
+
+#: utils/cpupower-set.c:22
+#, c-format
+msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:24
+#, c-format
+msgid ""
+"  -b, --perf-bias [VAL]    Sets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-set.c:26
+#, c-format
+msgid ""
+"  -m, --sched-mc  [VAL]    Sets the kernel's multi core scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:27
+#, c-format
+msgid ""
+"  -s, --sched-smt [VAL]    Sets the kernel's thread sibling scheduler "
+"policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:80
+#, c-format
+msgid "--perf-bias param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:91
+#, c-format
+msgid "--sched-mc param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:102
+#, c-format
+msgid "--sched-smt param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:121
+#, c-format
+msgid "Error setting sched-mc %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:127
+#, c-format
+msgid "Error setting sched-smt %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:146
+#, c-format
+msgid "Error setting perf-bias value on CPU %d\n"
+msgstr ""
+
+#: utils/cpupower-info.c:21
+#, c-format
+msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
+msgstr ""
+
+#: utils/cpupower-info.c:23
+#, c-format
+msgid ""
+"  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-info.c:25
+#, fuzzy, c-format
+msgid "  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"
+msgstr "  -p, --policy         Affiche la tactique actuelle de cpufreq *\n"
+
+#: utils/cpupower-info.c:26
+#, c-format
+msgid ""
+"  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-info.c:28
+#, c-format
+msgid ""
+"\n"
+"Passing no option will show all info, by default only on core 0\n"
+msgstr ""
+
+#: utils/cpupower-info.c:102
+#, c-format
+msgid "System's multi core scheduler setting: "
+msgstr ""
+
+#. if sysfs file is missing it's: errno == ENOENT
+#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
+#, c-format
+msgid "not supported\n"
+msgstr ""
+
+#: utils/cpupower-info.c:111
+#, c-format
+msgid "System's thread sibling scheduler setting: "
+msgstr ""
+
+#: utils/cpupower-info.c:126
+#, c-format
+msgid "Intel's performance bias setting needs root privileges\n"
+msgstr ""
+
+#: utils/cpupower-info.c:128
+#, c-format
+msgid "System does not support Intel's performance bias setting\n"
+msgstr ""
+
+#: utils/cpupower-info.c:147
+#, c-format
+msgid "Could not read perf-bias value\n"
+msgstr ""
+
+#: utils/cpupower-info.c:150
+#, c-format
+msgid "perf-bias: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:28
+#, fuzzy, c-format
+msgid "Analyzing CPU %d:\n"
+msgstr "analyse du CPU %d :\n"
+
+#: utils/cpuidle-info.c:32
+#, c-format
+msgid "CPU %u: No idle states\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:36
+#, c-format
+msgid "CPU %u: Can't read idle state info\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:41
+#, c-format
+msgid "Could not determine max idle state %u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:46
+#, c-format
+msgid "Number of idle states: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:48
+#, fuzzy, c-format
+msgid "Available idle states:"
+msgstr "  plage de fréquence : "
+
+#: utils/cpuidle-info.c:71
+#, c-format
+msgid "Flags/Description: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:74
+#, c-format
+msgid "Latency: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:76
+#, c-format
+msgid "Usage: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:78
+#, c-format
+msgid "Duration: %llu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:90
+#, c-format
+msgid "Could not determine cpuidle driver\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:94
+#, fuzzy, c-format
+msgid "CPUidle driver: %s\n"
+msgstr "  pilote : %s\n"
+
+#: utils/cpuidle-info.c:99
+#, c-format
+msgid "Could not determine cpuidle governor\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:103
+#, c-format
+msgid "CPUidle governor: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:122
+#, c-format
+msgid "CPU %u: Can't read C-state info\n"
+msgstr ""
+
+#. printf("Cstates: %d\n", cstates);
+#: utils/cpuidle-info.c:127
+#, c-format
+msgid "active state:            C0\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:128
+#, c-format
+msgid "max_cstate:              C%u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:129
+#, c-format
+msgid "maximum allowed latency: %lu usec\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:130
+#, c-format
+msgid "states:\t\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:132
+#, c-format
+msgid "    C%d:                  type[C%d] "
+msgstr ""
+
+#: utils/cpuidle-info.c:134
+#, c-format
+msgid "promotion[--] demotion[--] "
+msgstr ""
+
+#: utils/cpuidle-info.c:135
+#, c-format
+msgid "latency[%03lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:137
+#, c-format
+msgid "usage[%08lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:139
+#, c-format
+msgid "duration[%020Lu] \n"
+msgstr ""
+
+#: utils/cpuidle-info.c:147
+#, fuzzy, c-format
+msgid "Usage: cpupower idleinfo [options]\n"
+msgstr "Usage : cpufreq-info [options]\n"
+
+#: utils/cpuidle-info.c:149
+#, fuzzy, c-format
+msgid "  -s, --silent         Only show general C-state information\n"
+msgstr "  -e, --debug          Afficher les informations de déboguage\n"
+
+#: utils/cpuidle-info.c:150
+#, fuzzy, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"acpi/processor/*/power\n"
+"                       interface in older kernels\n"
+msgstr ""
+"  -o, --proc           Affiche les informations en utilisant l'interface\n"
+"                       fournie par /proc/cpufreq, présente dans les "
+"versions\n"
+"                       2.4 et les anciennes versions 2.6 du noyau\n"
+
+#: utils/cpuidle-info.c:209
+#, fuzzy, c-format
+msgid "You can't specify more than one output-specific argument\n"
+msgstr ""
+"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
+"spécifier plus d'un argument de formatage\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU    CPU number which information shall be determined "
+#~ "about\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU    Numéro du CPU pour lequel l'information sera "
+#~ "affichée\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU        number of CPU where cpufreq settings shall be "
+#~ "modified\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU        numéro du CPU à prendre en compte pour les\n"
+#~ "                           changements\n"
diff --git a/tools/power/cpupower/po/it.po b/tools/power/cpupower/po/it.po
new file mode 100644 (file)
index 0000000..f80c4dd
--- /dev/null
@@ -0,0 +1,961 @@
+# Italian translations for cpufrequtils package
+# Copyright (C) 2004-2009
+# This file is distributed under the same license as the cpufrequtils package.
+# Mattia Dongili <malattia@gmail.com>.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cpufrequtils 0.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-03-08 17:03+0100\n"
+"PO-Revision-Date: 2009-08-15 12:00+0900\n"
+"Last-Translator: Mattia Dongili <malattia@gmail.com>\n"
+"Language-Team: NONE\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: utils/idle_monitor/nhm_idle.c:36
+msgid "Processor Core C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:43
+msgid "Processor Core C6"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:51
+msgid "Processor Package C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
+msgid "Processor Package C6"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:33
+msgid "Processor Core C7"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:40
+msgid "Processor Package C2"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:47
+msgid "Processor Package C7"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:56
+msgid "Package in sleep state (PC1 or deeper)"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:63
+msgid "Processor Package C1"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:77
+msgid "North Bridge P1 boolean counter (returns 0 or 1)"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:35
+msgid "Processor Core not idle"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:42
+msgid "Processor Core in an idle state"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:50
+msgid "Average Frequency (including boost) in MHz"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:66
+#, c-format
+msgid ""
+"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:69
+#, c-format
+msgid ""
+"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:71
+#, c-format
+msgid "\t -v: be more verbose\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:73
+#, c-format
+msgid "\t -h: print this help\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:74
+#, c-format
+msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:75
+#, c-format
+msgid "\t -t: show CPU topology/hierarchy\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:76
+#, c-format
+msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:77
+#, c-format
+msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:79
+#, c-format
+msgid ""
+"only one of: -t, -l, -m are allowed\n"
+"If none of them is passed,"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:80
+#, c-format
+msgid " all supported monitors are shown\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:197
+#, c-format
+msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:207
+#, c-format
+msgid " *is offline\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:236
+#, c-format
+msgid "%s: max monitor name length (%d) exceeded\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:250
+#, c-format
+msgid "No matching monitor found in %s, try -l option\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:266
+#, c-format
+msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:319
+#, c-format
+msgid "%s took %.5f seconds and exited with status %d\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:406
+#, c-format
+msgid "Cannot read number of available processors\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:417
+#, c-format
+msgid "Available monitor %s needs root access\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:428
+#, c-format
+msgid "No HW Cstate monitors found\n"
+msgstr ""
+
+#: utils/cpupower.c:78
+#, c-format
+msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
+msgstr ""
+
+#: utils/cpupower.c:79
+#, c-format
+msgid "cpupower --version\n"
+msgstr ""
+
+#: utils/cpupower.c:80
+#, c-format
+msgid "Supported subcommands are:\n"
+msgstr ""
+
+#: utils/cpupower.c:83
+#, c-format
+msgid ""
+"\n"
+"Some subcommands can make use of the -c cpulist option.\n"
+msgstr ""
+
+#: utils/cpupower.c:84
+#, c-format
+msgid "Look at the general cpupower manpage how to use it\n"
+msgstr ""
+
+#: utils/cpupower.c:85
+#, c-format
+msgid "and read up the subcommand's manpage whether it is supported.\n"
+msgstr ""
+
+#: utils/cpupower.c:86
+#, c-format
+msgid ""
+"\n"
+"Use cpupower help subcommand for getting help for above subcommands.\n"
+msgstr ""
+
+#: utils/cpupower.c:91
+#, c-format
+msgid "Report errors and bugs to %s, please.\n"
+msgstr "Per favore, comunicare errori e malfunzionamenti a %s.\n"
+
+#: utils/cpupower.c:114
+#, c-format
+msgid "Error parsing cpu list\n"
+msgstr ""
+
+#: utils/cpupower.c:172
+#, c-format
+msgid "Subcommand %s needs root privileges\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:31
+#, c-format
+msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
+msgstr "Impossibile determinare il numero di CPU (%s: %s), assumo sia 1\n"
+
+#: utils/cpufreq-info.c:63
+#, c-format
+msgid ""
+"          minimum CPU frequency  -  maximum CPU frequency  -  governor\n"
+msgstr ""
+"          frequenza minima CPU   -  frequenza massima CPU  -  gestore\n"
+
+#: utils/cpufreq-info.c:151
+#, c-format
+msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
+msgstr ""
+
+#. P state changes via MSR are identified via cpuid 80000007
+#. on Intel and AMD, but we assume boost capable machines can do that
+#. if (cpuid_eax(0x80000000) >= 0x80000007
+#. && (cpuid_edx(0x80000007) & (1 << 7)))
+#.
+#: utils/cpufreq-info.c:161
+#, c-format
+msgid "  boost state support: \n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163
+#, c-format
+msgid "    Supported: %s\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "yes"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "no"
+msgstr ""
+
+#: utils/cpufreq-info.c:164
+#, fuzzy, c-format
+msgid "    Active: %s\n"
+msgstr "  modulo %s\n"
+
+#: utils/cpufreq-info.c:177
+#, c-format
+msgid "    Boost States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:178
+#, c-format
+msgid "    Total States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:181
+#, c-format
+msgid "    Pstate-Pb%d: %luMHz (boost state)\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:184
+#, c-format
+msgid "    Pstate-P%d:  %luMHz\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:211
+#, c-format
+msgid "  no or unknown cpufreq driver is active on this CPU\n"
+msgstr "  nessun modulo o modulo cpufreq sconosciuto per questa CPU\n"
+
+#: utils/cpufreq-info.c:213
+#, c-format
+msgid "  driver: %s\n"
+msgstr "  modulo %s\n"
+
+#: utils/cpufreq-info.c:219
+#, c-format
+msgid "  CPUs which run at the same hardware frequency: "
+msgstr "  CPU che operano alla stessa frequenza hardware: "
+
+#: utils/cpufreq-info.c:230
+#, c-format
+msgid "  CPUs which need to have their frequency coordinated by software: "
+msgstr "  CPU che è necessario siano coordinate dal software: "
+
+#: utils/cpufreq-info.c:241
+#, c-format
+msgid "  maximum transition latency: "
+msgstr "  latenza massima durante la transizione: "
+
+#: utils/cpufreq-info.c:247
+#, c-format
+msgid "  hardware limits: "
+msgstr "  limiti hardware: "
+
+#: utils/cpufreq-info.c:256
+#, c-format
+msgid "  available frequency steps: "
+msgstr "  frequenze disponibili: "
+
+#: utils/cpufreq-info.c:269
+#, c-format
+msgid "  available cpufreq governors: "
+msgstr "  gestori disponibili: "
+
+#: utils/cpufreq-info.c:280
+#, c-format
+msgid "  current policy: frequency should be within "
+msgstr "  gestore attuale: la frequenza deve mantenersi tra "
+
+#: utils/cpufreq-info.c:282
+#, c-format
+msgid " and "
+msgstr " e "
+
+#: utils/cpufreq-info.c:286
+#, c-format
+msgid ""
+"The governor \"%s\" may decide which speed to use\n"
+"                  within this range.\n"
+msgstr ""
+" Il gestore \"%s\" può decidere quale velocità usare\n"
+"                  in questo intervallo.\n"
+
+#: utils/cpufreq-info.c:293
+#, c-format
+msgid "  current CPU frequency is "
+msgstr "  la frequenza attuale della CPU è "
+
+#: utils/cpufreq-info.c:296
+#, c-format
+msgid " (asserted by call to hardware)"
+msgstr " (ottenuta da una chiamata diretta all'hardware)"
+
+#: utils/cpufreq-info.c:304
+#, c-format
+msgid "  cpufreq stats: "
+msgstr " statistiche cpufreq:"
+
+#: utils/cpufreq-info.c:472
+#, fuzzy, c-format
+msgid "Usage: cpupower freqinfo [options]\n"
+msgstr "Uso: cpufreq-info [opzioni]\n"
+
+#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
+#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
+#, c-format
+msgid "Options:\n"
+msgstr "Opzioni:\n"
+
+#: utils/cpufreq-info.c:474
+#, fuzzy, c-format
+msgid "  -e, --debug          Prints out debug information [default]\n"
+msgstr "  -e, --debug          Mostra informazioni di debug\n"
+
+#: utils/cpufreq-info.c:475
+#, c-format
+msgid ""
+"  -f, --freq           Get frequency the CPU currently runs at, according\n"
+"                       to the cpufreq core *\n"
+msgstr ""
+"  -f, --freq           Mostra la frequenza attuale della CPU secondo\n"
+"                       il modulo cpufreq *\n"
+
+#: utils/cpufreq-info.c:477
+#, c-format
+msgid ""
+"  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
+"                       it from hardware (only available to root) *\n"
+msgstr ""
+"  -w, --hwfreq         Mostra la frequenza attuale della CPU leggendola\n"
+"                       dall'hardware (disponibile solo per l'utente root) *\n"
+
+#: utils/cpufreq-info.c:479
+#, c-format
+msgid ""
+"  -l, --hwlimits       Determine the minimum and maximum CPU frequency "
+"allowed *\n"
+msgstr ""
+"  -l, --hwlimits       Determina le frequenze minima e massima possibili per "
+"la CPU *\n"
+
+#: utils/cpufreq-info.c:480
+#, c-format
+msgid "  -d, --driver         Determines the used cpufreq kernel driver *\n"
+msgstr ""
+"  -d, --driver         Determina il modulo cpufreq del kernel in uso *\n"
+
+#: utils/cpufreq-info.c:481
+#, c-format
+msgid "  -p, --policy         Gets the currently used cpufreq policy *\n"
+msgstr ""
+"  -p, --policy         Mostra il gestore cpufreq attualmente in uso *\n"
+
+#: utils/cpufreq-info.c:482
+#, c-format
+msgid "  -g, --governors      Determines available cpufreq governors *\n"
+msgstr "  -g, --governors      Determina i gestori cpufreq disponibili *\n"
+
+#: utils/cpufreq-info.c:483
+#, c-format
+msgid ""
+"  -r, --related-cpus   Determines which CPUs run at the same hardware "
+"frequency *\n"
+msgstr ""
+"  -r, --related-cpus   Determina quali CPU operano alla stessa frequenza *\n"
+
+#: utils/cpufreq-info.c:484
+#, c-format
+msgid ""
+"  -a, --affected-cpus  Determines which CPUs need to have their frequency\n"
+"                       coordinated by software *\n"
+msgstr ""
+"  -a, --affected-cpus  Determina quali CPU devono avere la frequenza\n"
+"                       coordinata dal software *\n"
+
+#: utils/cpufreq-info.c:486
+#, c-format
+msgid "  -s, --stats          Shows cpufreq statistics if available\n"
+msgstr "  -s, --stats          Mostra le statistiche se disponibili\n"
+
+#: utils/cpufreq-info.c:487
+#, c-format
+msgid ""
+"  -y, --latency        Determines the maximum latency on CPU frequency "
+"changes *\n"
+msgstr ""
+"  -y, --latency        Determina la latenza massima durante i cambi di "
+"frequenza *\n"
+
+#: utils/cpufreq-info.c:488
+#, c-format
+msgid "  -b, --boost          Checks for turbo or boost modes  *\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:489
+#, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"cpufreq\n"
+"                       interface in 2.4. and early 2.6. kernels\n"
+msgstr ""
+"  -o, --proc           Stampa le informazioni come se provenissero dalla\n"
+"                       interfaccia cpufreq /proc/ presente nei kernel\n"
+"                       2.4 ed i primi 2.6\n"
+
+#: utils/cpufreq-info.c:491
+#, c-format
+msgid ""
+"  -m, --human          human-readable output for the -f, -w, -s and -y "
+"parameters\n"
+msgstr ""
+"  -m, --human          formatta l'output delle opzioni -f, -w, -s e -y in "
+"maniera\n"
+"                       leggibile da un essere umano\n"
+
+#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
+#, c-format
+msgid "  -h, --help           Prints out this screen\n"
+msgstr "  -h, --help           Stampa questa schermata\n"
+
+#: utils/cpufreq-info.c:495
+#, c-format
+msgid ""
+"If no argument or only the -c, --cpu parameter is given, debug output about\n"
+"cpufreq is printed which is useful e.g. for reporting bugs.\n"
+msgstr ""
+"Se non viene specificata nessuna opzione o viene specificata solo l'opzione -"
+"c, --cpu,\n"
+"le informazioni di debug per cpufreq saranno utili ad esempio a riportare i "
+"bug.\n"
+
+#: utils/cpufreq-info.c:497
+#, c-format
+msgid ""
+"For the arguments marked with *, omitting the -c or --cpu argument is\n"
+"equivalent to setting it to zero\n"
+msgstr ""
+"Per le opzioni segnalate con *, omettere l'opzione -c o --cpu è come "
+"specificarla\n"
+"con il valore 0\n"
+
+#: utils/cpufreq-info.c:580
+#, c-format
+msgid ""
+"The argument passed to this tool can't be combined with passing a --cpu "
+"argument\n"
+msgstr ""
+"L'opzione specificata a questo programma non può essere combinata con --cpu\n"
+
+#: utils/cpufreq-info.c:596
+#, c-format
+msgid ""
+"You can't specify more than one --cpu parameter and/or\n"
+"more than one output-specific argument\n"
+msgstr ""
+"Non è possibile specificare più di una volta l'opzione --cpu e/o\n"
+"specificare più di un parametro di output specifico\n"
+
+#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
+#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
+#, c-format
+msgid "invalid or unknown argument\n"
+msgstr "opzione sconosciuta o non valida\n"
+
+#: utils/cpufreq-info.c:617
+#, c-format
+msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
+msgstr "impossibile analizzare la CPU %d poiché non sembra essere presente\n"
+
+#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
+#, c-format
+msgid "analyzing CPU %d:\n"
+msgstr "analisi della CPU %d:\n"
+
+#: utils/cpufreq-set.c:25
+#, fuzzy, c-format
+msgid "Usage: cpupower frequency-set [options]\n"
+msgstr "Uso: cpufreq-set [opzioni]\n"
+
+#: utils/cpufreq-set.c:27
+#, c-format
+msgid ""
+"  -d FREQ, --min FREQ      new minimum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -d FREQ, --min FREQ      la nuova frequenza minima che il gestore cpufreq "
+"può scegliere\n"
+
+#: utils/cpufreq-set.c:28
+#, c-format
+msgid ""
+"  -u FREQ, --max FREQ      new maximum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -u FREQ, --max FREQ      la nuova frequenza massima che il gestore cpufreq "
+"può scegliere\n"
+
+#: utils/cpufreq-set.c:29
+#, c-format
+msgid "  -g GOV, --governor GOV   new cpufreq governor\n"
+msgstr "  -g GOV, --governor GOV   nuovo gestore cpufreq\n"
+
+#: utils/cpufreq-set.c:30
+#, c-format
+msgid ""
+"  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
+"                           governor to be available and loaded\n"
+msgstr ""
+"  -f FREQ, --freq FREQ     specifica la frequenza a cui impostare la CPU.\n"
+"                           È necessario che il gestore userspace sia "
+"disponibile e caricato\n"
+
+#: utils/cpufreq-set.c:32
+#, c-format
+msgid "  -r, --related            Switches all hardware-related CPUs\n"
+msgstr ""
+"  -r, --related            Modifica tutte le CPU coordinate dall'hardware\n"
+
+#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
+#, c-format
+msgid "  -h, --help               Prints out this screen\n"
+msgstr "  -h, --help               Stampa questa schermata\n"
+
+#: utils/cpufreq-set.c:35
+#, fuzzy, c-format
+msgid ""
+"Notes:\n"
+"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
+msgstr ""
+"Per le opzioni segnalate con *, omettere l'opzione -c o --cpu è come "
+"specificarla\n"
+"con il valore 0\n"
+
+#: utils/cpufreq-set.c:37
+#, fuzzy, c-format
+msgid ""
+"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
+"parameter\n"
+"   except the -c CPU, --cpu CPU parameter\n"
+"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
+"   by postfixing the value with the wanted unit name, without any space\n"
+"   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+msgstr ""
+"Note:\n"
+"1. Omettere l'opzione -c o --cpu è equivalente a impostarlo a 0\n"
+"2. l'opzione -f FREQ, --freq FREQ non può essere specificata con altre "
+"opzioni\n"
+"   ad eccezione dell'opzione -c CPU o --cpu CPU\n"
+"3. le FREQuenze possono essere specuficate in  Hz, kHz (default), MHz, GHz, "
+"or THz\n"
+"   postponendo l'unità di misura al valore senza nessuno spazio fra loro\n"
+"   (FREQuenza in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+
+#: utils/cpufreq-set.c:57
+#, c-format
+msgid ""
+"Error setting new values. Common errors:\n"
+"- Do you have proper administration rights? (super-user?)\n"
+"- Is the governor you requested available and modprobed?\n"
+"- Trying to set an invalid policy?\n"
+"- Trying to set a specific frequency, but userspace governor is not "
+"available,\n"
+"   for example because of hardware which cannot be set to a specific "
+"frequency\n"
+"   or because the userspace governor isn't loaded?\n"
+msgstr ""
+"Si sono verificati degli errori impostando i nuovi valori.\n"
+"Alcuni errori comuni possono essere:\n"
+"- Hai i necessari diritti di amministrazione? (super-user?)\n"
+"- Il gestore che hai richiesto è disponibile e caricato?\n"
+"- Stai provando ad impostare una politica di gestione non valida?\n"
+"- Stai provando a impostare una specifica frequenza ma il gestore\n"
+"  userspace non è disponibile, per esempio a causa dell'hardware\n"
+"  che non supporta frequenze fisse o a causa del fatto che\n"
+"  il gestore userspace non è caricato?\n"
+
+#: utils/cpufreq-set.c:170
+#, c-format
+msgid "wrong, unknown or unhandled CPU?\n"
+msgstr "CPU errata, sconosciuta o non gestita?\n"
+
+#: utils/cpufreq-set.c:302
+#, c-format
+msgid ""
+"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
+"-g/--governor parameters\n"
+msgstr ""
+"l'opzione -f/--freq non può venire combinata con i parametri\n"
+" -d/--min, -u/--max o -g/--governor\n"
+
+#: utils/cpufreq-set.c:308
+#, c-format
+msgid ""
+"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
+"-g/--governor must be passed\n"
+msgstr ""
+"Almeno una delle opzioni -f/--freq, -d/--min, -u/--max, e -g/--governor\n"
+"deve essere specificata\n"
+
+#: utils/cpufreq-set.c:347
+#, c-format
+msgid "Setting cpu: %d\n"
+msgstr ""
+
+#: utils/cpupower-set.c:22
+#, c-format
+msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:24
+#, c-format
+msgid ""
+"  -b, --perf-bias [VAL]    Sets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-set.c:26
+#, c-format
+msgid ""
+"  -m, --sched-mc  [VAL]    Sets the kernel's multi core scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:27
+#, c-format
+msgid ""
+"  -s, --sched-smt [VAL]    Sets the kernel's thread sibling scheduler "
+"policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:80
+#, c-format
+msgid "--perf-bias param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:91
+#, c-format
+msgid "--sched-mc param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:102
+#, c-format
+msgid "--sched-smt param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:121
+#, c-format
+msgid "Error setting sched-mc %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:127
+#, c-format
+msgid "Error setting sched-smt %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:146
+#, c-format
+msgid "Error setting perf-bias value on CPU %d\n"
+msgstr ""
+
+#: utils/cpupower-info.c:21
+#, c-format
+msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
+msgstr ""
+
+#: utils/cpupower-info.c:23
+#, c-format
+msgid ""
+"  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-info.c:25
+#, fuzzy, c-format
+msgid "  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"
+msgstr ""
+"  -p, --policy         Mostra il gestore cpufreq attualmente in uso *\n"
+
+#: utils/cpupower-info.c:26
+#, c-format
+msgid ""
+"  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-info.c:28
+#, c-format
+msgid ""
+"\n"
+"Passing no option will show all info, by default only on core 0\n"
+msgstr ""
+
+#: utils/cpupower-info.c:102
+#, c-format
+msgid "System's multi core scheduler setting: "
+msgstr ""
+
+#. if sysfs file is missing it's: errno == ENOENT
+#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
+#, c-format
+msgid "not supported\n"
+msgstr ""
+
+#: utils/cpupower-info.c:111
+#, c-format
+msgid "System's thread sibling scheduler setting: "
+msgstr ""
+
+#: utils/cpupower-info.c:126
+#, c-format
+msgid "Intel's performance bias setting needs root privileges\n"
+msgstr ""
+
+#: utils/cpupower-info.c:128
+#, c-format
+msgid "System does not support Intel's performance bias setting\n"
+msgstr ""
+
+#: utils/cpupower-info.c:147
+#, c-format
+msgid "Could not read perf-bias value\n"
+msgstr ""
+
+#: utils/cpupower-info.c:150
+#, c-format
+msgid "perf-bias: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:28
+#, fuzzy, c-format
+msgid "Analyzing CPU %d:\n"
+msgstr "analisi della CPU %d:\n"
+
+#: utils/cpuidle-info.c:32
+#, c-format
+msgid "CPU %u: No idle states\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:36
+#, c-format
+msgid "CPU %u: Can't read idle state info\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:41
+#, c-format
+msgid "Could not determine max idle state %u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:46
+#, c-format
+msgid "Number of idle states: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:48
+#, fuzzy, c-format
+msgid "Available idle states:"
+msgstr "  frequenze disponibili: "
+
+#: utils/cpuidle-info.c:71
+#, c-format
+msgid "Flags/Description: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:74
+#, c-format
+msgid "Latency: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:76
+#, c-format
+msgid "Usage: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:78
+#, c-format
+msgid "Duration: %llu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:90
+#, c-format
+msgid "Could not determine cpuidle driver\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:94
+#, fuzzy, c-format
+msgid "CPUidle driver: %s\n"
+msgstr "  modulo %s\n"
+
+#: utils/cpuidle-info.c:99
+#, c-format
+msgid "Could not determine cpuidle governor\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:103
+#, c-format
+msgid "CPUidle governor: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:122
+#, c-format
+msgid "CPU %u: Can't read C-state info\n"
+msgstr ""
+
+#. printf("Cstates: %d\n", cstates);
+#: utils/cpuidle-info.c:127
+#, c-format
+msgid "active state:            C0\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:128
+#, c-format
+msgid "max_cstate:              C%u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:129
+#, fuzzy, c-format
+msgid "maximum allowed latency: %lu usec\n"
+msgstr "  latenza massima durante la transizione: "
+
+#: utils/cpuidle-info.c:130
+#, c-format
+msgid "states:\t\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:132
+#, c-format
+msgid "    C%d:                  type[C%d] "
+msgstr ""
+
+#: utils/cpuidle-info.c:134
+#, c-format
+msgid "promotion[--] demotion[--] "
+msgstr ""
+
+#: utils/cpuidle-info.c:135
+#, c-format
+msgid "latency[%03lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:137
+#, c-format
+msgid "usage[%08lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:139
+#, c-format
+msgid "duration[%020Lu] \n"
+msgstr ""
+
+#: utils/cpuidle-info.c:147
+#, fuzzy, c-format
+msgid "Usage: cpupower idleinfo [options]\n"
+msgstr "Uso: cpufreq-info [opzioni]\n"
+
+#: utils/cpuidle-info.c:149
+#, fuzzy, c-format
+msgid "  -s, --silent         Only show general C-state information\n"
+msgstr "  -e, --debug          Mostra informazioni di debug\n"
+
+#: utils/cpuidle-info.c:150
+#, fuzzy, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"acpi/processor/*/power\n"
+"                       interface in older kernels\n"
+msgstr ""
+"  -o, --proc           Stampa le informazioni come se provenissero dalla\n"
+"                       interfaccia cpufreq /proc/ presente nei kernel\n"
+"                       2.4 ed i primi 2.6\n"
+
+#: utils/cpuidle-info.c:209
+#, fuzzy, c-format
+msgid "You can't specify more than one output-specific argument\n"
+msgstr ""
+"Non è possibile specificare più di una volta l'opzione --cpu e/o\n"
+"specificare più di un parametro di output specifico\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU    CPU number which information shall be determined "
+#~ "about\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU    Numero di CPU per la quale ottenere le "
+#~ "informazioni\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU        number of CPU where cpufreq settings shall be "
+#~ "modified\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU        numero di CPU per la quale modificare le "
+#~ "impostazioni\n"
+
+#, fuzzy
+#~ msgid "  CPUs which coordinate software frequency requirements: "
+#~ msgstr ""
+#~ "  CPU per le quali e` necessario cambiare la frequenza "
+#~ "contemporaneamente: "
diff --git a/tools/power/cpupower/po/pt.po b/tools/power/cpupower/po/pt.po
new file mode 100644 (file)
index 0000000..990f526
--- /dev/null
@@ -0,0 +1,957 @@
+# Brazilian Portuguese translations for cpufrequtils package
+# Copyright (C) 2008 THE cpufrequtils'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the cpufrequtils package.
+# Claudio Eduardo <claudioeddy@gmail.com>, 2009.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cpufrequtils 004\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-03-08 17:03+0100\n"
+"PO-Revision-Date: 2008-06-14 22:16-0400\n"
+"Last-Translator: Claudio Eduardo <claudioeddy@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: utils/idle_monitor/nhm_idle.c:36
+msgid "Processor Core C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:43
+msgid "Processor Core C6"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:51
+msgid "Processor Package C3"
+msgstr ""
+
+#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70
+msgid "Processor Package C6"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:33
+msgid "Processor Core C7"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:40
+msgid "Processor Package C2"
+msgstr ""
+
+#: utils/idle_monitor/snb_idle.c:47
+msgid "Processor Package C7"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:56
+msgid "Package in sleep state (PC1 or deeper)"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:63
+msgid "Processor Package C1"
+msgstr ""
+
+#: utils/idle_monitor/amd_fam14h_idle.c:77
+msgid "North Bridge P1 boolean counter (returns 0 or 1)"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:35
+msgid "Processor Core not idle"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:42
+msgid "Processor Core in an idle state"
+msgstr ""
+
+#: utils/idle_monitor/mperf_monitor.c:50
+msgid "Average Frequency (including boost) in MHz"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:66
+#, c-format
+msgid ""
+"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:69
+#, c-format
+msgid ""
+"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i "
+"interval_sec | -c command ...]\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:71
+#, c-format
+msgid "\t -v: be more verbose\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:73
+#, c-format
+msgid "\t -h: print this help\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:74
+#, c-format
+msgid "\t -i: time intervall to measure for in seconds (default 1)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:75
+#, c-format
+msgid "\t -t: show CPU topology/hierarchy\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:76
+#, c-format
+msgid "\t -l: list available CPU sleep monitors (for use with -m)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:77
+#, c-format
+msgid "\t -m: show specific CPU sleep monitors only (in same order)\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:79
+#, c-format
+msgid ""
+"only one of: -t, -l, -m are allowed\n"
+"If none of them is passed,"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:80
+#, c-format
+msgid " all supported monitors are shown\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:197
+#, c-format
+msgid "Monitor %s, Counter %s has no count function. Implementation error\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:207
+#, c-format
+msgid " *is offline\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:236
+#, c-format
+msgid "%s: max monitor name length (%d) exceeded\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:250
+#, c-format
+msgid "No matching monitor found in %s, try -l option\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:266
+#, c-format
+msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:319
+#, c-format
+msgid "%s took %.5f seconds and exited with status %d\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:406
+#, c-format
+msgid "Cannot read number of available processors\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:417
+#, c-format
+msgid "Available monitor %s needs root access\n"
+msgstr ""
+
+#: utils/idle_monitor/cpupower-monitor.c:428
+#, c-format
+msgid "No HW Cstate monitors found\n"
+msgstr ""
+
+#: utils/cpupower.c:78
+#, c-format
+msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n"
+msgstr ""
+
+#: utils/cpupower.c:79
+#, c-format
+msgid "cpupower --version\n"
+msgstr ""
+
+#: utils/cpupower.c:80
+#, c-format
+msgid "Supported subcommands are:\n"
+msgstr ""
+
+#: utils/cpupower.c:83
+#, c-format
+msgid ""
+"\n"
+"Some subcommands can make use of the -c cpulist option.\n"
+msgstr ""
+
+#: utils/cpupower.c:84
+#, c-format
+msgid "Look at the general cpupower manpage how to use it\n"
+msgstr ""
+
+#: utils/cpupower.c:85
+#, c-format
+msgid "and read up the subcommand's manpage whether it is supported.\n"
+msgstr ""
+
+#: utils/cpupower.c:86
+#, c-format
+msgid ""
+"\n"
+"Use cpupower help subcommand for getting help for above subcommands.\n"
+msgstr ""
+
+#: utils/cpupower.c:91
+#, c-format
+msgid "Report errors and bugs to %s, please.\n"
+msgstr "Reporte erros e bugs para %s, por favor.\n"
+
+#: utils/cpupower.c:114
+#, c-format
+msgid "Error parsing cpu list\n"
+msgstr ""
+
+#: utils/cpupower.c:172
+#, c-format
+msgid "Subcommand %s needs root privileges\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:31
+#, c-format
+msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
+msgstr "Não foi possível contar o número de CPUs (%s: %s), assumindo 1\n"
+
+#: utils/cpufreq-info.c:63
+#, c-format
+msgid ""
+"          minimum CPU frequency  -  maximum CPU frequency  -  governor\n"
+msgstr ""
+"          frequência mínina do CPU  -  frequência máxima do CPU  -  "
+"regulador\n"
+
+#: utils/cpufreq-info.c:151
+#, c-format
+msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n"
+msgstr ""
+
+#. P state changes via MSR are identified via cpuid 80000007
+#. on Intel and AMD, but we assume boost capable machines can do that
+#. if (cpuid_eax(0x80000000) >= 0x80000007
+#. && (cpuid_edx(0x80000007) & (1 << 7)))
+#.
+#: utils/cpufreq-info.c:161
+#, c-format
+msgid "  boost state support: \n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163
+#, c-format
+msgid "    Supported: %s\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "yes"
+msgstr ""
+
+#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164
+msgid "no"
+msgstr ""
+
+#: utils/cpufreq-info.c:164
+#, fuzzy, c-format
+msgid "    Active: %s\n"
+msgstr "  driver: %s\n"
+
+#: utils/cpufreq-info.c:177
+#, c-format
+msgid "    Boost States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:178
+#, c-format
+msgid "    Total States: %d\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:181
+#, c-format
+msgid "    Pstate-Pb%d: %luMHz (boost state)\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:184
+#, c-format
+msgid "    Pstate-P%d:  %luMHz\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:211
+#, c-format
+msgid "  no or unknown cpufreq driver is active on this CPU\n"
+msgstr "  nenhum ou driver do cpufreq deconhecido está ativo nesse CPU\n"
+
+#: utils/cpufreq-info.c:213
+#, c-format
+msgid "  driver: %s\n"
+msgstr "  driver: %s\n"
+
+#: utils/cpufreq-info.c:219
+#, c-format
+msgid "  CPUs which run at the same hardware frequency: "
+msgstr "  CPUs que rodam na mesma frequência de hardware: "
+
+#: utils/cpufreq-info.c:230
+#, c-format
+msgid "  CPUs which need to have their frequency coordinated by software: "
+msgstr "  CPUs que precisam ter suas frequências coordenadas por software: "
+
+#: utils/cpufreq-info.c:241
+#, c-format
+msgid "  maximum transition latency: "
+msgstr "  maior latência de transição: "
+
+#: utils/cpufreq-info.c:247
+#, c-format
+msgid "  hardware limits: "
+msgstr "  limites do hardware: "
+
+#: utils/cpufreq-info.c:256
+#, c-format
+msgid "  available frequency steps: "
+msgstr "  níveis de frequência disponíveis: "
+
+#: utils/cpufreq-info.c:269
+#, c-format
+msgid "  available cpufreq governors: "
+msgstr "  reguladores do cpufreq disponíveis: "
+
+#: utils/cpufreq-info.c:280
+#, c-format
+msgid "  current policy: frequency should be within "
+msgstr "  política de frequência atual deve estar entre "
+
+#: utils/cpufreq-info.c:282
+#, c-format
+msgid " and "
+msgstr " e "
+
+#: utils/cpufreq-info.c:286
+#, c-format
+msgid ""
+"The governor \"%s\" may decide which speed to use\n"
+"                  within this range.\n"
+msgstr ""
+"O regulador \"%s\" deve decidir qual velocidade usar\n"
+"                  dentro desse limite.\n"
+
+#: utils/cpufreq-info.c:293
+#, c-format
+msgid "  current CPU frequency is "
+msgstr "  frequência atual do CPU é "
+
+#: utils/cpufreq-info.c:296
+#, c-format
+msgid " (asserted by call to hardware)"
+msgstr " (declarado por chamada ao hardware)"
+
+#: utils/cpufreq-info.c:304
+#, c-format
+msgid "  cpufreq stats: "
+msgstr "  status do cpufreq: "
+
+#: utils/cpufreq-info.c:472
+#, fuzzy, c-format
+msgid "Usage: cpupower freqinfo [options]\n"
+msgstr "Uso: cpufreq-info [opções]\n"
+
+#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23
+#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148
+#, c-format
+msgid "Options:\n"
+msgstr "Opções:\n"
+
+#: utils/cpufreq-info.c:474
+#, fuzzy, c-format
+msgid "  -e, --debug          Prints out debug information [default]\n"
+msgstr "  -e, --debug          Mostra informação de debug\n"
+
+#: utils/cpufreq-info.c:475
+#, c-format
+msgid ""
+"  -f, --freq           Get frequency the CPU currently runs at, according\n"
+"                       to the cpufreq core *\n"
+msgstr ""
+"  -f, --freq           Obtem a frequência na qual o CPU roda no momento, de "
+"acordo\n"
+"                       com o núcleo do cpufreq *\n"
+
+#: utils/cpufreq-info.c:477
+#, c-format
+msgid ""
+"  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
+"                       it from hardware (only available to root) *\n"
+msgstr ""
+"  -w, --hwfreq         Obtem a frequência na qual o CPU está operando no "
+"momento,\n"
+"                       através de leitura no hardware (disponível somente "
+"para root) *\n"
+
+#: utils/cpufreq-info.c:479
+#, c-format
+msgid ""
+"  -l, --hwlimits       Determine the minimum and maximum CPU frequency "
+"allowed *\n"
+msgstr ""
+"  -l, --hwlimits       Determina a frequência mínima e máxima do CPU "
+"permitida *\n"
+
+#: utils/cpufreq-info.c:480
+#, c-format
+msgid "  -d, --driver         Determines the used cpufreq kernel driver *\n"
+msgstr ""
+"  -d,  --driver         Determina o driver do kernel do cpufreq usado *\n"
+
+#: utils/cpufreq-info.c:481
+#, c-format
+msgid "  -p, --policy         Gets the currently used cpufreq policy *\n"
+msgstr ""
+"--p, --policy         Obtem a política do cpufreq em uso no momento *\n"
+
+#: utils/cpufreq-info.c:482
+#, c-format
+msgid "  -g, --governors      Determines available cpufreq governors *\n"
+msgstr ""
+"  -g, --governors      Determina reguladores do cpufreq disponíveis *\n"
+
+#: utils/cpufreq-info.c:483
+#, c-format
+msgid ""
+"  -r, --related-cpus   Determines which CPUs run at the same hardware "
+"frequency *\n"
+msgstr ""
+"  -r, --related-cpus   Determina quais CPUs rodam na mesma frequência de "
+"hardware *\n"
+
+#: utils/cpufreq-info.c:484
+#, c-format
+msgid ""
+"  -a, --affected-cpus  Determines which CPUs need to have their frequency\n"
+"                       coordinated by software *\n"
+msgstr ""
+"  -a, --affected-cpus  Determina quais CPUs precisam ter suas frequências\n"
+"                       coordenadas por software *\n"
+
+#: utils/cpufreq-info.c:486
+#, c-format
+msgid "  -s, --stats          Shows cpufreq statistics if available\n"
+msgstr "  -s, --stats          Mostra estatísticas do cpufreq se disponíveis\n"
+
+#: utils/cpufreq-info.c:487
+#, c-format
+msgid ""
+"  -y, --latency        Determines the maximum latency on CPU frequency "
+"changes *\n"
+msgstr ""
+"  -y, --latency        Determina a latência máxima nas trocas de frequência "
+"do CPU *\n"
+
+#: utils/cpufreq-info.c:488
+#, c-format
+msgid "  -b, --boost          Checks for turbo or boost modes  *\n"
+msgstr ""
+
+#: utils/cpufreq-info.c:489
+#, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"cpufreq\n"
+"                       interface in 2.4. and early 2.6. kernels\n"
+msgstr ""
+"  -o, --proc           Mostra informação do tipo provida pela interface /"
+"proc/cpufreq\n"
+"                       em kernels 2.4. e mais recentes 2.6\n"
+
+#: utils/cpufreq-info.c:491
+#, c-format
+msgid ""
+"  -m, --human          human-readable output for the -f, -w, -s and -y "
+"parameters\n"
+msgstr ""
+"  -m, --human          saída legível para humanos para os parâmetros -f, -w, "
+"-s e -y\n"
+
+#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
+#, c-format
+msgid "  -h, --help           Prints out this screen\n"
+msgstr " -h, --help           Imprime essa tela\n"
+
+#: utils/cpufreq-info.c:495
+#, c-format
+msgid ""
+"If no argument or only the -c, --cpu parameter is given, debug output about\n"
+"cpufreq is printed which is useful e.g. for reporting bugs.\n"
+msgstr ""
+"Se nenhum argumento ou somente o parâmetro -c, --cpu é dado, informação de "
+"debug sobre\n"
+"o cpufreq é mostrada, o que é útil por exemplo para reportar bugs.\n"
+
+#: utils/cpufreq-info.c:497
+#, c-format
+msgid ""
+"For the arguments marked with *, omitting the -c or --cpu argument is\n"
+"equivalent to setting it to zero\n"
+msgstr ""
+"Para os argumentos marcados com *, omitir o argumento -c ou --cpu é\n"
+"equivalente a setá-lo como zero\n"
+
+#: utils/cpufreq-info.c:580
+#, c-format
+msgid ""
+"The argument passed to this tool can't be combined with passing a --cpu "
+"argument\n"
+msgstr ""
+"O argumento usado pra essa ferramenta não pode ser combinado com um "
+"argumento --cpu\n"
+
+#: utils/cpufreq-info.c:596
+#, c-format
+msgid ""
+"You can't specify more than one --cpu parameter and/or\n"
+"more than one output-specific argument\n"
+msgstr ""
+"Você não pode especificar mais do que um parâmetro --cpu e/ou\n"
+"mais do que um argumento de saída específico\n"
+
+#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
+#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
+#, c-format
+msgid "invalid or unknown argument\n"
+msgstr "argumento inválido ou desconhecido\n"
+
+#: utils/cpufreq-info.c:617
+#, c-format
+msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
+msgstr ""
+"não foi possível analisar o CPU % já que o mesmo parece não estar presente\n"
+
+#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
+#, c-format
+msgid "analyzing CPU %d:\n"
+msgstr "analisando o CPU %d:\n"
+
+#: utils/cpufreq-set.c:25
+#, fuzzy, c-format
+msgid "Usage: cpupower frequency-set [options]\n"
+msgstr "Uso: cpufreq-set [opções]\n"
+
+#: utils/cpufreq-set.c:27
+#, c-format
+msgid ""
+"  -d FREQ, --min FREQ      new minimum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -d FREQ, --min FREQ      nova frequência mínima do CPU que o regulador "
+"deve selecionar\n"
+
+#: utils/cpufreq-set.c:28
+#, c-format
+msgid ""
+"  -u FREQ, --max FREQ      new maximum CPU frequency the governor may "
+"select\n"
+msgstr ""
+"  -u FREQ, --max FREQ      nova frequência máxima do CPU que o regulador "
+"deve escolher\n"
+
+#: utils/cpufreq-set.c:29
+#, c-format
+msgid "  -g GOV, --governor GOV   new cpufreq governor\n"
+msgstr "  -g GOV, --governor GOV   novo regulador do cpufreq\n"
+
+#: utils/cpufreq-set.c:30
+#, c-format
+msgid ""
+"  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
+"                           governor to be available and loaded\n"
+msgstr ""
+"  -f FREQ, --freq FREQ     frequência específica para ser setada. Necessita "
+"que o regulador em\n"
+"                           nível de usuário esteja disponível e carregado\n"
+
+#: utils/cpufreq-set.c:32
+#, c-format
+msgid "  -r, --related            Switches all hardware-related CPUs\n"
+msgstr ""
+"  -r, --related            Modifica todos os CPUs relacionados ao hardware\n"
+
+#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
+#, c-format
+msgid "  -h, --help               Prints out this screen\n"
+msgstr " -h, --help           Mostra essa tela\n"
+
+#: utils/cpufreq-set.c:35
+#, fuzzy, c-format
+msgid ""
+"Notes:\n"
+"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"
+msgstr ""
+"Para os argumentos marcados com *, omitir o argumento -c ou --cpu é\n"
+"equivalente a setá-lo como zero\n"
+
+#: utils/cpufreq-set.c:37
+#, fuzzy, c-format
+msgid ""
+"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other "
+"parameter\n"
+"   except the -c CPU, --cpu CPU parameter\n"
+"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
+"   by postfixing the value with the wanted unit name, without any space\n"
+"   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+msgstr ""
+"Notas:\n"
+"1. Omitir o argumento -c or --cpu é equivalente a setá-lo como zero\n"
+"2. O parâmetro -f FREQ, --freq FREQ não pode ser combinado com qualquer "
+"outro parâmetro\n"
+"   exceto com o parâmetro -c CPU, --cpu CPU\n"
+"3. FREQuências podem ser usadas em Hz, kHz (padrão), MHz, GHz, o THz\n"
+"   colocando o nome desejado da unidade após o valor, sem qualquer espaço\n"
+"   (FREQuência em kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
+
+#: utils/cpufreq-set.c:57
+#, c-format
+msgid ""
+"Error setting new values. Common errors:\n"
+"- Do you have proper administration rights? (super-user?)\n"
+"- Is the governor you requested available and modprobed?\n"
+"- Trying to set an invalid policy?\n"
+"- Trying to set a specific frequency, but userspace governor is not "
+"available,\n"
+"   for example because of hardware which cannot be set to a specific "
+"frequency\n"
+"   or because the userspace governor isn't loaded?\n"
+msgstr ""
+"Erro ao setar novos valores. Erros comuns:\n"
+"- Você tem direitos administrativos necessários? (super-usuário?)\n"
+"- O regulador que você requesitou está disponível e foi \"modprobed\"?\n"
+"- Tentando setar uma política inválida?\n"
+"- Tentando setar uma frequência específica, mas o regulador em nível de "
+"usuário não está disponível,\n"
+"   por exemplo devido ao hardware que não pode ser setado pra uma frequência "
+"específica\n"
+"   ou porque o regulador em nível de usuário não foi carregado?\n"
+
+#: utils/cpufreq-set.c:170
+#, c-format
+msgid "wrong, unknown or unhandled CPU?\n"
+msgstr "CPU errado, desconhecido ou inesperado?\n"
+
+#: utils/cpufreq-set.c:302
+#, c-format
+msgid ""
+"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
+"-g/--governor parameters\n"
+msgstr ""
+"o parâmetro -f/--freq não pode ser combinado com os parâmetros -d/--min, -"
+"u/--max ou\n"
+"-g/--governor\n"
+
+#: utils/cpufreq-set.c:308
+#, c-format
+msgid ""
+"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
+"-g/--governor must be passed\n"
+msgstr ""
+"Pelo menos um parâmetro entre -f/--freq, -d/--min, -u/--max, e\n"
+"-g/--governor deve ser usado\n"
+
+#: utils/cpufreq-set.c:347
+#, c-format
+msgid "Setting cpu: %d\n"
+msgstr ""
+
+#: utils/cpupower-set.c:22
+#, c-format
+msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:24
+#, c-format
+msgid ""
+"  -b, --perf-bias [VAL]    Sets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-set.c:26
+#, c-format
+msgid ""
+"  -m, --sched-mc  [VAL]    Sets the kernel's multi core scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:27
+#, c-format
+msgid ""
+"  -s, --sched-smt [VAL]    Sets the kernel's thread sibling scheduler "
+"policy.\n"
+msgstr ""
+
+#: utils/cpupower-set.c:80
+#, c-format
+msgid "--perf-bias param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:91
+#, c-format
+msgid "--sched-mc param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:102
+#, c-format
+msgid "--sched-smt param out of range [0-%d]\n"
+msgstr ""
+
+#: utils/cpupower-set.c:121
+#, c-format
+msgid "Error setting sched-mc %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:127
+#, c-format
+msgid "Error setting sched-smt %s\n"
+msgstr ""
+
+#: utils/cpupower-set.c:146
+#, c-format
+msgid "Error setting perf-bias value on CPU %d\n"
+msgstr ""
+
+#: utils/cpupower-info.c:21
+#, c-format
+msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"
+msgstr ""
+
+#: utils/cpupower-info.c:23
+#, c-format
+msgid ""
+"  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
+"                           Intel models [0-15], see manpage for details\n"
+msgstr ""
+
+#: utils/cpupower-info.c:25
+#, fuzzy, c-format
+msgid "  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"
+msgstr ""
+"--p, --policy         Obtem a política do cpufreq em uso no momento *\n"
+
+#: utils/cpupower-info.c:26
+#, c-format
+msgid ""
+"  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"
+msgstr ""
+
+#: utils/cpupower-info.c:28
+#, c-format
+msgid ""
+"\n"
+"Passing no option will show all info, by default only on core 0\n"
+msgstr ""
+
+#: utils/cpupower-info.c:102
+#, c-format
+msgid "System's multi core scheduler setting: "
+msgstr ""
+
+#. if sysfs file is missing it's: errno == ENOENT
+#: utils/cpupower-info.c:105 utils/cpupower-info.c:114
+#, c-format
+msgid "not supported\n"
+msgstr ""
+
+#: utils/cpupower-info.c:111
+#, c-format
+msgid "System's thread sibling scheduler setting: "
+msgstr ""
+
+#: utils/cpupower-info.c:126
+#, c-format
+msgid "Intel's performance bias setting needs root privileges\n"
+msgstr ""
+
+#: utils/cpupower-info.c:128
+#, c-format
+msgid "System does not support Intel's performance bias setting\n"
+msgstr ""
+
+#: utils/cpupower-info.c:147
+#, c-format
+msgid "Could not read perf-bias value\n"
+msgstr ""
+
+#: utils/cpupower-info.c:150
+#, c-format
+msgid "perf-bias: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:28
+#, fuzzy, c-format
+msgid "Analyzing CPU %d:\n"
+msgstr "analisando o CPU %d:\n"
+
+#: utils/cpuidle-info.c:32
+#, c-format
+msgid "CPU %u: No idle states\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:36
+#, c-format
+msgid "CPU %u: Can't read idle state info\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:41
+#, c-format
+msgid "Could not determine max idle state %u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:46
+#, c-format
+msgid "Number of idle states: %d\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:48
+#, fuzzy, c-format
+msgid "Available idle states:"
+msgstr "  níveis de frequência disponíveis: "
+
+#: utils/cpuidle-info.c:71
+#, c-format
+msgid "Flags/Description: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:74
+#, c-format
+msgid "Latency: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:76
+#, c-format
+msgid "Usage: %lu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:78
+#, c-format
+msgid "Duration: %llu\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:90
+#, c-format
+msgid "Could not determine cpuidle driver\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:94
+#, fuzzy, c-format
+msgid "CPUidle driver: %s\n"
+msgstr "  driver: %s\n"
+
+#: utils/cpuidle-info.c:99
+#, c-format
+msgid "Could not determine cpuidle governor\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:103
+#, c-format
+msgid "CPUidle governor: %s\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:122
+#, c-format
+msgid "CPU %u: Can't read C-state info\n"
+msgstr ""
+
+#. printf("Cstates: %d\n", cstates);
+#: utils/cpuidle-info.c:127
+#, c-format
+msgid "active state:            C0\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:128
+#, c-format
+msgid "max_cstate:              C%u\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:129
+#, fuzzy, c-format
+msgid "maximum allowed latency: %lu usec\n"
+msgstr "  maior latência de transição: "
+
+#: utils/cpuidle-info.c:130
+#, c-format
+msgid "states:\t\n"
+msgstr ""
+
+#: utils/cpuidle-info.c:132
+#, c-format
+msgid "    C%d:                  type[C%d] "
+msgstr ""
+
+#: utils/cpuidle-info.c:134
+#, c-format
+msgid "promotion[--] demotion[--] "
+msgstr ""
+
+#: utils/cpuidle-info.c:135
+#, c-format
+msgid "latency[%03lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:137
+#, c-format
+msgid "usage[%08lu] "
+msgstr ""
+
+#: utils/cpuidle-info.c:139
+#, c-format
+msgid "duration[%020Lu] \n"
+msgstr ""
+
+#: utils/cpuidle-info.c:147
+#, fuzzy, c-format
+msgid "Usage: cpupower idleinfo [options]\n"
+msgstr "Uso: cpufreq-info [opções]\n"
+
+#: utils/cpuidle-info.c:149
+#, fuzzy, c-format
+msgid "  -s, --silent         Only show general C-state information\n"
+msgstr "  -e, --debug          Mostra informação de debug\n"
+
+#: utils/cpuidle-info.c:150
+#, fuzzy, c-format
+msgid ""
+"  -o, --proc           Prints out information like provided by the /proc/"
+"acpi/processor/*/power\n"
+"                       interface in older kernels\n"
+msgstr ""
+"  -o, --proc           Mostra informação do tipo provida pela interface /"
+"proc/cpufreq\n"
+"                       em kernels 2.4. e mais recentes 2.6\n"
+
+#: utils/cpuidle-info.c:209
+#, fuzzy, c-format
+msgid "You can't specify more than one output-specific argument\n"
+msgstr ""
+"Você não pode especificar mais do que um parâmetro --cpu e/ou\n"
+"mais do que um argumento de saída específico\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU    CPU number which information shall be determined "
+#~ "about\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU    número do CPU sobre o qual as inforções devem ser "
+#~ "determinadas\n"
+
+#~ msgid ""
+#~ "  -c CPU, --cpu CPU        number of CPU where cpufreq settings shall be "
+#~ "modified\n"
+#~ msgstr ""
+#~ "  -c CPU, --cpu CPU        número do CPU onde as configurações do cpufreq "
+#~ "vão ser modificadas\n"
diff --git a/tools/power/cpupower/utils/builtin.h b/tools/power/cpupower/utils/builtin.h
new file mode 100644 (file)
index 0000000..c870ffb
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef BUILTIN_H
+#define BUILTIN_H
+
+extern int cmd_set(int argc, const char **argv);
+extern int cmd_info(int argc, const char **argv);
+extern int cmd_freq_set(int argc, const char **argv);
+extern int cmd_freq_info(int argc, const char **argv);
+extern int cmd_idle_info(int argc, const char **argv);
+extern int cmd_monitor(int argc, const char **argv);
+
+extern void set_help(void);
+extern void info_help(void);
+extern void freq_set_help(void);
+extern void freq_info_help(void);
+extern void idle_info_help(void);
+extern void monitor_help(void);
+
+#endif
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
new file mode 100644 (file)
index 0000000..5a1d25f
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <getopt.h>
+
+#include "cpufreq.h"
+#include "helpers/helpers.h"
+#include "helpers/bitmask.h"
+
+#define LINE_LEN 10
+
+static unsigned int count_cpus(void)
+{
+       FILE *fp;
+       char value[LINE_LEN];
+       unsigned int ret = 0;
+       unsigned int cpunr = 0;
+
+       fp = fopen("/proc/stat", "r");
+       if (!fp) {
+               printf(_("Couldn't count the number of CPUs (%s: %s), assuming 1\n"), "/proc/stat", strerror(errno));
+               return 1;
+       }
+
+       while (!feof(fp)) {
+               if (!fgets(value, LINE_LEN, fp))
+                       continue;
+               value[LINE_LEN - 1] = '\0';
+               if (strlen(value) < (LINE_LEN - 2))
+                       continue;
+               if (strstr(value, "cpu "))
+                       continue;
+               if (sscanf(value, "cpu%d ", &cpunr) != 1)
+                       continue;
+               if (cpunr > ret)
+                       ret = cpunr;
+       }
+       fclose(fp);
+
+       /* cpu count starts from 0, on error return 1 (UP) */
+       return ret + 1;
+}
+
+
+static void proc_cpufreq_output(void)
+{
+       unsigned int cpu, nr_cpus;
+       struct cpufreq_policy *policy;
+       unsigned int min_pctg = 0;
+       unsigned int max_pctg = 0;
+       unsigned long min, max;
+
+       printf(_("          minimum CPU frequency  -  maximum CPU frequency  -  governor\n"));
+
+       nr_cpus = count_cpus();
+       for (cpu = 0; cpu < nr_cpus; cpu++) {
+               policy = cpufreq_get_policy(cpu);
+               if (!policy)
+                       continue;
+
+               if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
+                       max = 0;
+               } else {
+                       min_pctg = (policy->min * 100) / max;
+                       max_pctg = (policy->max * 100) / max;
+               }
+               printf("CPU%3d    %9lu kHz (%3d %%)  -  %9lu kHz (%3d %%)  -  %s\n",
+                       cpu , policy->min, max ? min_pctg : 0, policy->max,
+                       max ? max_pctg : 0, policy->governor);
+
+               cpufreq_put_policy(policy);
+       }
+}
+
+static void print_speed(unsigned long speed)
+{
+       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);
+
+       return;
+}
+
+static void print_duration(unsigned long duration)
+{
+       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);
+
+       return;
+}
+
+/* --boost / -b */
+
+static int get_boost_mode(unsigned int cpu)
+{
+       int support, active, b_states = 0, ret, pstate_no, i;
+       /* ToDo: Make this more global */
+       unsigned long pstates[MAX_HW_PSTATES] = {0,};
+
+       if (cpupower_cpu_info.vendor != X86_VENDOR_AMD &&
+           cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
+               return 0;
+
+       ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states);
+       if (ret) {
+               printf(_("Error while evaluating Boost Capabilities"
+                               " on CPU %d -- are you root?\n"), cpu);
+               return ret;
+       }
+       /* P state changes via MSR are identified via cpuid 80000007
+          on Intel and AMD, but we assume boost capable machines can do that
+          if (cpuid_eax(0x80000000) >= 0x80000007
+          && (cpuid_edx(0x80000007) & (1 << 7)))
+       */
+
+       printf(_("  boost state support:\n"));
+
+       printf(_("    Supported: %s\n"), support ? _("yes") : _("no"));
+       printf(_("    Active: %s\n"), active ? _("yes") : _("no"));
+
+       if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
+           cpupower_cpu_info.family >= 0x10) {
+               ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
+                                    pstates, &pstate_no);
+               if (ret)
+                       return ret;
+
+               printf(_("    Boost States: %d\n"), b_states);
+               printf(_("    Total States: %d\n"), pstate_no);
+               for (i = 0; i < pstate_no; i++) {
+                       if (i < b_states)
+                               printf(_("    Pstate-Pb%d: %luMHz (boost state)"
+                                        "\n"), i, pstates[i]);
+                       else
+                               printf(_("    Pstate-P%d:  %luMHz\n"),
+                                      i - b_states, pstates[i]);
+               }
+       } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) {
+               double bclk;
+               unsigned long long intel_turbo_ratio = 0;
+               unsigned int ratio;
+
+               /* Any way to autodetect this ? */
+               if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB)
+                       bclk = 100.00;
+               else
+                       bclk = 133.33;
+               intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu);
+               dprint ("    Ratio: 0x%llx - bclk: %f\n",
+                       intel_turbo_ratio, bclk);
+
+               ratio = (intel_turbo_ratio >> 24) & 0xFF;
+               if (ratio)
+                       printf(_("    %.0f MHz max turbo 4 active cores\n"),
+                              ratio * bclk);
+
+               ratio = (intel_turbo_ratio >> 16) & 0xFF;
+               if (ratio)
+                       printf(_("    %.0f MHz max turbo 3 active cores\n"),
+                              ratio * bclk);
+
+               ratio = (intel_turbo_ratio >> 8) & 0xFF;
+               if (ratio)
+                       printf(_("    %.0f MHz max turbo 2 active cores\n"),
+                              ratio * bclk);
+
+               ratio = (intel_turbo_ratio >> 0) & 0xFF;
+               if (ratio)
+                       printf(_("    %.0f MHz max turbo 1 active cores\n"),
+                              ratio * bclk);
+       }
+       return 0;
+}
+
+static void debug_output_one(unsigned int cpu)
+{
+       char *driver;
+       struct cpufreq_affected_cpus *cpus;
+       struct cpufreq_available_frequencies *freqs;
+       unsigned long min, max, freq_kernel, freq_hardware;
+       unsigned long total_trans, latency;
+       unsigned long long total_time;
+       struct cpufreq_policy *policy;
+       struct cpufreq_available_governors *governors;
+       struct cpufreq_stats *stats;
+
+       if (cpufreq_cpu_exists(cpu))
+               return;
+
+       freq_kernel = cpufreq_get_freq_kernel(cpu);
+       freq_hardware = cpufreq_get_freq_hardware(cpu);
+
+       driver = cpufreq_get_driver(cpu);
+       if (!driver) {
+               printf(_("  no or unknown cpufreq driver is active on this CPU\n"));
+       } else {
+               printf(_("  driver: %s\n"), driver);
+               cpufreq_put_driver(driver);
+       }
+
+       cpus = cpufreq_get_related_cpus(cpu);
+       if (cpus) {
+               printf(_("  CPUs which run at the same hardware frequency: "));
+               while (cpus->next) {
+                       printf("%d ", cpus->cpu);
+                       cpus = cpus->next;
+               }
+               printf("%d\n", cpus->cpu);
+               cpufreq_put_related_cpus(cpus);
+       }
+
+       cpus = cpufreq_get_affected_cpus(cpu);
+       if (cpus) {
+               printf(_("  CPUs which need to have their frequency coordinated by software: "));
+               while (cpus->next) {
+                       printf("%d ", cpus->cpu);
+                       cpus = cpus->next;
+               }
+               printf("%d\n", cpus->cpu);
+               cpufreq_put_affected_cpus(cpus);
+       }
+
+       latency = cpufreq_get_transition_latency(cpu);
+       if (latency) {
+               printf(_("  maximum transition latency: "));
+               print_duration(latency);
+               printf(".\n");
+       }
+
+       if (!(cpufreq_get_hardware_limits(cpu, &min, &max))) {
+               printf(_("  hardware limits: "));
+               print_speed(min);
+               printf(" - ");
+               print_speed(max);
+               printf("\n");
+       }
+
+       freqs = cpufreq_get_available_frequencies(cpu);
+       if (freqs) {
+               printf(_("  available frequency steps: "));
+               while (freqs->next) {
+                       print_speed(freqs->frequency);
+                       printf(", ");
+                       freqs = freqs->next;
+               }
+               print_speed(freqs->frequency);
+               printf("\n");
+               cpufreq_put_available_frequencies(freqs);
+       }
+
+       governors = cpufreq_get_available_governors(cpu);
+       if (governors) {
+               printf(_("  available cpufreq governors: "));
+               while (governors->next) {
+                       printf("%s, ", governors->governor);
+                       governors = governors->next;
+               }
+               printf("%s\n", governors->governor);
+               cpufreq_put_available_governors(governors);
+       }
+
+       policy = cpufreq_get_policy(cpu);
+       if (policy) {
+               printf(_("  current policy: frequency should be within "));
+               print_speed(policy->min);
+               printf(_(" and "));
+               print_speed(policy->max);
+
+               printf(".\n                  ");
+               printf(_("The governor \"%s\" may"
+                      " decide which speed to use\n                  within this range.\n"),
+                      policy->governor);
+               cpufreq_put_policy(policy);
+       }
+
+       if (freq_kernel || freq_hardware) {
+               printf(_("  current CPU frequency is "));
+               if (freq_hardware) {
+                       print_speed(freq_hardware);
+                       printf(_(" (asserted by call to hardware)"));
+               } else
+                       print_speed(freq_kernel);
+               printf(".\n");
+       }
+       stats = cpufreq_get_stats(cpu, &total_time);
+       if (stats) {
+               printf(_("  cpufreq stats: "));
+               while (stats) {
+                       print_speed(stats->frequency);
+                       printf(":%.2f%%", (100.0 * stats->time_in_state) / total_time);
+                       stats = stats->next;
+                       if (stats)
+                               printf(", ");
+               }
+               cpufreq_put_stats(stats);
+               total_trans = cpufreq_get_transitions(cpu);
+               if (total_trans)
+                       printf("  (%lu)\n", total_trans);
+               else
+                       printf("\n");
+       }
+       get_boost_mode(cpu);
+
+}
+
+/* --freq / -f */
+
+static int get_freq_kernel(unsigned int cpu, unsigned int human)
+{
+       unsigned long freq = cpufreq_get_freq_kernel(cpu);
+       if (!freq)
+               return -EINVAL;
+       if (human) {
+               print_speed(freq);
+               printf("\n");
+       } else
+               printf("%lu\n", freq);
+       return 0;
+}
+
+
+/* --hwfreq / -w */
+
+static int get_freq_hardware(unsigned int cpu, unsigned int human)
+{
+       unsigned long freq = cpufreq_get_freq_hardware(cpu);
+       if (!freq)
+               return -EINVAL;
+       if (human) {
+               print_speed(freq);
+               printf("\n");
+       } else
+               printf("%lu\n", freq);
+       return 0;
+}
+
+/* --hwlimits / -l */
+
+static int get_hardware_limits(unsigned int cpu)
+{
+       unsigned long min, max;
+       if (cpufreq_get_hardware_limits(cpu, &min, &max))
+               return -EINVAL;
+       printf("%lu %lu\n", min, max);
+       return 0;
+}
+
+/* --driver / -d */
+
+static int get_driver(unsigned int cpu)
+{
+       char *driver = cpufreq_get_driver(cpu);
+       if (!driver)
+               return -EINVAL;
+       printf("%s\n", driver);
+       cpufreq_put_driver(driver);
+       return 0;
+}
+
+/* --policy / -p */
+
+static int get_policy(unsigned int cpu)
+{
+       struct cpufreq_policy *policy = cpufreq_get_policy(cpu);
+       if (!policy)
+               return -EINVAL;
+       printf("%lu %lu %s\n", policy->min, policy->max, policy->governor);
+       cpufreq_put_policy(policy);
+       return 0;
+}
+
+/* --governors / -g */
+
+static int get_available_governors(unsigned int cpu)
+{
+       struct cpufreq_available_governors *governors =
+               cpufreq_get_available_governors(cpu);
+       if (!governors)
+               return -EINVAL;
+
+       while (governors->next) {
+               printf("%s ", governors->governor);
+               governors = governors->next;
+       }
+       printf("%s\n", governors->governor);
+       cpufreq_put_available_governors(governors);
+       return 0;
+}
+
+
+/* --affected-cpus  / -a */
+
+static int get_affected_cpus(unsigned int cpu)
+{
+       struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu);
+       if (!cpus)
+               return -EINVAL;
+
+       while (cpus->next) {
+               printf("%d ", cpus->cpu);
+               cpus = cpus->next;
+       }
+       printf("%d\n", cpus->cpu);
+       cpufreq_put_affected_cpus(cpus);
+       return 0;
+}
+
+/* --related-cpus  / -r */
+
+static int get_related_cpus(unsigned int cpu)
+{
+       struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu);
+       if (!cpus)
+               return -EINVAL;
+
+       while (cpus->next) {
+               printf("%d ", cpus->cpu);
+               cpus = cpus->next;
+       }
+       printf("%d\n", cpus->cpu);
+       cpufreq_put_related_cpus(cpus);
+       return 0;
+}
+
+/* --stats / -s */
+
+static int get_freq_stats(unsigned int cpu, unsigned int human)
+{
+       unsigned long total_trans = cpufreq_get_transitions(cpu);
+       unsigned long long total_time;
+       struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time);
+       while (stats) {
+               if (human) {
+                       print_speed(stats->frequency);
+                       printf(":%.2f%%",
+                               (100.0 * stats->time_in_state) / total_time);
+               } else
+                       printf("%lu:%llu",
+                               stats->frequency, stats->time_in_state);
+               stats = stats->next;
+               if (stats)
+                       printf(", ");
+       }
+       cpufreq_put_stats(stats);
+       if (total_trans)
+               printf("  (%lu)\n", total_trans);
+       return 0;
+}
+
+/* --latency / -y */
+
+static int get_latency(unsigned int cpu, unsigned int human)
+{
+       unsigned long latency = cpufreq_get_transition_latency(cpu);
+       if (!latency)
+               return -EINVAL;
+
+       if (human) {
+               print_duration(latency);
+               printf("\n");
+       } else
+               printf("%lu\n", latency);
+       return 0;
+}
+
+void freq_info_help(void)
+{
+       printf(_("Usage: cpupower freqinfo [options]\n"));
+       printf(_("Options:\n"));
+       printf(_("  -e, --debug          Prints out debug information [default]\n"));
+       printf(_("  -f, --freq           Get frequency the CPU currently runs at, according\n"
+              "                       to the cpufreq core *\n"));
+       printf(_("  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
+              "                       it from hardware (only available to root) *\n"));
+       printf(_("  -l, --hwlimits       Determine the minimum and maximum CPU frequency allowed *\n"));
+       printf(_("  -d, --driver         Determines the used cpufreq kernel driver *\n"));
+       printf(_("  -p, --policy         Gets the currently used cpufreq policy *\n"));
+       printf(_("  -g, --governors      Determines available cpufreq governors *\n"));
+       printf(_("  -r, --related-cpus   Determines which CPUs run at the same hardware frequency *\n"));
+       printf(_("  -a, --affected-cpus  Determines which CPUs need to have their frequency\n"
+                       "                       coordinated by software *\n"));
+       printf(_("  -s, --stats          Shows cpufreq statistics if available\n"));
+       printf(_("  -y, --latency        Determines the maximum latency on CPU frequency changes *\n"));
+       printf(_("  -b, --boost          Checks for turbo or boost modes  *\n"));
+       printf(_("  -o, --proc           Prints out information like provided by the /proc/cpufreq\n"
+              "                       interface in 2.4. and early 2.6. kernels\n"));
+       printf(_("  -m, --human          human-readable output for the -f, -w, -s and -y parameters\n"));
+       printf(_("  -h, --help           Prints out this screen\n"));
+
+       printf("\n");
+       printf(_("If no argument is given, full output about\n"
+              "cpufreq is printed which is useful e.g. for reporting bugs.\n\n"));
+       printf(_("By default info of CPU 0 is shown which can be overridden\n"
+                "with the cpupower --cpu main command option.\n"));
+}
+
+static struct option info_opts[] = {
+       { .name = "debug",      .has_arg = no_argument,         .flag = NULL,   .val = 'e'},
+       { .name = "boost",      .has_arg = no_argument,         .flag = NULL,   .val = 'b'},
+       { .name = "freq",       .has_arg = no_argument,         .flag = NULL,   .val = 'f'},
+       { .name = "hwfreq",     .has_arg = no_argument,         .flag = NULL,   .val = 'w'},
+       { .name = "hwlimits",   .has_arg = no_argument,         .flag = NULL,   .val = 'l'},
+       { .name = "driver",     .has_arg = no_argument,         .flag = NULL,   .val = 'd'},
+       { .name = "policy",     .has_arg = no_argument,         .flag = NULL,   .val = 'p'},
+       { .name = "governors",  .has_arg = no_argument,         .flag = NULL,   .val = 'g'},
+       { .name = "related-cpus", .has_arg = no_argument,       .flag = NULL,   .val = 'r'},
+       { .name = "affected-cpus",.has_arg = no_argument,       .flag = NULL,   .val = 'a'},
+       { .name = "stats",      .has_arg = no_argument,         .flag = NULL,   .val = 's'},
+       { .name = "latency",    .has_arg = no_argument,         .flag = NULL,   .val = 'y'},
+       { .name = "proc",       .has_arg = no_argument,         .flag = NULL,   .val = 'o'},
+       { .name = "human",      .has_arg = no_argument,         .flag = NULL,   .val = 'm'},
+       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
+       { },
+};
+
+int cmd_freq_info(int argc, char **argv)
+{
+       extern char *optarg;
+       extern int optind, opterr, optopt;
+       int ret = 0, cont = 1;
+       unsigned int cpu = 0;
+       unsigned int human = 0;
+       int output_param = 0;
+
+       do {
+               ret = getopt_long(argc, argv, "hoefwldpgrasmyb", info_opts, NULL);
+               switch (ret) {
+               case '?':
+                       output_param = '?';
+                       cont = 0;
+                       break;
+               case 'h':
+                       output_param = 'h';
+                       cont = 0;
+                       break;
+               case -1:
+                       cont = 0;
+                       break;
+               case 'b':
+               case 'o':
+               case 'a':
+               case 'r':
+               case 'g':
+               case 'p':
+               case 'd':
+               case 'l':
+               case 'w':
+               case 'f':
+               case 'e':
+               case 's':
+               case 'y':
+                       if (output_param) {
+                               output_param = -1;
+                               cont = 0;
+                               break;
+                       }
+                       output_param = ret;
+                       break;
+               case 'm':
+                       if (human) {
+                               output_param = -1;
+                               cont = 0;
+                               break;
+                       }
+                       human = 1;
+                       break;
+               default:
+                       fprintf(stderr, "invalid or unknown argument\n");
+                       return EXIT_FAILURE;
+               }
+       } while (cont);
+
+       switch (output_param) {
+       case 'o':
+               if (!bitmask_isallclear(cpus_chosen)) {
+                       printf(_("The argument passed to this tool can't be "
+                                "combined with passing a --cpu argument\n"));
+                       return -EINVAL;
+               }
+               break;
+       case 0:
+               output_param = 'e';
+       }
+
+       ret = 0;
+
+       /* Default is: show output of CPU 0 only */
+       if (bitmask_isallclear(cpus_chosen))
+               bitmask_setbit(cpus_chosen, 0);
+
+       switch (output_param) {
+       case -1:
+               printf(_("You can't specify more than one --cpu parameter and/or\n"
+                      "more than one output-specific argument\n"));
+               return -EINVAL;
+       case '?':
+               printf(_("invalid or unknown argument\n"));
+               freq_info_help();
+               return -EINVAL;
+       case 'h':
+               freq_info_help();
+               return EXIT_SUCCESS;
+       case 'o':
+               proc_cpufreq_output();
+               return EXIT_SUCCESS;
+       }
+
+       for (cpu = bitmask_first(cpus_chosen);
+            cpu <= bitmask_last(cpus_chosen); cpu++) {
+
+               if (!bitmask_isbitset(cpus_chosen, cpu))
+                       continue;
+               if (cpufreq_cpu_exists(cpu)) {
+                       printf(_("couldn't analyze CPU %d as it doesn't seem to be present\n"), cpu);
+                       continue;
+               }
+               printf(_("analyzing CPU %d:\n"), cpu);
+
+               switch (output_param) {
+               case 'b':
+                       get_boost_mode(cpu);
+                       break;
+               case 'e':
+                       debug_output_one(cpu);
+                       break;
+               case 'a':
+                       ret = get_affected_cpus(cpu);
+                       break;
+               case 'r':
+                       ret = get_related_cpus(cpu);
+                       break;
+               case 'g':
+                       ret = get_available_governors(cpu);
+                       break;
+               case 'p':
+                       ret = get_policy(cpu);
+                       break;
+               case 'd':
+                       ret = get_driver(cpu);
+                       break;
+               case 'l':
+                       ret = get_hardware_limits(cpu);
+                       break;
+               case 'w':
+                       ret = get_freq_hardware(cpu, human);
+                       break;
+               case 'f':
+                       ret = get_freq_kernel(cpu, human);
+                       break;
+               case 's':
+                       ret = get_freq_stats(cpu, human);
+                       break;
+               case 'y':
+                       ret = get_latency(cpu, human);
+                       break;
+               }
+               if (ret)
+                       return ret;
+       }
+       return ret;
+}
diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c
new file mode 100644 (file)
index 0000000..5f78362
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <getopt.h>
+
+#include "cpufreq.h"
+#include "helpers/helpers.h"
+
+#define NORM_FREQ_LEN 32
+
+void freq_set_help(void)
+{
+       printf(_("Usage: cpupower frequency-set [options]\n"));
+       printf(_("Options:\n"));
+       printf(_("  -d FREQ, --min FREQ      new minimum CPU frequency the governor may select\n"));
+       printf(_("  -u FREQ, --max FREQ      new maximum CPU frequency the governor may select\n"));
+       printf(_("  -g GOV, --governor GOV   new cpufreq governor\n"));
+       printf(_("  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
+              "                           governor to be available and loaded\n"));
+       printf(_("  -r, --related            Switches all hardware-related CPUs\n"));
+       printf(_("  -h, --help               Prints out this screen\n"));
+       printf("\n");
+       printf(_("Notes:\n"
+              "1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"));
+       printf(_("2. The -f FREQ, --freq FREQ parameter cannot be combined with any other parameter\n"
+              "   except the -c CPU, --cpu CPU parameter\n"
+              "3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
+              "   by postfixing the value with the wanted unit name, without any space\n"
+              "   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"));
+
+}
+
+static struct option set_opts[] = {
+       { .name = "min",        .has_arg = required_argument,   .flag = NULL,   .val = 'd'},
+       { .name = "max",        .has_arg = required_argument,   .flag = NULL,   .val = 'u'},
+       { .name = "governor",   .has_arg = required_argument,   .flag = NULL,   .val = 'g'},
+       { .name = "freq",       .has_arg = required_argument,   .flag = NULL,   .val = 'f'},
+       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
+       { .name = "related",    .has_arg = no_argument,         .flag = NULL,   .val='r'},
+       { },
+};
+
+static void print_error(void)
+{
+       printf(_("Error setting new values. Common errors:\n"
+                       "- Do you have proper administration rights? (super-user?)\n"
+                       "- Is the governor you requested available and modprobed?\n"
+                       "- Trying to set an invalid policy?\n"
+                       "- Trying to set a specific frequency, but userspace governor is not available,\n"
+                       "   for example because of hardware which cannot be set to a specific frequency\n"
+                       "   or because the userspace governor isn't loaded?\n"));
+};
+
+struct freq_units {
+       char            *str_unit;
+       int             power_of_ten;
+};
+
+const struct freq_units def_units[] = {
+       {"hz", -3},
+       {"khz", 0}, /* default */
+       {"mhz", 3},
+       {"ghz", 6},
+       {"thz", 9},
+       {NULL, 0}
+};
+
+static void print_unknown_arg(void)
+{
+       printf(_("invalid or unknown argument\n"));
+       freq_set_help();
+}
+
+static unsigned long string_to_frequency(const char *str)
+{
+       char normalized[NORM_FREQ_LEN];
+       const struct freq_units *unit;
+       const char *scan;
+       char *end;
+       unsigned long freq;
+       int power = 0, match_count = 0, i, cp, pad;
+
+       while (*str == '0')
+               str++;
+
+       for (scan = str; isdigit(*scan) || *scan == '.'; scan++) {
+               if (*scan == '.' && match_count == 0)
+                       match_count = 1;
+               else if (*scan == '.' && match_count == 1)
+                       return 0;
+       }
+
+       if (*scan) {
+               match_count = 0;
+               for (unit = def_units; unit->str_unit; unit++) {
+                       for (i = 0;
+                            scan[i] && tolower(scan[i]) == unit->str_unit[i];
+                            ++i)
+                               continue;
+                       if (scan[i])
+                               continue;
+                       match_count++;
+                       power = unit->power_of_ten;
+               }
+               if (match_count != 1)
+                       return 0;
+       }
+
+       /* count the number of digits to be copied */
+       for (cp = 0; isdigit(str[cp]); cp++)
+               continue;
+
+       if (str[cp] == '.') {
+               while (power > -1 && isdigit(str[cp+1]))
+                       cp++, power--;
+       }
+       if (power >= -1)        /* not enough => pad */
+               pad = power + 1;
+       else                    /* to much => strip */
+               pad = 0, cp += power + 1;
+       /* check bounds */
+       if (cp <= 0 || cp + pad > NORM_FREQ_LEN - 1)
+               return 0;
+
+       /* copy digits */
+       for (i = 0; i < cp; i++, str++) {
+               if (*str == '.')
+                       str++;
+               normalized[i] = *str;
+       }
+       /* and pad */
+       for (; i < cp + pad; i++)
+               normalized[i] = '0';
+
+       /* round up, down ? */
+       match_count = (normalized[i-1] >= '5');
+       /* and drop the decimal part */
+       normalized[i-1] = 0; /* cp > 0 && pad >= 0 ==> i > 0 */
+
+       /* final conversion (and applying rounding) */
+       errno = 0;
+       freq = strtoul(normalized, &end, 10);
+       if (errno)
+               return 0;
+       else {
+               if (match_count && freq != ULONG_MAX)
+                       freq++;
+               return freq;
+       }
+}
+
+static int do_new_policy(unsigned int cpu, struct cpufreq_policy *new_pol)
+{
+       struct cpufreq_policy *cur_pol = cpufreq_get_policy(cpu);
+       int ret;
+
+       if (!cur_pol) {
+               printf(_("wrong, unknown or unhandled CPU?\n"));
+               return -EINVAL;
+       }
+
+       if (!new_pol->min)
+               new_pol->min = cur_pol->min;
+
+       if (!new_pol->max)
+               new_pol->max = cur_pol->max;
+
+       if (!new_pol->governor)
+               new_pol->governor = cur_pol->governor;
+
+       ret = cpufreq_set_policy(cpu, new_pol);
+
+       cpufreq_put_policy(cur_pol);
+
+       return ret;
+}
+
+
+static int do_one_cpu(unsigned int cpu, struct cpufreq_policy *new_pol,
+               unsigned long freq, unsigned int pc)
+{
+       switch (pc) {
+       case 0:
+               return cpufreq_set_frequency(cpu, freq);
+
+       case 1:
+               /* if only one value of a policy is to be changed, we can
+                * use a "fast path".
+                */
+               if (new_pol->min)
+                       return cpufreq_modify_policy_min(cpu, new_pol->min);
+               else if (new_pol->max)
+                       return cpufreq_modify_policy_max(cpu, new_pol->max);
+               else if (new_pol->governor)
+                       return cpufreq_modify_policy_governor(cpu,
+                                                       new_pol->governor);
+
+       default:
+               /* slow path */
+               return do_new_policy(cpu, new_pol);
+       }
+}
+
+int cmd_freq_set(int argc, char **argv)
+{
+       extern char *optarg;
+       extern int optind, opterr, optopt;
+       int ret = 0, cont = 1;
+       int double_parm = 0, related = 0, policychange = 0;
+       unsigned long freq = 0;
+       char gov[20];
+       unsigned int cpu;
+
+       struct cpufreq_policy new_pol = {
+               .min = 0,
+               .max = 0,
+               .governor = NULL,
+       };
+
+       /* parameter parsing */
+       do {
+               ret = getopt_long(argc, argv, "d:u:g:f:hr", set_opts, NULL);
+               switch (ret) {
+               case '?':
+                       print_unknown_arg();
+                       return -EINVAL;
+               case 'h':
+                       freq_set_help();
+                       return 0;
+               case -1:
+                       cont = 0;
+                       break;
+               case 'r':
+                       if (related)
+                               double_parm++;
+                       related++;
+                       break;
+               case 'd':
+                       if (new_pol.min)
+                               double_parm++;
+                       policychange++;
+                       new_pol.min = string_to_frequency(optarg);
+                       if (new_pol.min == 0) {
+                               print_unknown_arg();
+                               return -EINVAL;
+                       }
+                       break;
+               case 'u':
+                       if (new_pol.max)
+                               double_parm++;
+                       policychange++;
+                       new_pol.max = string_to_frequency(optarg);
+                       if (new_pol.max == 0) {
+                               print_unknown_arg();
+                               return -EINVAL;
+                       }
+                       break;
+               case 'f':
+                       if (freq)
+                               double_parm++;
+                       freq = string_to_frequency(optarg);
+                       if (freq == 0) {
+                               print_unknown_arg();
+                               return -EINVAL;
+                       }
+                       break;
+               case 'g':
+                       if (new_pol.governor)
+                               double_parm++;
+                       policychange++;
+                       if ((strlen(optarg) < 3) || (strlen(optarg) > 18)) {
+                               print_unknown_arg();
+                               return -EINVAL;
+                       }
+                       if ((sscanf(optarg, "%s", gov)) != 1) {
+                               print_unknown_arg();
+                               return -EINVAL;
+                       }
+                       new_pol.governor = gov;
+                       break;
+               }
+       } while (cont);
+
+       /* parameter checking */
+       if (double_parm) {
+               printf("the same parameter was passed more than once\n");
+               return -EINVAL;
+       }
+
+       if (freq && policychange) {
+               printf(_("the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n"
+                               "-g/--governor parameters\n"));
+               return -EINVAL;
+       }
+
+       if (!freq && !policychange) {
+               printf(_("At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
+                               "-g/--governor must be passed\n"));
+               return -EINVAL;
+       }
+
+       /* Default is: set all CPUs */
+       if (bitmask_isallclear(cpus_chosen))
+               bitmask_setall(cpus_chosen);
+
+       /* Also set frequency settings for related CPUs if -r is passed */
+       if (related) {
+               for (cpu = bitmask_first(cpus_chosen);
+                    cpu <= bitmask_last(cpus_chosen); cpu++) {
+                       struct cpufreq_affected_cpus *cpus;
+
+                       if (!bitmask_isbitset(cpus_chosen, cpu) ||
+                           cpufreq_cpu_exists(cpu))
+                               continue;
+
+                       cpus = cpufreq_get_related_cpus(cpu);
+                       if (!cpus)
+                               break;
+                       while (cpus->next) {
+                               bitmask_setbit(cpus_chosen, cpus->cpu);
+                               cpus = cpus->next;
+                       }
+                       cpufreq_put_related_cpus(cpus);
+               }
+       }
+
+
+       /* loop over CPUs */
+       for (cpu = bitmask_first(cpus_chosen);
+            cpu <= bitmask_last(cpus_chosen); cpu++) {
+
+               if (!bitmask_isbitset(cpus_chosen, cpu) ||
+                   cpufreq_cpu_exists(cpu))
+                       continue;
+
+               printf(_("Setting cpu: %d\n"), cpu);
+               ret = do_one_cpu(cpu, &new_pol, freq, policychange);
+               if (ret)
+                       break;
+       }
+
+       if (ret)
+               print_error();
+
+       return ret;
+}
diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c
new file mode 100644 (file)
index 0000000..70da357
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
+ *  (C) 2010       Thomas Renninger <trenn@suse.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <cpufreq.h>
+
+#include "helpers/helpers.h"
+#include "helpers/sysfs.h"
+#include "helpers/bitmask.h"
+
+#define LINE_LEN 10
+
+static void cpuidle_cpu_output(unsigned int cpu, int verbose)
+{
+       int idlestates, idlestate;
+       char *tmp;
+
+       printf(_ ("Analyzing CPU %d:\n"), cpu);
+
+       idlestates = sysfs_get_idlestate_count(cpu);
+       if (idlestates == 0) {
+               printf(_("CPU %u: No idle states\n"), cpu);
+               return;
+       } else if (idlestates <= 0) {
+               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++) {
+               tmp = sysfs_get_idlestate_name(cpu, idlestate);
+               if (!tmp)
+                       continue;
+               printf(" %s", tmp);
+               free(tmp);
+       }
+       printf("\n");
+
+       if (!verbose)
+               return;
+
+       for (idlestate = 1; idlestate < idlestates; idlestate++) {
+               tmp = sysfs_get_idlestate_name(cpu, idlestate);
+               if (!tmp)
+                       continue;
+               printf("%s:\n", tmp);
+               free(tmp);
+
+               tmp = sysfs_get_idlestate_desc(cpu, idlestate);
+               if (!tmp)
+                       continue;
+               printf(_("Flags/Description: %s\n"), tmp);
+               free(tmp);
+
+               printf(_("Latency: %lu\n"),
+                      sysfs_get_idlestate_latency(cpu, idlestate));
+               printf(_("Usage: %lu\n"),
+                      sysfs_get_idlestate_usage(cpu, idlestate));
+               printf(_("Duration: %llu\n"),
+                      sysfs_get_idlestate_time(cpu, idlestate));
+       }
+       printf("\n");
+}
+
+static void cpuidle_general_output(void)
+{
+       char *tmp;
+
+       tmp = sysfs_get_cpuidle_driver();
+       if (!tmp) {
+               printf(_("Could not determine cpuidle driver\n"));
+               return;
+       }
+
+       printf(_("CPUidle driver: %s\n"), tmp);
+       free(tmp);
+
+       tmp = sysfs_get_cpuidle_governor();
+       if (!tmp) {
+               printf(_("Could not determine cpuidle governor\n"));
+               return;
+       }
+
+       printf(_("CPUidle governor: %s\n"), tmp);
+       free(tmp);
+}
+
+static void proc_cpuidle_cpu_output(unsigned int cpu)
+{
+       long max_allowed_cstate = 2000000000;
+       int cstates, cstate;
+
+       cstates = sysfs_get_idlestate_count(cpu);
+       if (cstates == 0) {
+               /*
+                * Go on and print same useless info as you'd see with
+                * cat /proc/acpi/processor/../power
+                *      printf(_("CPU %u: No C-states available\n"), cpu);
+                *      return;
+                */
+       } else if (cstates <= 0) {
+               printf(_("CPU %u: Can't read C-state info\n"), cpu);
+               return;
+       }
+       /* printf("Cstates: %d\n", cstates); */
+
+       printf(_("active state:            C0\n"));
+       printf(_("max_cstate:              C%u\n"), cstates-1);
+       printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);
+       printf(_("states:\t\n"));
+       for (cstate = 1; cstate < cstates; cstate++) {
+               printf(_("    C%d:                  "
+                        "type[C%d] "), cstate, cstate);
+               printf(_("promotion[--] demotion[--] "));
+               printf(_("latency[%03lu] "),
+                      sysfs_get_idlestate_latency(cpu, cstate));
+               printf(_("usage[%08lu] "),
+                      sysfs_get_idlestate_usage(cpu, cstate));
+               printf(_("duration[%020Lu] \n"),
+                      sysfs_get_idlestate_time(cpu, cstate));
+       }
+}
+
+/* --freq / -f */
+
+void idle_info_help(void)
+{
+       printf(_ ("Usage: cpupower idleinfo [options]\n"));
+       printf(_ ("Options:\n"));
+       printf(_ ("  -s, --silent         Only show general C-state information\n"));
+       printf(_ ("  -o, --proc           Prints out information like provided by the /proc/acpi/processor/*/power\n"
+              "                       interface in older kernels\n"));
+       printf(_ ("  -h, --help           Prints out this screen\n"));
+
+       printf("\n");
+}
+
+static struct option info_opts[] = {
+       { .name = "silent",     .has_arg = no_argument, .flag = NULL,   .val = 's'},
+       { .name = "proc",       .has_arg = no_argument, .flag = NULL,   .val = 'o'},
+       { .name = "help",       .has_arg = no_argument, .flag = NULL,   .val = 'h'},
+       { },
+};
+
+static inline void cpuidle_exit(int fail)
+{
+       idle_info_help();
+       exit(EXIT_FAILURE);
+}
+
+int cmd_idle_info(int argc, char **argv)
+{
+       extern char *optarg;
+       extern int optind, opterr, optopt;
+       int ret = 0, cont = 1, output_param = 0, verbose = 1;
+       unsigned int cpu = 0;
+
+       do {
+               ret = getopt_long(argc, argv, "hos", info_opts, NULL);
+               if (ret == -1)
+                       break;
+               switch (ret) {
+               case '?':
+                       output_param = '?';
+                       cont = 0;
+                       break;
+               case 'h':
+                       output_param = 'h';
+                       cont = 0;
+                       break;
+               case 's':
+                       verbose = 0;
+                       break;
+               case -1:
+                       cont = 0;
+                       break;
+               case 'o':
+                       if (output_param) {
+                               output_param = -1;
+                               cont = 0;
+                               break;
+                       }
+                       output_param = ret;
+                       break;
+               }
+       } while (cont);
+
+       switch (output_param) {
+       case -1:
+               printf(_("You can't specify more than one "
+                        "output-specific argument\n"));
+               cpuidle_exit(EXIT_FAILURE);
+       case '?':
+               printf(_("invalid or unknown argument\n"));
+               cpuidle_exit(EXIT_FAILURE);
+       case 'h':
+               cpuidle_exit(EXIT_SUCCESS);
+       }
+
+       /* Default is: show output of CPU 0 only */
+       if (bitmask_isallclear(cpus_chosen))
+               bitmask_setbit(cpus_chosen, 0);
+
+       if (output_param == 0)
+               cpuidle_general_output();
+
+       for (cpu = bitmask_first(cpus_chosen);
+            cpu <= bitmask_last(cpus_chosen); cpu++) {
+
+               if (!bitmask_isbitset(cpus_chosen, cpu) ||
+                   cpufreq_cpu_exists(cpu))
+                       continue;
+
+               switch (output_param) {
+
+               case 'o':
+                       proc_cpuidle_cpu_output(cpu);
+                       break;
+               case 0:
+                       printf("\n");
+                       cpuidle_cpu_output(cpu, verbose);
+                       break;
+               }
+       }
+       return EXIT_SUCCESS;
+}
diff --git a/tools/power/cpupower/utils/cpupower-info.c b/tools/power/cpupower/utils/cpupower-info.c
new file mode 100644 (file)
index 0000000..85253cb
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cpufreq.h>
+#include "helpers/helpers.h"
+#include "helpers/sysfs.h"
+
+void info_help(void)
+{
+       printf(_("Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"));
+       printf(_("Options:\n"));
+       printf(_("  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
+              "                           Intel models [0-15], see manpage for details\n"));
+       printf(_("  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"));
+       printf(_("  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"));
+       printf(_("  -h, --help               Prints out this screen\n"));
+       printf(_("\nPassing no option will show all info, by default only on core 0\n"));
+       printf("\n");
+}
+
+static struct option set_opts[] = {
+       { .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'},
+       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
+       { },
+};
+
+static void print_wrong_arg_exit(void)
+{
+       printf(_("invalid or unknown argument\n"));
+       info_help();
+       exit(EXIT_FAILURE);
+}
+
+int cmd_info(int argc, char **argv)
+{
+       extern char *optarg;
+       extern int optind, opterr, optopt;
+       unsigned int cpu;
+
+       union {
+               struct {
+                       int sched_mc:1;
+                       int sched_smt:1;
+                       int perf_bias:1;
+               };
+               int params;
+       } params = {};
+       int ret = 0;
+
+       setlocale(LC_ALL, "");
+       textdomain(PACKAGE);
+
+       /* parameter parsing */
+       while ((ret = getopt_long(argc, argv, "msbh", set_opts, NULL)) != -1) {
+               switch (ret) {
+               case 'h':
+                       info_help();
+                       return 0;
+               case 'b':
+                       if (params.perf_bias)
+                               print_wrong_arg_exit();
+                       params.perf_bias = 1;
+                       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:
+                       print_wrong_arg_exit();
+               }
+       };
+
+       if (!params.params)
+               params.params = 0x7;
+
+       /* Default is: show output of CPU 0 only */
+       if (bitmask_isallclear(cpus_chosen))
+               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 */
+       if (!params.perf_bias)
+               return ret;
+
+       if (params.perf_bias) {
+               if (!run_as_root) {
+                       params.perf_bias = 0;
+                       printf(_("Intel's performance bias setting needs root privileges\n"));
+               } else if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) {
+                       printf(_("System does not support Intel's performance"
+                                " bias setting\n"));
+                       params.perf_bias = 0;
+               }
+       }
+
+       /* loop over CPUs */
+       for (cpu = bitmask_first(cpus_chosen);
+            cpu <= bitmask_last(cpus_chosen); cpu++) {
+
+               if (!bitmask_isbitset(cpus_chosen, cpu) ||
+                   cpufreq_cpu_exists(cpu))
+                       continue;
+
+               printf(_("analyzing CPU %d:\n"), cpu);
+
+               if (params.perf_bias) {
+                       ret = msr_intel_get_perf_bias(cpu);
+                       if (ret < 0) {
+                               printf(_("Could not read perf-bias value\n"));
+                               break;
+                       } else
+                               printf(_("perf-bias: %d\n"), ret);
+               }
+       }
+       return ret;
+}
diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c
new file mode 100644 (file)
index 0000000..bc1b391
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cpufreq.h>
+#include "helpers/helpers.h"
+#include "helpers/sysfs.h"
+#include "helpers/bitmask.h"
+
+void set_help(void)
+{
+       printf(_("Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"));
+       printf(_("Options:\n"));
+       printf(_("  -b, --perf-bias [VAL]    Sets CPU's power vs performance policy on some\n"
+              "                           Intel models [0-15], see manpage for details\n"));
+       printf(_("  -m, --sched-mc  [VAL]    Sets the kernel's multi core scheduler policy.\n"));
+       printf(_("  -s, --sched-smt [VAL]    Sets the kernel's thread sibling scheduler policy.\n"));
+       printf(_("  -h, --help               Prints out this screen\n"));
+       printf("\n");
+}
+
+static struct option set_opts[] = {
+       { .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'},
+       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
+       { },
+};
+
+static void print_wrong_arg_exit(void)
+{
+       printf(_("invalid or unknown argument\n"));
+       set_help();
+       exit(EXIT_FAILURE);
+}
+
+int cmd_set(int argc, char **argv)
+{
+       extern char *optarg;
+       extern int optind, opterr, optopt;
+       unsigned int cpu;
+
+       union {
+               struct {
+                       int sched_mc:1;
+                       int sched_smt:1;
+                       int perf_bias:1;
+               };
+               int params;
+       } params;
+       int sched_mc = 0, sched_smt = 0, perf_bias = 0;
+       int ret = 0;
+
+       setlocale(LC_ALL, "");
+       textdomain(PACKAGE);
+
+       params.params = 0;
+       /* parameter parsing */
+       while ((ret = getopt_long(argc, argv, "m:s:b:h",
+                                               set_opts, NULL)) != -1) {
+               switch (ret) {
+               case 'h':
+                       set_help();
+                       return 0;
+               case 'b':
+                       if (params.perf_bias)
+                               print_wrong_arg_exit();
+                       perf_bias = atoi(optarg);
+                       if (perf_bias < 0 || perf_bias > 15) {
+                               printf(_("--perf-bias param out "
+                                        "of range [0-%d]\n"), 15);
+                               print_wrong_arg_exit();
+                       }
+                       params.perf_bias = 1;
+                       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:
+                       print_wrong_arg_exit();
+               }
+       };
+
+       if (!params.params) {
+               set_help();
+               return -EINVAL;
+       }
+
+       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 */
+       if (bitmask_isallclear(cpus_chosen))
+               bitmask_setall(cpus_chosen);
+
+       /* loop over CPUs */
+       for (cpu = bitmask_first(cpus_chosen);
+            cpu <= bitmask_last(cpus_chosen); cpu++) {
+
+               if (!bitmask_isbitset(cpus_chosen, cpu) ||
+                   cpufreq_cpu_exists(cpu))
+                       continue;
+
+               if (params.perf_bias) {
+                       ret = msr_intel_set_perf_bias(cpu, perf_bias);
+                       if (ret) {
+                               fprintf(stderr, _("Error setting perf-bias "
+                                                 "value on CPU %d\n"), cpu);
+                               break;
+                       }
+               }
+       }
+       return ret;
+}
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c
new file mode 100644 (file)
index 0000000..5844ae0
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  Ideas taken over from the perf userspace tool (included in the Linus
+ *  kernel git repo): subcommand builtins and param parsing.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "builtin.h"
+#include "helpers/helpers.h"
+#include "helpers/bitmask.h"
+
+struct cmd_struct {
+       const char *cmd;
+       int (*main)(int, const char **);
+       void (*usage)(void);
+       int needs_root;
+};
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+int cmd_help(int argc, const char **argv);
+
+/* Global cpu_info object available for all binaries
+ * Info only retrieved from CPU 0
+ *
+ * Values will be zero/unknown on non X86 archs
+ */
+struct cpupower_cpu_info cpupower_cpu_info;
+int run_as_root;
+/* Affected cpus chosen by -c/--cpu param */
+struct bitmask *cpus_chosen;
+
+#ifdef DEBUG
+int be_verbose;
+#endif
+
+static void print_help(void);
+
+static struct cmd_struct commands[] = {
+       { "frequency-info",     cmd_freq_info,  freq_info_help, 0       },
+       { "frequency-set",      cmd_freq_set,   freq_set_help,  1       },
+       { "idle-info",          cmd_idle_info,  idle_info_help, 0       },
+       { "set",                cmd_set,        set_help,       1       },
+       { "info",               cmd_info,       info_help,      0       },
+       { "monitor",            cmd_monitor,    monitor_help,   0       },
+       { "help",               cmd_help,       print_help,     0       },
+       /*      { "bench",      cmd_bench,      NULL,           1       }, */
+};
+
+int cmd_help(int argc, const char **argv)
+{
+       unsigned int i;
+
+       if (argc > 1) {
+               for (i = 0; i < ARRAY_SIZE(commands); i++) {
+                       struct cmd_struct *p = commands + i;
+                       if (strcmp(p->cmd, argv[1]))
+                               continue;
+                       if (p->usage) {
+                               p->usage();
+                               return EXIT_SUCCESS;
+                       }
+               }
+       }
+       print_help();
+       if (argc == 1)
+               return EXIT_SUCCESS; /* cpupower help */
+       return EXIT_FAILURE;
+}
+
+static void print_help(void)
+{
+       unsigned int i;
+
+#ifdef DEBUG
+       printf(_("cpupower [ -d ][ -c cpulist ] subcommand [ARGS]\n"));
+       printf(_("  -d, --debug      May increase output (stderr) on some subcommands\n"));
+#else
+       printf(_("cpupower [ -c cpulist ] subcommand [ARGS]\n"));
+#endif
+       printf(_("cpupower --version\n"));
+       printf(_("Supported subcommands are:\n"));
+       for (i = 0; i < ARRAY_SIZE(commands); i++)
+               printf("\t%s\n", commands[i].cmd);
+       printf(_("\nSome subcommands can make use of the -c cpulist option.\n"));
+       printf(_("Look at the general cpupower manpage how to use it\n"));
+       printf(_("and read up the subcommand's manpage whether it is supported.\n"));
+       printf(_("\nUse cpupower help subcommand for getting help for above subcommands.\n"));
+}
+
+static void print_version(void)
+{
+       printf(PACKAGE " " VERSION "\n");
+       printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT);
+}
+
+static void handle_options(int *argc, const char ***argv)
+{
+       int ret, x, new_argc = 0;
+
+       if (*argc < 1)
+               return;
+
+       for (x = 0;  x < *argc && ((*argv)[x])[0] == '-'; x++) {
+               const char *param = (*argv)[x];
+               if (!strcmp(param, "-h") || !strcmp(param, "--help")) {
+                       print_help();
+                       exit(EXIT_SUCCESS);
+               } else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")) {
+                       if (*argc < 2) {
+                               print_help();
+                               exit(EXIT_FAILURE);
+                       }
+                       if (!strcmp((*argv)[x+1], "all"))
+                               bitmask_setall(cpus_chosen);
+                       else {
+                               ret = bitmask_parselist(
+                                               (*argv)[x+1], cpus_chosen);
+                               if (ret < 0) {
+                                       fprintf(stderr, _("Error parsing cpu "
+                                                         "list\n"));
+                                       exit(EXIT_FAILURE);
+                               }
+                       }
+                       x += 1;
+                       /* Cut out param: cpupower -c 1 info -> cpupower info */
+                       new_argc += 2;
+                       continue;
+               } else if (!strcmp(param, "-v") ||
+                       !strcmp(param, "--version")) {
+                       print_version();
+                       exit(EXIT_SUCCESS);
+#ifdef DEBUG
+               } else if (!strcmp(param, "-d") || !strcmp(param, "--debug")) {
+                       be_verbose = 1;
+                       new_argc++;
+                       continue;
+#endif
+               } else {
+                       fprintf(stderr, "Unknown option: %s\n", param);
+                       print_help();
+                       exit(EXIT_FAILURE);
+               }
+       }
+       *argc -= new_argc;
+       *argv += new_argc;
+}
+
+int main(int argc, const char *argv[])
+{
+       const char *cmd;
+       unsigned int i, ret;
+
+       cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
+
+       argc--;
+       argv += 1;
+
+       handle_options(&argc, &argv);
+
+       cmd = argv[0];
+
+       if (argc < 1) {
+               print_help();
+               return EXIT_FAILURE;
+       }
+
+       setlocale(LC_ALL, "");
+       textdomain(PACKAGE);
+
+       /* Turn "perf cmd --help" into "perf help cmd" */
+       if (argc > 1 && !strcmp(argv[1], "--help")) {
+               argv[1] = argv[0];
+               argv[0] = cmd = "help";
+       }
+
+       get_cpu_info(0, &cpupower_cpu_info);
+       run_as_root = !getuid();
+
+       for (i = 0; i < ARRAY_SIZE(commands); i++) {
+               struct cmd_struct *p = commands + i;
+               if (strcmp(p->cmd, cmd))
+                       continue;
+               if (!run_as_root && p->needs_root) {
+                       fprintf(stderr, _("Subcommand %s needs root "
+                                         "privileges\n"), cmd);
+                       return EXIT_FAILURE;
+               }
+               ret = p->main(argc, argv);
+               if (cpus_chosen)
+                       bitmask_free(cpus_chosen);
+               return ret;
+       }
+       print_help();
+       return EXIT_FAILURE;
+}
diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c
new file mode 100644 (file)
index 0000000..87d5605
--- /dev/null
@@ -0,0 +1,137 @@
+#if defined(__i386__) || defined(__x86_64__)
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include <pci/pci.h>
+
+#include "helpers/helpers.h"
+
+#define MSR_AMD_PSTATE_STATUS  0xc0010063
+#define MSR_AMD_PSTATE         0xc0010064
+#define MSR_AMD_PSTATE_LIMIT   0xc0010061
+
+union msr_pstate {
+       struct {
+               unsigned fid:6;
+               unsigned did:3;
+               unsigned vid:7;
+               unsigned res1:6;
+               unsigned nbdid:1;
+               unsigned res2:2;
+               unsigned nbvid:7;
+               unsigned iddval:8;
+               unsigned idddiv:2;
+               unsigned res3:21;
+               unsigned en:1;
+       } bits;
+       unsigned long long val;
+};
+
+static int get_did(int family, union msr_pstate pstate)
+{
+       int t;
+
+       if (family == 0x12)
+               t = pstate.val & 0xf;
+       else
+               t = pstate.bits.did;
+
+       return t;
+}
+
+static int get_cof(int family, union msr_pstate pstate)
+{
+       int t;
+       int fid, did;
+
+       did = get_did(family, pstate);
+
+       t = 0x10;
+       fid = pstate.bits.fid;
+       if (family == 0x11)
+               t = 0x8;
+
+       return (100 * (fid + t)) >> did;
+}
+
+/* Needs:
+ * cpu          -> the cpu that gets evaluated
+ * cpu_family   -> The cpu's family (0x10, 0x12,...)
+ * boots_states -> how much boost states the machines support
+ *
+ * Fills up:
+ * pstates -> a pointer to an array of size MAX_HW_PSTATES
+ *            must be initialized with zeros.
+ *            All available  HW pstates (including boost states)
+ * no      -> amount of pstates above array got filled up with
+ *
+ * returns zero on success, -1 on failure
+ */
+int decode_pstates(unsigned int cpu, unsigned int cpu_family,
+                  int boost_states, unsigned long *pstates, int *no)
+{
+       int i, psmax, pscur;
+       union msr_pstate pstate;
+       unsigned long long val;
+
+       /* Only read out frequencies from HW when CPU might be boostable
+          to keep the code as short and clean as possible.
+          Otherwise frequencies are exported via ACPI tables.
+       */
+       if (cpu_family < 0x10 || cpu_family == 0x14)
+               return -1;
+
+       if (read_msr(cpu, MSR_AMD_PSTATE_LIMIT, &val))
+               return -1;
+
+       psmax = (val >> 4) & 0x7;
+
+       if (read_msr(cpu, MSR_AMD_PSTATE_STATUS, &val))
+               return -1;
+
+       pscur = val & 0x7;
+
+       pscur += boost_states;
+       psmax += boost_states;
+       for (i = 0; i <= psmax; i++) {
+               if (i >= MAX_HW_PSTATES) {
+                       fprintf(stderr, "HW pstates [%d] exceeding max [%d]\n",
+                               psmax, MAX_HW_PSTATES);
+                       return -1;
+               }
+               if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
+                       return -1;
+               pstates[i] = get_cof(cpu_family, pstate);
+       }
+       *no = i;
+       return 0;
+}
+
+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);
+
+       if (device == NULL)
+               return -ENODEV;
+
+       val = pci_read_byte(device, 0x15c);
+       if (val & 3)
+               *active = 1;
+       else
+               *active = 0;
+       *states = (val >> 2) & 7;
+
+       pci_cleanup(pci_acc);
+       return 0;
+}
+#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/helpers/bitmask.c b/tools/power/cpupower/utils/helpers/bitmask.c
new file mode 100644 (file)
index 0000000..5c074c6
--- /dev/null
@@ -0,0 +1,292 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <helpers/bitmask.h>
+
+/* How many bits in an unsigned long */
+#define bitsperlong (8 * sizeof(unsigned long))
+
+/* howmany(a,b) : how many elements of size b needed to hold all of a */
+#define howmany(x, y) (((x)+((y)-1))/(y))
+
+/* How many longs in mask of n bits */
+#define longsperbits(n) howmany(n, bitsperlong)
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+/*
+ * Allocate and free `struct bitmask *`
+ */
+
+/* Allocate a new `struct bitmask` with a size of n bits */
+struct bitmask *bitmask_alloc(unsigned int n)
+{
+       struct bitmask *bmp;
+
+       bmp = malloc(sizeof(*bmp));
+       if (bmp == 0)
+               return 0;
+       bmp->size = n;
+       bmp->maskp = calloc(longsperbits(n), sizeof(unsigned long));
+       if (bmp->maskp == 0) {
+               free(bmp);
+               return 0;
+       }
+       return bmp;
+}
+
+/* Free `struct bitmask` */
+void bitmask_free(struct bitmask *bmp)
+{
+       if (bmp == 0)
+               return;
+       free(bmp->maskp);
+       bmp->maskp = (unsigned long *)0xdeadcdef;  /* double free tripwire */
+       free(bmp);
+}
+
+/*
+ * The routines _getbit() and _setbit() are the only
+ * routines that actually understand the layout of bmp->maskp[].
+ *
+ * On little endian architectures, this could simply be an array of
+ * bytes.  But the kernel layout of bitmasks _is_ visible to userspace
+ * via the sched_(set/get)affinity calls in Linux 2.6, and on big
+ * endian architectures, it is painfully obvious that this is an
+ * array of unsigned longs.
+ */
+
+/* Return the value (0 or 1) of bit n in bitmask bmp */
+static unsigned int _getbit(const struct bitmask *bmp, unsigned int n)
+{
+       if (n < bmp->size)
+               return (bmp->maskp[n/bitsperlong] >> (n % bitsperlong)) & 1;
+       else
+               return 0;
+}
+
+/* Set bit n in bitmask bmp to value v (0 or 1) */
+static void _setbit(struct bitmask *bmp, unsigned int n, unsigned int v)
+{
+       if (n < bmp->size) {
+               if (v)
+                       bmp->maskp[n/bitsperlong] |= 1UL << (n % bitsperlong);
+               else
+                       bmp->maskp[n/bitsperlong] &=
+                               ~(1UL << (n % bitsperlong));
+       }
+}
+
+/*
+ * When parsing bitmask lists, only allow numbers, separated by one
+ * of the allowed next characters.
+ *
+ * The parameter 'sret' is the return from a sscanf "%u%c".  It is
+ * -1 if the sscanf input string was empty.  It is 0 if the first
+ * character in the sscanf input string was not a decimal number.
+ * It is 1 if the unsigned number matching the "%u" was the end of the
+ * input string.  It is 2 if one or more additional characters followed
+ * the matched unsigned number.  If it is 2, then 'nextc' is the first
+ * character following the number.  The parameter 'ok_next_chars'
+ * is the nul-terminated list of allowed next characters.
+ *
+ * The mask term just scanned was ok if and only if either the numbers
+ * matching the %u were all of the input or if the next character in
+ * the input past the numbers was one of the allowed next characters.
+ */
+static int scan_was_ok(int sret, char nextc, const char *ok_next_chars)
+{
+       return sret == 1 ||
+               (sret == 2 && strchr(ok_next_chars, nextc) != NULL);
+}
+
+static const char *nexttoken(const char *q,  int sep)
+{
+       if (q)
+               q = strchr(q, sep);
+       if (q)
+               q++;
+       return q;
+}
+
+/* Set a single bit i in bitmask */
+struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i)
+{
+       _setbit(bmp, i, 1);
+       return bmp;
+}
+
+/* Set all bits in bitmask: bmp = ~0 */
+struct bitmask *bitmask_setall(struct bitmask *bmp)
+{
+       unsigned int i;
+       for (i = 0; i < bmp->size; i++)
+               _setbit(bmp, i, 1);
+       return bmp;
+}
+
+/* Clear all bits in bitmask: bmp = 0 */
+struct bitmask *bitmask_clearall(struct bitmask *bmp)
+{
+       unsigned int i;
+       for (i = 0; i < bmp->size; i++)
+               _setbit(bmp, i, 0);
+       return bmp;
+}
+
+/* True if all bits are clear */
+int bitmask_isallclear(const struct bitmask *bmp)
+{
+       unsigned int i;
+       for (i = 0; i < bmp->size; i++)
+               if (_getbit(bmp, i))
+                       return 0;
+       return 1;
+}
+
+/* True if specified bit i is set */
+int bitmask_isbitset(const struct bitmask *bmp, unsigned int i)
+{
+       return _getbit(bmp, i);
+}
+
+/* Number of lowest set bit (min) */
+unsigned int bitmask_first(const struct bitmask *bmp)
+{
+       return bitmask_next(bmp, 0);
+}
+
+/* Number of highest set bit (max) */
+unsigned int bitmask_last(const struct bitmask *bmp)
+{
+       unsigned int i;
+       unsigned int m = bmp->size;
+       for (i = 0; i < bmp->size; i++)
+               if (_getbit(bmp, i))
+                       m = i;
+       return m;
+}
+
+/* Number of next set bit at or above given bit i */
+unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i)
+{
+       unsigned int n;
+       for (n = i; n < bmp->size; n++)
+               if (_getbit(bmp, n))
+                       break;
+       return n;
+}
+
+/*
+ * Parses a comma-separated list of numbers and ranges of numbers,
+ * with optional ':%u' strides modifying ranges, into provided bitmask.
+ * Some examples of input lists and their equivalent simple list:
+ *     Input           Equivalent to
+ *     0-3             0,1,2,3
+ *     0-7:2           0,2,4,6
+ *     1,3,5-7         1,3,5,6,7
+ *     0-3:2,8-15:4    0,2,8,12
+ */
+int bitmask_parselist(const char *buf, struct bitmask *bmp)
+{
+       const char *p, *q;
+
+       bitmask_clearall(bmp);
+
+       q = buf;
+       while (p = q, q = nexttoken(q, ','), p) {
+               unsigned int a;         /* begin of range */
+               unsigned int b;         /* end of range */
+               unsigned int s;         /* stride */
+               const char *c1, *c2;    /* next tokens after '-' or ',' */
+               char nextc;             /* char after sscanf %u match */
+               int sret;               /* sscanf return (number of matches) */
+
+               sret = sscanf(p, "%u%c", &a, &nextc);
+               if (!scan_was_ok(sret, nextc, ",-"))
+                       goto err;
+               b = a;
+               s = 1;
+               c1 = nexttoken(p, '-');
+               c2 = nexttoken(p, ',');
+               if (c1 != NULL && (c2 == NULL || c1 < c2)) {
+                       sret = sscanf(c1, "%u%c", &b, &nextc);
+                       if (!scan_was_ok(sret, nextc, ",:"))
+                               goto err;
+                       c1 = nexttoken(c1, ':');
+                       if (c1 != NULL && (c2 == NULL || c1 < c2)) {
+                               sret = sscanf(c1, "%u%c", &s, &nextc);
+                               if (!scan_was_ok(sret, nextc, ","))
+                                       goto err;
+                       }
+               }
+               if (!(a <= b))
+                       goto err;
+               if (b >= bmp->size)
+                       goto err;
+               while (a <= b) {
+                       _setbit(bmp, a, 1);
+                       a += s;
+               }
+       }
+       return 0;
+err:
+       bitmask_clearall(bmp);
+       return -1;
+}
+
+/*
+ * emit(buf, buflen, rbot, rtop, len)
+ *
+ * Helper routine for bitmask_displaylist().  Write decimal number
+ * or range to buf+len, suppressing output past buf+buflen, with optional
+ * comma-prefix.  Return len of what would be written to buf, if it
+ * all fit.
+ */
+
+static inline int emit(char *buf, int buflen, int rbot, int rtop, int len)
+{
+       if (len > 0)
+               len += snprintf(buf + len, max(buflen - len, 0), ",");
+       if (rbot == rtop)
+               len += snprintf(buf + len, max(buflen - len, 0), "%d", rbot);
+       else
+               len += snprintf(buf + len, max(buflen - len, 0), "%d-%d",
+                               rbot, rtop);
+       return len;
+}
+
+/*
+ * Write decimal list representation of bmp to buf.
+ *
+ * Output format is a comma-separated list of decimal numbers and
+ * ranges.  Consecutively set bits are shown as two hyphen-separated
+ * decimal numbers, the smallest and largest bit numbers set in
+ * the range.  Output format is compatible with the format
+ * accepted as input by bitmap_parselist().
+ *
+ * The return value is the number of characters which would be
+ * generated for the given input, excluding the trailing '\0', as
+ * per ISO C99.
+ */
+
+int bitmask_displaylist(char *buf, int buflen, const struct bitmask *bmp)
+{
+       int len = 0;
+       /* current bit is 'cur', most recently seen range is [rbot, rtop] */
+       unsigned int cur, rbot, rtop;
+
+       if (buflen > 0)
+               *buf = 0;
+       rbot = cur = bitmask_first(bmp);
+       while (cur < bmp->size) {
+               rtop = cur;
+               cur = bitmask_next(bmp, cur+1);
+               if (cur >= bmp->size || cur > rtop + 1) {
+                       len = emit(buf, buflen, rbot, rtop, len);
+                       rbot = cur;
+               }
+       }
+       return len;
+}
diff --git a/tools/power/cpupower/utils/helpers/bitmask.h b/tools/power/cpupower/utils/helpers/bitmask.h
new file mode 100644 (file)
index 0000000..eb289df
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __CPUPOWER_BITMASK__
+#define __CPUPOWER_BITMASK__
+
+/* Taken over from libbitmask, a project initiated from sgi:
+ * Url:            http://oss.sgi.com/projects/cpusets/
+ * Unfortunately it's not very widespread, therefore relevant parts are
+ * pasted here.
+ */
+
+struct bitmask {
+       unsigned int size;
+       unsigned long *maskp;
+};
+
+struct bitmask *bitmask_alloc(unsigned int n);
+void bitmask_free(struct bitmask *bmp);
+
+struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i);
+struct bitmask *bitmask_setall(struct bitmask *bmp);
+struct bitmask *bitmask_clearall(struct bitmask *bmp);
+
+unsigned int bitmask_first(const struct bitmask *bmp);
+unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i);
+unsigned int bitmask_last(const struct bitmask *bmp);
+int bitmask_isallclear(const struct bitmask *bmp);
+int bitmask_isbitset(const struct bitmask *bmp, unsigned int i);
+
+int bitmask_parselist(const char *buf, struct bitmask *bmp);
+int bitmask_displaylist(char *buf, int len, const struct bitmask *bmp);
+
+
+
+#endif /*__CPUPOWER_BITMASK__ */
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
new file mode 100644 (file)
index 0000000..906895d
--- /dev/null
@@ -0,0 +1,176 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "helpers/helpers.h"
+
+static const char *cpu_vendor_table[X86_VENDOR_MAX] = {
+       "Unknown", "GenuineIntel", "AuthenticAMD",
+};
+
+#if defined(__i386__) || defined(__x86_64__)
+
+/* from gcc */
+#include <cpuid.h>
+
+/*
+ * CPUID functions returning a single datum
+ *
+ * Define unsigned int cpuid_e[abcd]x(unsigned int op)
+ */
+#define cpuid_func(reg)                                        \
+       unsigned int cpuid_##reg(unsigned int op)       \
+       {                                               \
+       unsigned int eax, ebx, ecx, edx;                \
+       __cpuid(op, eax, ebx, ecx, edx);                \
+       return reg;                                     \
+       }
+cpuid_func(eax);
+cpuid_func(ebx);
+cpuid_func(ecx);
+cpuid_func(edx);
+
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+/* get_cpu_info
+ *
+ * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo
+ *
+ * Returns 0 on success or a negativ error code
+ *
+ * TBD: Should there be a cpuid alternative for this if /proc is not mounted?
+ */
+int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info)
+{
+       FILE *fp;
+       char value[64];
+       unsigned int proc, x;
+       unsigned int unknown = 0xffffff;
+       unsigned int cpuid_level, ext_cpuid_level;
+
+       int ret = -EINVAL;
+
+       cpu_info->vendor                = X86_VENDOR_UNKNOWN;
+       cpu_info->family                = unknown;
+       cpu_info->model                 = unknown;
+       cpu_info->stepping              = unknown;
+       cpu_info->caps                  = 0;
+
+       fp = fopen("/proc/cpuinfo", "r");
+       if (!fp)
+               return -EIO;
+
+       while (!feof(fp)) {
+               if (!fgets(value, 64, fp))
+                       continue;
+               value[63 - 1] = '\0';
+
+               if (!strncmp(value, "processor\t: ", 12))
+                       sscanf(value, "processor\t: %u", &proc);
+
+               if (proc != cpu)
+                       continue;
+
+               /* Get CPU vendor */
+               if (!strncmp(value, "vendor_id", 9)) {
+                       for (x = 1; x < X86_VENDOR_MAX; x++) {
+                               if (strstr(value, cpu_vendor_table[x]))
+                                       cpu_info->vendor = x;
+                       }
+               /* Get CPU family, etc. */
+               } else if (!strncmp(value, "cpu family\t: ", 13)) {
+                       sscanf(value, "cpu family\t: %u",
+                              &cpu_info->family);
+               } else if (!strncmp(value, "model\t\t: ", 9)) {
+                       sscanf(value, "model\t\t: %u",
+                              &cpu_info->model);
+               } else if (!strncmp(value, "stepping\t: ", 10)) {
+                       sscanf(value, "stepping\t: %u",
+                              &cpu_info->stepping);
+
+                       /* Exit -> all values must have been set */
+                       if (cpu_info->vendor == X86_VENDOR_UNKNOWN ||
+                           cpu_info->family == unknown ||
+                           cpu_info->model == unknown ||
+                           cpu_info->stepping == unknown) {
+                               ret = -EINVAL;
+                               goto out;
+                       }
+
+                       ret = 0;
+                       goto out;
+               }
+       }
+       ret = -ENODEV;
+out:
+       fclose(fp);
+       /* Get some useful CPU capabilities from cpuid */
+       if (cpu_info->vendor != X86_VENDOR_AMD &&
+           cpu_info->vendor != X86_VENDOR_INTEL)
+               return ret;
+
+       cpuid_level     = cpuid_eax(0);
+       ext_cpuid_level = cpuid_eax(0x80000000);
+
+       /* Invariant TSC */
+       if (ext_cpuid_level >= 0x80000007 &&
+           (cpuid_edx(0x80000007) & (1 << 8)))
+               cpu_info->caps |= CPUPOWER_CAP_INV_TSC;
+
+       /* Aperf/Mperf registers support */
+       if (cpuid_level >= 6 && (cpuid_ecx(6) & 0x1))
+               cpu_info->caps |= CPUPOWER_CAP_APERF;
+
+       /* AMD Boost state enable/disable register */
+       if (cpu_info->vendor == X86_VENDOR_AMD) {
+               if (ext_cpuid_level >= 0x80000007 &&
+                   (cpuid_edx(0x80000007) & (1 << 9)))
+                       cpu_info->caps |= CPUPOWER_CAP_AMD_CBP;
+       }
+
+       if (cpu_info->vendor == X86_VENDOR_INTEL) {
+               if (cpuid_level >= 6 &&
+                   (cpuid_eax(6) & (1 << 1)))
+                       cpu_info->caps |= CPUPOWER_CAP_INTEL_IDA;
+       }
+
+       if (cpu_info->vendor == X86_VENDOR_INTEL) {
+               /* Intel's perf-bias MSR support */
+               if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3)))
+                       cpu_info->caps |= CPUPOWER_CAP_PERF_BIAS;
+
+               /* Intel's Turbo Ratio Limit support */
+               if (cpu_info->family == 6) {
+                       switch (cpu_info->model) {
+                       case 0x1A:      /* Core i7, Xeon 5500 series
+                                        * Bloomfield, Gainstown NHM-EP
+                                        */
+                       case 0x1E:      /* Core i7 and i5 Processor
+                                        * Clarksfield, Lynnfield, Jasper Forest
+                                        */
+                       case 0x1F:      /* Core i7 and i5 Processor - Nehalem */
+                       case 0x25:      /* Westmere Client
+                                        * Clarkdale, Arrandale
+                                        */
+                       case 0x2C:      /* Westmere EP - Gulftown */
+                               cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
+                       case 0x2A:      /* SNB */
+                       case 0x2D:      /* SNB Xeon */
+                               cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
+                               cpu_info->caps |= CPUPOWER_CAP_IS_SNB;
+                               break;
+                       case 0x2E:      /* Nehalem-EX Xeon - Beckton */
+                       case 0x2F:      /* Westmere-EX Xeon - Eagleton */
+                       default:
+                               break;
+                       }
+               }
+       }
+
+       /*      printf("ID: %u - Extid: 0x%x - Caps: 0x%llx\n",
+               cpuid_level, ext_cpuid_level, cpu_info->caps);
+       */
+       return ret;
+}
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
new file mode 100644 (file)
index 0000000..592ee36
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ * Miscellaneous helpers which do not fit or are worth
+ * to put into separate headers
+ */
+
+#ifndef __CPUPOWERUTILS_HELPERS__
+#define __CPUPOWERUTILS_HELPERS__
+
+#include <libintl.h>
+#include <locale.h>
+
+#include "helpers/bitmask.h"
+
+/* Internationalization ****************************/
+#define _(String) gettext(String)
+#ifndef gettext_noop
+#define gettext_noop(String) String
+#endif
+#define N_(String) gettext_noop(String)
+/* Internationalization ****************************/
+
+extern int run_as_root;
+extern struct bitmask *cpus_chosen;
+
+/* Global verbose (-d) stuff *********************************/
+/*
+ * define DEBUG via global Makefile variable
+ * Debug output is sent to stderr, do:
+ * cpupower monitor 2>/tmp/debug
+ * to split debug output away from normal output
+*/
+#ifdef DEBUG
+extern int be_verbose;
+
+#define dprint(fmt, ...) {                                     \
+               if (be_verbose) {                               \
+                       fprintf(stderr, "%s: " fmt,             \
+                               __func__, ##__VA_ARGS__);       \
+               }                                               \
+       }
+#else
+static inline void dprint(const char *fmt, ...) { }
+#endif
+extern int be_verbose;
+/* Global verbose (-v) stuff *********************************/
+
+/* cpuid and cpuinfo helpers  **************************/
+enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
+                         X86_VENDOR_AMD, X86_VENDOR_MAX};
+
+#define CPUPOWER_CAP_INV_TSC           0x00000001
+#define CPUPOWER_CAP_APERF             0x00000002
+#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 MAX_HW_PSTATES 10
+
+struct cpupower_cpu_info {
+       enum cpupower_cpu_vendor vendor;
+       unsigned int family;
+       unsigned int model;
+       unsigned int stepping;
+       /* CPU capabilities read out from cpuid */
+       unsigned long long caps;
+};
+
+/* get_cpu_info
+ *
+ * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo
+ *
+ * Returns 0 on success or a negativ error code
+ * Only used on x86, below global's struct values are zero/unknown on
+ * other archs
+ */
+extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info);
+extern struct cpupower_cpu_info cpupower_cpu_info;
+/* cpuid and cpuinfo helpers  **************************/
+
+
+/* CPU topology/hierarchy parsing ******************/
+struct cpupower_topology {
+       /* Amount of CPU cores, packages and threads per core in the system */
+       unsigned int cores;
+       unsigned int pkgs;
+       unsigned int threads; /* per core */
+
+       /* Array gets mallocated with cores entries, holding per core info */
+       struct {
+               int pkg;
+               int core;
+               int cpu;
+       } *core_info;
+};
+
+extern int get_cpu_topology(struct cpupower_topology *cpu_top);
+extern void cpu_topology_release(struct cpupower_topology cpu_top);
+/* CPU topology/hierarchy parsing ******************/
+
+/* X86 ONLY ****************************************/
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <pci/pci.h>
+
+/* Read/Write msr ****************************/
+extern int read_msr(int cpu, unsigned int idx, unsigned long long *val);
+extern int write_msr(int cpu, unsigned int idx, unsigned long long val);
+
+extern int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val);
+extern int msr_intel_get_perf_bias(unsigned int cpu);
+extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);
+
+/* Read/Write msr ****************************/
+
+/* 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);
+
+/* PCI stuff ****************************/
+
+/* AMD HW pstate decoding **************************/
+
+extern int decode_pstates(unsigned int cpu, unsigned int cpu_family,
+                         int boost_states, unsigned long *pstates, int *no);
+
+/* AMD HW pstate decoding **************************/
+
+extern int cpufreq_has_boost_support(unsigned int cpu, int *support,
+                                    int *active, int * states);
+/*
+ * CPUID functions returning a single datum
+ */
+unsigned int cpuid_eax(unsigned int op);
+unsigned int cpuid_ebx(unsigned int op);
+unsigned int cpuid_ecx(unsigned int op);
+unsigned int cpuid_edx(unsigned int op);
+
+/* cpuid and cpuinfo helpers  **************************/
+/* X86 ONLY ********************************************/
+#else
+static inline int decode_pstates(unsigned int cpu, unsigned int cpu_family,
+                                int boost_states, unsigned long *pstates,
+                                int *no)
+{ return -1; };
+
+static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val)
+{ return -1; };
+static inline int write_msr(int cpu, unsigned int idx, unsigned long long val)
+{ return -1; };
+static inline int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val)
+{ return -1; };
+static inline int msr_intel_get_perf_bias(unsigned int cpu)
+{ return -1; };
+static inline unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu)
+{ return 0; };
+
+/* Read/Write msr ****************************/
+
+static inline int cpufreq_has_boost_support(unsigned int cpu, int *support,
+                                           int *active, int * states)
+{ return -1; }
+
+/* cpuid and cpuinfo helpers  **************************/
+
+static inline unsigned int cpuid_eax(unsigned int op) { return 0; };
+static inline unsigned int cpuid_ebx(unsigned int op) { return 0; };
+static inline unsigned int cpuid_ecx(unsigned int op) { return 0; };
+static inline unsigned int cpuid_edx(unsigned int op) { return 0; };
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+#endif /* __CPUPOWERUTILS_HELPERS__ */
diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
new file mode 100644 (file)
index 0000000..1609243
--- /dev/null
@@ -0,0 +1,27 @@
+#if defined(__i386__) || defined(__x86_64__)
+
+#include "helpers/helpers.h"
+
+int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
+                       int *states)
+{
+       struct cpupower_cpu_info cpu_info;
+       int ret;
+
+       *support = *active = *states = 0;
+
+       ret = get_cpu_info(0, &cpu_info);
+       if (ret)
+               return ret;
+
+       if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CBP) {
+               *support = 1;
+               amd_pci_get_num_boost_states(active, states);
+               if (ret <= 0)
+                       return ret;
+               *support = 1;
+       } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA)
+               *support = *active = 1;
+       return 0;
+}
+#endif /* #if defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c
new file mode 100644 (file)
index 0000000..31a4b24
--- /dev/null
@@ -0,0 +1,115 @@
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "helpers/helpers.h"
+
+/* Intel specific MSRs */
+#define MSR_IA32_PERF_STATUS           0x198
+#define MSR_IA32_MISC_ENABLES          0x1a0
+#define MSR_IA32_ENERGY_PERF_BIAS      0x1b0
+#define MSR_NEHALEM_TURBO_RATIO_LIMIT  0x1ad
+
+/*
+ * read_msr
+ *
+ * Will return 0 on success and -1 on failure.
+ * Possible errno values could be:
+ * EFAULT -If the read/write did not fully complete
+ * EIO    -If the CPU does not support MSRs
+ * ENXIO  -If the CPU does not exist
+ */
+
+int read_msr(int cpu, unsigned int idx, unsigned long long *val)
+{
+       int fd;
+       char msr_file_name[64];
+
+       sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
+       fd = open(msr_file_name, O_RDONLY);
+       if (fd < 0)
+               return -1;
+       if (lseek(fd, idx, SEEK_CUR) == -1)
+               goto err;
+       if (read(fd, val, sizeof *val) != sizeof *val)
+               goto err;
+       close(fd);
+       return 0;
+ err:
+       close(fd);
+       return -1;
+}
+
+/*
+ * write_msr
+ *
+ * Will return 0 on success and -1 on failure.
+ * Possible errno values could be:
+ * EFAULT -If the read/write did not fully complete
+ * EIO    -If the CPU does not support MSRs
+ * ENXIO  -If the CPU does not exist
+ */
+int write_msr(int cpu, unsigned int idx, unsigned long long val)
+{
+       int fd;
+       char msr_file_name[64];
+
+       sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
+       fd = open(msr_file_name, O_WRONLY);
+       if (fd < 0)
+               return -1;
+       if (lseek(fd, idx, SEEK_CUR) == -1)
+               goto err;
+       if (write(fd, &val, sizeof val) != sizeof val)
+               goto err;
+       close(fd);
+       return 0;
+ err:
+       close(fd);
+       return -1;
+}
+
+int msr_intel_get_perf_bias(unsigned int cpu)
+{
+       unsigned long long val;
+       int ret;
+
+       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS))
+               return -1;
+
+       ret = read_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &val);
+       if (ret)
+               return ret;
+       return val;
+}
+
+int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val)
+{
+       int ret;
+
+       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS))
+               return -1;
+
+       ret = write_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, val);
+       if (ret)
+               return ret;
+       return 0;
+}
+
+unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu)
+{
+       unsigned long long val;
+       int ret;
+
+       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO))
+               return -1;
+
+       ret = read_msr(cpu, MSR_NEHALEM_TURBO_RATIO_LIMIT, &val);
+       if (ret)
+               return ret;
+       return val;
+}
+#endif
diff --git a/tools/power/cpupower/utils/helpers/pci.c b/tools/power/cpupower/utils/helpers/pci.c
new file mode 100644 (file)
index 0000000..cd2eb6f
--- /dev/null
@@ -0,0 +1,44 @@
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <helpers/helpers.h>
+
+/*
+ * pci_acc_init
+ *
+ * PCI access helper function depending on libpci
+ *
+ * **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
+ *
+ * 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_filter filter_nb_link = { -1, -1, -1, -1, vendor_id, 0};
+       struct pci_dev *device;
+       unsigned int i;
+
+       *pacc = pci_alloc();
+       if (*pacc == NULL)
+               return NULL;
+
+       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;
+               }
+       }
+       pci_cleanup(*pacc);
+       return NULL;
+}
+#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
new file mode 100644 (file)
index 0000000..55e2466
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
+ *  (C) 2011       Thomas Renninger <trenn@novell.com> Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "helpers/sysfs.h"
+
+unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
+{
+       int fd;
+       ssize_t numread;
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+               return 0;
+
+       numread = read(fd, buf, buflen - 1);
+       if (numread < 1) {
+               close(fd);
+               return 0;
+       }
+
+       buf[numread] = '\0';
+       close(fd);
+
+       return (unsigned int) numread;
+}
+
+static unsigned int sysfs_write_file(const char *path,
+                                    const char *value, size_t len)
+{
+       int fd;
+       ssize_t numwrite;
+
+       fd = open(path, O_WRONLY);
+       if (fd == -1)
+               return 0;
+
+       numwrite = write(fd, value, len);
+       if (numwrite < 1) {
+               close(fd);
+               return 0;
+       }
+       close(fd);
+       return (unsigned int) numwrite;
+}
+
+/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
+
+/*
+ * helper function to read file from /sys into given buffer
+ * fname is a relative path under "cpuX/cpuidle/stateX/" dir
+ * cstates starting with 0, C0 is not counted as cstate.
+ * This means if you want C1 info, pass 0 as idlestate param
+ */
+unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate,
+                            const char *fname, char *buf, size_t buflen)
+{
+       char path[SYSFS_PATH_MAX];
+       int fd;
+       ssize_t numread;
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
+                cpu, idlestate, fname);
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+               return 0;
+
+       numread = read(fd, buf, buflen - 1);
+       if (numread < 1) {
+               close(fd);
+               return 0;
+       }
+
+       buf[numread] = '\0';
+       close(fd);
+
+       return (unsigned int) numread;
+}
+
+/* read access to files which contain one numeric value */
+
+enum idlestate_value {
+       IDLESTATE_USAGE,
+       IDLESTATE_POWER,
+       IDLESTATE_LATENCY,
+       IDLESTATE_TIME,
+       MAX_IDLESTATE_VALUE_FILES
+};
+
+static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = {
+       [IDLESTATE_USAGE] = "usage",
+       [IDLESTATE_POWER] = "power",
+       [IDLESTATE_LATENCY] = "latency",
+       [IDLESTATE_TIME]  = "time",
+};
+
+static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu,
+                                                    unsigned int idlestate,
+                                                    enum idlestate_value which)
+{
+       unsigned long long value;
+       unsigned int len;
+       char linebuf[MAX_LINE_LEN];
+       char *endp;
+
+       if (which >= MAX_IDLESTATE_VALUE_FILES)
+               return 0;
+
+       len = sysfs_idlestate_read_file(cpu, idlestate,
+                                       idlestate_value_files[which],
+                                       linebuf, sizeof(linebuf));
+       if (len == 0)
+               return 0;
+
+       value = strtoull(linebuf, &endp, 0);
+
+       if (endp == linebuf || errno == ERANGE)
+               return 0;
+
+       return value;
+}
+
+/* read access to files which contain one string */
+
+enum idlestate_string {
+       IDLESTATE_DESC,
+       IDLESTATE_NAME,
+       MAX_IDLESTATE_STRING_FILES
+};
+
+static const char *idlestate_string_files[MAX_IDLESTATE_STRING_FILES] = {
+       [IDLESTATE_DESC] = "desc",
+       [IDLESTATE_NAME] = "name",
+};
+
+
+static char *sysfs_idlestate_get_one_string(unsigned int cpu,
+                                       unsigned int idlestate,
+                                       enum idlestate_string which)
+{
+       char linebuf[MAX_LINE_LEN];
+       char *result;
+       unsigned int len;
+
+       if (which >= MAX_IDLESTATE_STRING_FILES)
+               return NULL;
+
+       len = sysfs_idlestate_read_file(cpu, idlestate,
+                                       idlestate_string_files[which],
+                                       linebuf, sizeof(linebuf));
+       if (len == 0)
+               return NULL;
+
+       result = strdup(linebuf);
+       if (result == NULL)
+               return NULL;
+
+       if (result[strlen(result) - 1] == '\n')
+               result[strlen(result) - 1] = '\0';
+
+       return result;
+}
+
+unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
+                                       unsigned int idlestate)
+{
+       return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY);
+}
+
+unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
+                                       unsigned int idlestate)
+{
+       return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_USAGE);
+}
+
+unsigned long long sysfs_get_idlestate_time(unsigned int cpu,
+                                       unsigned int idlestate)
+{
+       return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_TIME);
+}
+
+char *sysfs_get_idlestate_name(unsigned int cpu, unsigned int idlestate)
+{
+       return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_NAME);
+}
+
+char *sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate)
+{
+       return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_DESC);
+}
+
+/*
+ * Returns number of supported C-states of CPU core cpu
+ * Negativ in error case
+ * Zero if cpuidle does not export any C-states
+ */
+int sysfs_get_idlestate_count(unsigned int cpu)
+{
+       char file[SYSFS_PATH_MAX];
+       struct stat statbuf;
+       int idlestates = 1;
+
+
+       snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpuidle");
+       if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
+               return -ENODEV;
+
+       snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state0", cpu);
+       if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
+               return 0;
+
+       while (stat(file, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
+               snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU
+                        "cpu%u/cpuidle/state%d", cpu, idlestates);
+               idlestates++;
+       }
+       idlestates--;
+       return idlestates;
+}
+
+/* CPUidle general /sys/devices/system/cpu/cpuidle/ sysfs access ********/
+
+/*
+ * helper function to read file from /sys into given buffer
+ * fname is a relative path under "cpu/cpuidle/" dir
+ */
+static unsigned int sysfs_cpuidle_read_file(const char *fname, char *buf,
+                                           size_t buflen)
+{
+       char path[SYSFS_PATH_MAX];
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpuidle/%s", fname);
+
+       return sysfs_read_file(path, buf, buflen);
+}
+
+
+
+/* read access to files which contain one string */
+
+enum cpuidle_string {
+       CPUIDLE_GOVERNOR,
+       CPUIDLE_GOVERNOR_RO,
+       CPUIDLE_DRIVER,
+       MAX_CPUIDLE_STRING_FILES
+};
+
+static const char *cpuidle_string_files[MAX_CPUIDLE_STRING_FILES] = {
+       [CPUIDLE_GOVERNOR]      = "current_governor",
+       [CPUIDLE_GOVERNOR_RO]   = "current_governor_ro",
+       [CPUIDLE_DRIVER]        = "current_driver",
+};
+
+
+static char *sysfs_cpuidle_get_one_string(enum cpuidle_string which)
+{
+       char linebuf[MAX_LINE_LEN];
+       char *result;
+       unsigned int len;
+
+       if (which >= MAX_CPUIDLE_STRING_FILES)
+               return NULL;
+
+       len = sysfs_cpuidle_read_file(cpuidle_string_files[which],
+                               linebuf, sizeof(linebuf));
+       if (len == 0)
+               return NULL;
+
+       result = strdup(linebuf);
+       if (result == NULL)
+               return NULL;
+
+       if (result[strlen(result) - 1] == '\n')
+               result[strlen(result) - 1] = '\0';
+
+       return result;
+}
+
+char *sysfs_get_cpuidle_governor(void)
+{
+       char *tmp = sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR_RO);
+       if (!tmp)
+               return sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR);
+       else
+               return tmp;
+}
+
+char *sysfs_get_cpuidle_driver(void)
+{
+       return sysfs_cpuidle_get_one_string(CPUIDLE_DRIVER);
+}
+/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
+
+/*
+ * Get sched_mc or sched_smt settings
+ * Pass "mc" or "smt" as argument
+ *
+ * Returns negative value on failure
+ */
+int sysfs_get_sched(const char *smt_mc)
+{
+       unsigned long value;
+       char linebuf[MAX_LINE_LEN];
+       char *endp;
+       char path[SYSFS_PATH_MAX];
+
+       if (strcmp("mc", smt_mc) && strcmp("smt", smt_mc))
+               return -EINVAL;
+
+       snprintf(path, sizeof(path),
+               PATH_TO_CPU "sched_%s_power_savings", smt_mc);
+       if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0)
+               return -1;
+       value = strtoul(linebuf, &endp, 0);
+       if (endp == linebuf || errno == ERANGE)
+               return -1;
+       return value;
+}
+
+/*
+ * Get sched_mc or sched_smt settings
+ * Pass "mc" or "smt" as argument
+ *
+ * Returns negative value on failure
+ */
+int sysfs_set_sched(const char *smt_mc, int val)
+{
+       char linebuf[MAX_LINE_LEN];
+       char path[SYSFS_PATH_MAX];
+       struct stat statbuf;
+
+       if (strcmp("mc", smt_mc) && strcmp("smt", smt_mc))
+               return -EINVAL;
+
+       snprintf(path, sizeof(path),
+               PATH_TO_CPU "sched_%s_power_savings", smt_mc);
+       sprintf(linebuf, "%d", val);
+
+       if (stat(path, &statbuf) != 0)
+               return -ENODEV;
+
+       if (sysfs_write_file(path, linebuf, MAX_LINE_LEN) == 0)
+               return -1;
+       return 0;
+}
diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h
new file mode 100644 (file)
index 0000000..f9373e0
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __CPUPOWER_HELPERS_SYSFS_H__
+#define __CPUPOWER_HELPERS_SYSFS_H__
+
+#define PATH_TO_CPU "/sys/devices/system/cpu/"
+#define MAX_LINE_LEN 255
+#define SYSFS_PATH_MAX 255
+
+extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
+
+extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
+                                               unsigned int idlestate);
+extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
+                                       unsigned int idlestate);
+extern unsigned long long sysfs_get_idlestate_time(unsigned int cpu,
+                                               unsigned int idlestate);
+extern char *sysfs_get_idlestate_name(unsigned int cpu,
+                               unsigned int idlestate);
+extern char *sysfs_get_idlestate_desc(unsigned int cpu,
+                               unsigned int idlestate);
+extern int sysfs_get_idlestate_count(unsigned int cpu);
+
+extern char *sysfs_get_cpuidle_governor(void);
+extern char *sysfs_get_cpuidle_driver(void);
+
+extern int sysfs_get_sched(const char *smt_mc);
+extern int sysfs_set_sched(const char *smt_mc, int val);
+
+#endif /* __CPUPOWER_HELPERS_SYSFS_H__ */
diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c
new file mode 100644 (file)
index 0000000..385ee5c
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ * ToDo: Needs to be done more properly for AMD/Intel specifics
+ */
+
+/* Helper struct for qsort, must be in sync with cpupower_topology.cpu_info */
+/* Be careful: Need to pass unsigned to the sort, so that offlined cores are
+   in the end, but double check for -1 for offlined cpus at other places */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <helpers/helpers.h>
+#include <helpers/sysfs.h>
+
+/* returns -1 on failure, 0 on success */
+int sysfs_topology_read_file(unsigned int cpu, const char *fname)
+{
+       unsigned long value;
+       char linebuf[MAX_LINE_LEN];
+       char *endp;
+       char path[SYSFS_PATH_MAX];
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s",
+                        cpu, fname);
+       if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0)
+               return -1;
+       value = strtoul(linebuf, &endp, 0);
+       if (endp == linebuf || errno == ERANGE)
+               return -1;
+       return value;
+}
+
+struct cpuid_core_info {
+       unsigned int pkg;
+       unsigned int thread;
+       unsigned int cpu;
+};
+
+static int __compare(const void *t1, const void *t2)
+{
+       struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1;
+       struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2;
+       if (top1->pkg < top2->pkg)
+               return -1;
+       else if (top1->pkg > top2->pkg)
+               return 1;
+       else if (top1->thread < top2->thread)
+               return -1;
+       else if (top1->thread > top2->thread)
+               return 1;
+       else if (top1->cpu < top2->cpu)
+               return -1;
+       else if (top1->cpu > top2->cpu)
+               return 1;
+       else
+               return 0;
+}
+
+/*
+ * Returns amount of cpus, negative on error, cpu_top must be
+ * passed to cpu_topology_release to free resources
+ *
+ * Array is sorted after ->pkg, ->core, then ->cpu
+ */
+int get_cpu_topology(struct cpupower_topology *cpu_top)
+{
+       int cpu, cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+       cpu_top->core_info = malloc(sizeof(struct cpupower_topology) * cpus);
+       if (cpu_top->core_info == NULL)
+               return -ENOMEM;
+       cpu_top->pkgs = cpu_top->cores = 0;
+       for (cpu = 0; cpu < cpus; cpu++) {
+               cpu_top->core_info[cpu].pkg =
+                       sysfs_topology_read_file(cpu, "physical_package_id");
+               if ((int)cpu_top->core_info[cpu].pkg != -1 &&
+                   cpu_top->core_info[cpu].pkg > cpu_top->pkgs)
+                       cpu_top->pkgs = cpu_top->core_info[cpu].pkg;
+               cpu_top->core_info[cpu].core =
+                       sysfs_topology_read_file(cpu, "core_id");
+               cpu_top->core_info[cpu].cpu = cpu;
+       }
+       cpu_top->pkgs++;
+
+       qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
+             __compare);
+
+       /* Intel's cores count is not consecutively numbered, there may
+        * be a core_id of 3, but none of 2. Assume there always is 0
+        * Get amount of cores by counting duplicates in a package
+       for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) {
+               if (cpu_top->core_info[cpu].core == 0)
+       cpu_top->cores++;
+       */
+       return cpus;
+}
+
+void cpu_topology_release(struct cpupower_topology cpu_top)
+{
+       free(cpu_top.core_info);
+}
diff --git a/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c
new file mode 100644 (file)
index 0000000..202e555
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ *  (C) 2010,2011      Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  PCI initialization based on example code from:
+ *  Andreas Herrmann <andreas.herrmann3@amd.com>
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <time.h>
+#include <string.h>
+
+#include <pci/pci.h>
+
+#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
+
+#define PCI_MONITOR_ENABLE_REG  0xe0
+
+#define PCI_NON_PC0_ENABLE_BIT 0
+#define PCI_PC1_ENABLE_BIT     1
+#define PCI_PC6_ENABLE_BIT     2
+
+#define PCI_NBP1_STAT_OFFSET   0x98
+#define PCI_NBP1_ACTIVE_BIT    2
+#define PCI_NBP1_ENTERED_BIT   1
+
+#define PCI_NBP1_CAP_OFFSET    0x90
+#define PCI_NBP1_CAPABLE_BIT    31
+
+#define OVERFLOW_MS            343597 /* 32 bit register filled at 12500 HZ
+                                         (1 tick per 80ns) */
+
+enum amd_fam14h_states {NON_PC0 = 0, PC1, PC6, NBP1,
+                       AMD_FAM14H_STATE_NUM};
+
+static int fam14h_get_count_percent(unsigned int self_id, double *percent,
+                                   unsigned int cpu);
+static int fam14h_nbp1_count(unsigned int id, unsigned long long *count,
+                            unsigned int cpu);
+
+static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = {
+       {
+               .name                   = "!PC0",
+               .desc                   = N_("Package in sleep state (PC1 or deeper)"),
+               .id                     = NON_PC0,
+               .range                  = RANGE_PACKAGE,
+               .get_count_percent      = fam14h_get_count_percent,
+       },
+       {
+               .name                   = "PC1",
+               .desc                   = N_("Processor Package C1"),
+               .id                     = PC1,
+               .range                  = RANGE_PACKAGE,
+               .get_count_percent      = fam14h_get_count_percent,
+       },
+       {
+               .name                   = "PC6",
+               .desc                   = N_("Processor Package C6"),
+               .id                     = PC6,
+               .range                  = RANGE_PACKAGE,
+               .get_count_percent      = fam14h_get_count_percent,
+       },
+       {
+               .name                   = "NBP1",
+               .desc                   = N_("North Bridge P1 boolean counter (returns 0 or 1)"),
+               .id                     = NBP1,
+               .range                  = RANGE_PACKAGE,
+               .get_count              = fam14h_nbp1_count,
+       },
+};
+
+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;
+static unsigned long long timediff;
+
+#ifdef DEBUG
+struct timespec dbg_time;
+long dbg_timediff;
+#endif
+
+static unsigned long long *previous_count[AMD_FAM14H_STATE_NUM];
+static unsigned long long *current_count[AMD_FAM14H_STATE_NUM];
+
+static int amd_fam14h_get_pci_info(struct cstate *state,
+                                  unsigned int *pci_offset,
+                                  unsigned int *enable_bit,
+                                  unsigned int cpu)
+{
+       switch (state->id) {
+       case NON_PC0:
+               *enable_bit = PCI_NON_PC0_ENABLE_BIT;
+               *pci_offset = PCI_NON_PC0_OFFSET;
+               break;
+       case PC1:
+               *enable_bit = PCI_PC1_ENABLE_BIT;
+               *pci_offset = PCI_PC1_OFFSET;
+               break;
+       case PC6:
+               *enable_bit = PCI_PC6_ENABLE_BIT;
+               *pci_offset = PCI_PC6_OFFSET;
+               break;
+       case NBP1:
+               *enable_bit = PCI_NBP1_ENTERED_BIT;
+               *pci_offset = PCI_NBP1_STAT_OFFSET;
+               break;
+       default:
+               return -1;
+       };
+       return 0;
+}
+
+static int amd_fam14h_init(cstate_t *state, unsigned int cpu)
+{
+       int enable_bit, pci_offset, ret;
+       uint32_t val;
+
+       ret = amd_fam14h_get_pci_info(state, &pci_offset, &enable_bit, cpu);
+       if (ret)
+               return ret;
+
+       /* NBP1 needs extra treating -> write 1 to D18F6x98 bit 1 for init */
+       if (state->id == NBP1) {
+               val = pci_read_long(amd_fam14h_pci_dev, pci_offset);
+               val |= 1 << enable_bit;
+               val = pci_write_long(amd_fam14h_pci_dev, pci_offset, val);
+               return ret;
+       }
+
+       /* Enable monitor */
+       val = pci_read_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG);
+       dprint("Init %s: read at offset: 0x%x val: %u\n", state->name,
+              PCI_MONITOR_ENABLE_REG, (unsigned int) val);
+       val |= 1 << enable_bit;
+       pci_write_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG, val);
+
+       dprint("Init %s: offset: 0x%x enable_bit: %d - val: %u (%u)\n",
+              state->name, PCI_MONITOR_ENABLE_REG, enable_bit,
+              (unsigned int) val, cpu);
+
+       /* Set counter to zero */
+       pci_write_long(amd_fam14h_pci_dev, pci_offset, 0);
+       previous_count[state->id][cpu] = 0;
+
+       return 0;
+}
+
+static int amd_fam14h_disable(cstate_t *state, unsigned int cpu)
+{
+       int enable_bit, pci_offset, ret;
+       uint32_t val;
+
+       ret = amd_fam14h_get_pci_info(state, &pci_offset, &enable_bit, cpu);
+       if (ret)
+               return ret;
+
+       val = pci_read_long(amd_fam14h_pci_dev, pci_offset);
+       dprint("%s: offset: 0x%x %u\n", state->name, pci_offset, val);
+       if (state->id == NBP1) {
+               /* was the bit whether NBP1 got entered set? */
+               nbp1_entered = (val & (1 << PCI_NBP1_ACTIVE_BIT)) |
+                       (val & (1 << PCI_NBP1_ENTERED_BIT));
+
+               dprint("NBP1 was %sentered - 0x%x - enable_bit: "
+                      "%d - pci_offset: 0x%x\n",
+                      nbp1_entered ? "" : "not ",
+                      val, enable_bit, pci_offset);
+               return ret;
+       }
+       current_count[state->id][cpu] = val;
+
+       dprint("%s: Current -  %llu (%u)\n", state->name,
+              current_count[state->id][cpu], cpu);
+       dprint("%s: Previous - %llu (%u)\n", state->name,
+              previous_count[state->id][cpu], cpu);
+
+       val = pci_read_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG);
+       val &= ~(1 << enable_bit);
+       pci_write_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG, val);
+
+       return 0;
+}
+
+static int fam14h_nbp1_count(unsigned int id, unsigned long long *count,
+                            unsigned int cpu)
+{
+       if (id == NBP1) {
+               if (nbp1_entered)
+                       *count = 1;
+               else
+                       *count = 0;
+               return 0;
+       }
+       return -1;
+}
+static int fam14h_get_count_percent(unsigned int id, double *percent,
+                                   unsigned int cpu)
+{
+       unsigned long diff;
+
+       if (id >= AMD_FAM14H_STATE_NUM)
+               return -1;
+       /* residency count in 80ns -> divide through 12.5 to get us residency */
+       diff = current_count[id][cpu] - previous_count[id][cpu];
+
+       if (timediff == 0)
+               *percent = 0.0;
+       else
+               *percent = 100.0 * diff / timediff / 12.5;
+
+       dprint("Timediff: %llu - res~: %lu us - percent: %.2f %%\n",
+              timediff, diff * 10 / 125, *percent);
+
+       return 0;
+}
+
+static int amd_fam14h_start(void)
+{
+       int num, cpu;
+       clock_gettime(CLOCK_REALTIME, &start_time);
+       for (num = 0; num < AMD_FAM14H_STATE_NUM; num++) {
+               for (cpu = 0; cpu < cpu_count; cpu++)
+                       amd_fam14h_init(&amd_fam14h_cstates[num], cpu);
+       }
+#ifdef DEBUG
+       clock_gettime(CLOCK_REALTIME, &dbg_time);
+       dbg_timediff = timespec_diff_us(start_time, dbg_time);
+       dprint("Enabling counters took: %lu us\n",
+              dbg_timediff);
+#endif
+       return 0;
+}
+
+static int amd_fam14h_stop(void)
+{
+       int num, cpu;
+       struct timespec end_time;
+
+       clock_gettime(CLOCK_REALTIME, &end_time);
+
+       for (num = 0; num < AMD_FAM14H_STATE_NUM; num++) {
+               for (cpu = 0; cpu < cpu_count; cpu++)
+                       amd_fam14h_disable(&amd_fam14h_cstates[num], cpu);
+       }
+#ifdef DEBUG
+       clock_gettime(CLOCK_REALTIME, &dbg_time);
+       dbg_timediff = timespec_diff_us(end_time, dbg_time);
+       dprint("Disabling counters took: %lu ns\n", dbg_timediff);
+#endif
+       timediff = timespec_diff_us(start_time, end_time);
+       if (timediff / 1000 > OVERFLOW_MS)
+               print_overflow_err((unsigned int)timediff / 1000000,
+                                  OVERFLOW_MS / 1000);
+
+       return 0;
+}
+
+static int is_nbp1_capable(void)
+{
+       uint32_t val;
+       val = pci_read_long(amd_fam14h_pci_dev, PCI_NBP1_CAP_OFFSET);
+       return val & (1 << 31);
+}
+
+struct cpuidle_monitor *amd_fam14h_register(void)
+{
+       int num;
+
+       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
+               return NULL;
+
+       /* We do not alloc for nbp1 machine wide counter */
+       for (num = 0; num < AMD_FAM14H_STATE_NUM - 1; num++) {
+               previous_count[num] = calloc(cpu_count,
+                                             sizeof(unsigned long long));
+               current_count[num]  = calloc(cpu_count,
+                                             sizeof(unsigned long long));
+       }
+
+       amd_fam14h_pci_dev = pci_acc_init(&pci_acc, pci_vendor_id, pci_dev_ids);
+       if (amd_fam14h_pci_dev == NULL || pci_acc == NULL)
+               return NULL;
+
+       if (!is_nbp1_capable())
+               amd_fam14h_monitor.hw_states_num = AMD_FAM14H_STATE_NUM - 1;
+
+       amd_fam14h_monitor.name_len = strlen(amd_fam14h_monitor.name);
+       return &amd_fam14h_monitor;
+}
+
+static void amd_fam14h_unregister(void)
+{
+       int num;
+       for (num = 0; num < AMD_FAM14H_STATE_NUM - 1; num++) {
+               free(previous_count[num]);
+               free(current_count[num]);
+       }
+       pci_cleanup(pci_acc);
+}
+
+struct cpuidle_monitor amd_fam14h_monitor = {
+       .name                   = "Ontario",
+       .hw_states              = amd_fam14h_cstates,
+       .hw_states_num          = AMD_FAM14H_STATE_NUM,
+       .start                  = amd_fam14h_start,
+       .stop                   = amd_fam14h_stop,
+       .do_register            = amd_fam14h_register,
+       .unregister             = amd_fam14h_unregister,
+       .needs_root             = 1,
+       .overflow_s             = OVERFLOW_MS / 1000,
+};
+#endif /* #if defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c b/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
new file mode 100644 (file)
index 0000000..d048b96
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+
+#include "helpers/sysfs.h"
+#include "helpers/helpers.h"
+#include "idle_monitor/cpupower-monitor.h"
+
+#define CPUIDLE_STATES_MAX 10
+static cstate_t cpuidle_cstates[CPUIDLE_STATES_MAX];
+struct cpuidle_monitor cpuidle_sysfs_monitor;
+
+static unsigned long long **previous_count;
+static unsigned long long **current_count;
+struct timespec start_time;
+static unsigned long long timediff;
+
+static int cpuidle_get_count_percent(unsigned int id, double *percent,
+                                    unsigned int cpu)
+{
+       unsigned long long statediff = current_count[cpu][id]
+               - previous_count[cpu][id];
+       dprint("%s: - diff: %llu - percent: %f (%u)\n",
+              cpuidle_cstates[id].name, timediff, *percent, cpu);
+
+       if (timediff == 0)
+               *percent = 0.0;
+       else
+               *percent = ((100.0 * statediff) / timediff);
+
+       dprint("%s: - timediff: %llu - statediff: %llu - percent: %f (%u)\n",
+              cpuidle_cstates[id].name, timediff, statediff, *percent, cpu);
+
+       return 0;
+}
+
+static int cpuidle_start(void)
+{
+       int cpu, state;
+       clock_gettime(CLOCK_REALTIME, &start_time);
+       for (cpu = 0; cpu < cpu_count; cpu++) {
+               for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num;
+                    state++) {
+                       previous_count[cpu][state] =
+                               sysfs_get_idlestate_time(cpu, state);
+                       dprint("CPU %d - State: %d - Val: %llu\n",
+                              cpu, state, previous_count[cpu][state]);
+               }
+       };
+       return 0;
+}
+
+static int cpuidle_stop(void)
+{
+       int cpu, state;
+       struct timespec end_time;
+       clock_gettime(CLOCK_REALTIME, &end_time);
+       timediff = timespec_diff_us(start_time, end_time);
+
+       for (cpu = 0; cpu < cpu_count; cpu++) {
+               for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num;
+                    state++) {
+                       current_count[cpu][state] =
+                               sysfs_get_idlestate_time(cpu, state);
+                       dprint("CPU %d - State: %d - Val: %llu\n",
+                              cpu, state, previous_count[cpu][state]);
+               }
+       };
+       return 0;
+}
+
+void fix_up_intel_idle_driver_name(char *tmp, int num)
+{
+       /* fix up cpuidle name for intel idle driver */
+       if (!strncmp(tmp, "NHM-", 4)) {
+               switch (num) {
+               case 1:
+                       strcpy(tmp, "C1");
+                       break;
+               case 2:
+                       strcpy(tmp, "C3");
+                       break;
+               case 3:
+                       strcpy(tmp, "C6");
+                       break;
+               }
+       } else if (!strncmp(tmp, "SNB-", 4)) {
+               switch (num) {
+               case 1:
+                       strcpy(tmp, "C1");
+                       break;
+               case 2:
+                       strcpy(tmp, "C3");
+                       break;
+               case 3:
+                       strcpy(tmp, "C6");
+                       break;
+               case 4:
+                       strcpy(tmp, "C7");
+                       break;
+               }
+       } else if (!strncmp(tmp, "ATM-", 4)) {
+               switch (num) {
+               case 1:
+                       strcpy(tmp, "C1");
+                       break;
+               case 2:
+                       strcpy(tmp, "C2");
+                       break;
+               case 3:
+                       strcpy(tmp, "C4");
+                       break;
+               case 4:
+                       strcpy(tmp, "C6");
+                       break;
+               }
+       }
+}
+
+static struct cpuidle_monitor *cpuidle_register(void)
+{
+       int num;
+       char *tmp;
+
+       /* Assume idle state count is the same for all CPUs */
+       cpuidle_sysfs_monitor.hw_states_num = sysfs_get_idlestate_count(0);
+
+       if (cpuidle_sysfs_monitor.hw_states_num == 0)
+               return NULL;
+
+       for (num = 0; num < cpuidle_sysfs_monitor.hw_states_num; num++) {
+               tmp = sysfs_get_idlestate_name(0, num);
+               if (tmp == NULL)
+                       continue;
+
+               fix_up_intel_idle_driver_name(tmp, num);
+               strncpy(cpuidle_cstates[num].name, tmp, CSTATE_NAME_LEN - 1);
+               free(tmp);
+
+               tmp = sysfs_get_idlestate_desc(0, num);
+               if (tmp == NULL)
+                       continue;
+               strncpy(cpuidle_cstates[num].desc, tmp, CSTATE_DESC_LEN - 1);
+               free(tmp);
+
+               cpuidle_cstates[num].range = RANGE_THREAD;
+               cpuidle_cstates[num].id = num;
+               cpuidle_cstates[num].get_count_percent =
+                       cpuidle_get_count_percent;
+       };
+
+       /* Free this at program termination */
+       previous_count = malloc(sizeof(long long *) * cpu_count);
+       current_count = malloc(sizeof(long long *) * cpu_count);
+       for (num = 0; num < cpu_count; num++) {
+               previous_count[num] = malloc(sizeof(long long) *
+                                       cpuidle_sysfs_monitor.hw_states_num);
+               current_count[num] = malloc(sizeof(long long) *
+                                       cpuidle_sysfs_monitor.hw_states_num);
+       }
+
+       cpuidle_sysfs_monitor.name_len = strlen(cpuidle_sysfs_monitor.name);
+       return &cpuidle_sysfs_monitor;
+}
+
+void cpuidle_unregister(void)
+{
+       int num;
+
+       for (num = 0; num < cpu_count; num++) {
+               free(previous_count[num]);
+               free(current_count[num]);
+       }
+       free(previous_count);
+       free(current_count);
+}
+
+struct cpuidle_monitor cpuidle_sysfs_monitor = {
+       .name                   = "Idle_Stats",
+       .hw_states              = cpuidle_cstates,
+       .start                  = cpuidle_start,
+       .stop                   = cpuidle_stop,
+       .do_register            = cpuidle_register,
+       .unregister             = cpuidle_unregister,
+       .needs_root             = 0,
+       .overflow_s             = UINT_MAX,
+};
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
new file mode 100644 (file)
index 0000000..ba4bf06
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  Output format inspired by Len Brown's <lenb@kernel.org> turbostat tool.
+ *
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <libgen.h>
+
+#include "idle_monitor/cpupower-monitor.h"
+#include "idle_monitor/idle_monitors.h"
+#include "helpers/helpers.h"
+
+/* Define pointers to all monitors.  */
+#define DEF(x) & x ## _monitor ,
+struct cpuidle_monitor *all_monitors[] = {
+#include "idle_monitors.def"
+0
+};
+
+static struct cpuidle_monitor *monitors[MONITORS_MAX];
+static unsigned int avail_monitors;
+
+static char *progname;
+
+enum operation_mode_e { list = 1, show, show_all };
+static int mode;
+static int interval = 1;
+static char *show_monitors_param;
+static struct cpupower_topology cpu_top;
+
+/* ToDo: Document this in the manpage */
+static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };
+
+long long timespec_diff_us(struct timespec start, struct timespec end)
+{
+       struct timespec temp;
+       if ((end.tv_nsec - start.tv_nsec) < 0) {
+               temp.tv_sec = end.tv_sec - start.tv_sec - 1;
+               temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
+       } else {
+               temp.tv_sec = end.tv_sec - start.tv_sec;
+               temp.tv_nsec = end.tv_nsec - start.tv_nsec;
+       }
+       return (temp.tv_sec * 1000000) + (temp.tv_nsec / 1000);
+}
+
+void monitor_help(void)
+{
+       printf(_("cpupower monitor: [-m <mon1>,[<mon2>],.. ] command\n"));
+       printf(_("cpupower monitor: [-m <mon1>,[<mon2>],.. ] [ -i interval_sec ]\n"));
+       printf(_("cpupower monitor: -l\n"));
+       printf(_("\t command: pass an arbitrary command to measure specific workload\n"));
+       printf(_("\t -i: time intervall to measure for in seconds (default 1)\n"));
+       printf(_("\t -l: list available CPU sleep monitors (for use with -m)\n"));
+       printf(_("\t -m: show specific CPU sleep monitors only (in same order)\n"));
+       printf(_("\t -h: print this help\n"));
+       printf("\n");
+       printf(_("only one of: -l, -m are allowed\nIf none of them is passed,"));
+       printf(_(" all supported monitors are shown\n"));
+}
+
+void print_n_spaces(int n)
+{
+       int x;
+       for (x = 0; x < n; x++)
+               printf(" ");
+}
+
+/* size of s must be at least n + 1 */
+int fill_string_with_spaces(char *s, int n)
+{
+       int len = strlen(s);
+       if (len > n)
+               return -1;
+       for (; len < n; len++)
+               s[len] = ' ';
+       s[len] = '\0';
+       return 0;
+}
+
+void print_header(int topology_depth)
+{
+       int unsigned mon;
+       int state, need_len, pr_mon_len;
+       cstate_t s;
+       char buf[128] = "";
+       int percent_width = 4;
+
+       fill_string_with_spaces(buf, topology_depth * 5 - 1);
+       printf("%s|", buf);
+
+       for (mon = 0; mon < avail_monitors; mon++) {
+               pr_mon_len = 0;
+               need_len = monitors[mon]->hw_states_num * (percent_width + 3)
+                       - 1;
+               if (mon != 0) {
+                       printf("|| ");
+                       need_len--;
+               }
+               sprintf(buf, "%s", monitors[mon]->name);
+               fill_string_with_spaces(buf, need_len);
+               printf("%s", buf);
+       }
+       printf("\n");
+
+       if (topology_depth > 2)
+               printf("PKG |");
+       if (topology_depth > 1)
+               printf("CORE|");
+       if (topology_depth > 0)
+               printf("CPU |");
+
+       for (mon = 0; mon < avail_monitors; mon++) {
+               if (mon != 0)
+                       printf("|| ");
+               else
+                       printf(" ");
+               for (state = 0; state < monitors[mon]->hw_states_num; state++) {
+                       if (state != 0)
+                               printf(" | ");
+                       s = monitors[mon]->hw_states[state];
+                       sprintf(buf, "%s", s.name);
+                       fill_string_with_spaces(buf, percent_width);
+                       printf("%s", buf);
+               }
+               printf(" ");
+       }
+       printf("\n");
+}
+
+
+void print_results(int topology_depth, int cpu)
+{
+       unsigned int mon;
+       int state, ret;
+       double percent;
+       unsigned long long result;
+       cstate_t s;
+
+       if (topology_depth > 2)
+               printf("%4d|", cpu_top.core_info[cpu].pkg);
+       if (topology_depth > 1)
+               printf("%4d|", cpu_top.core_info[cpu].core);
+       if (topology_depth > 0)
+               printf("%4d|", cpu_top.core_info[cpu].cpu);
+
+       for (mon = 0; mon < avail_monitors; mon++) {
+               if (mon != 0)
+                       printf("||");
+
+               for (state = 0; state < monitors[mon]->hw_states_num; state++) {
+                       if (state != 0)
+                               printf("|");
+
+                       s = monitors[mon]->hw_states[state];
+
+                       if (s.get_count_percent) {
+                               ret = s.get_count_percent(s.id, &percent,
+                                                 cpu_top.core_info[cpu].cpu);
+                               if (ret)
+                                       printf("******");
+                               else if (percent >= 100.0)
+                                       printf("%6.1f", percent);
+                               else
+                                       printf("%6.2f", percent);
+                       } else if (s.get_count) {
+                               ret = s.get_count(s.id, &result,
+                                                 cpu_top.core_info[cpu].cpu);
+                               if (ret)
+                                       printf("******");
+                               else
+                                       printf("%6llu", result);
+                       } else {
+                               printf(_("Monitor %s, Counter %s has no count "
+                                        "function. Implementation error\n"),
+                                      monitors[mon]->name, s.name);
+                               exit(EXIT_FAILURE);
+                       }
+               }
+       }
+       /* cpu offline */
+       if (cpu_top.core_info[cpu].pkg == -1 ||
+           cpu_top.core_info[cpu].core == -1) {
+               printf(_(" *is offline\n"));
+               return;
+       } else
+               printf("\n");
+}
+
+
+/* param: string passed by -m param (The list of monitors to show)
+ *
+ * Monitors must have been registered already, matching monitors
+ * are picked out and available monitors array is overridden
+ * with matching ones
+ *
+ * Monitors get sorted in the same order the user passes them
+*/
+
+static void parse_monitor_param(char *param)
+{
+       unsigned int num;
+       int mon, hits = 0;
+       char *tmp = param, *token;
+       struct cpuidle_monitor *tmp_mons[MONITORS_MAX];
+
+
+       for (mon = 0; mon < MONITORS_MAX; mon++, tmp = NULL) {
+               token = strtok(tmp, ",");
+               if (token == NULL)
+                       break;
+               if (strlen(token) >= MONITOR_NAME_LEN) {
+                       printf(_("%s: max monitor name length"
+                                " (%d) exceeded\n"), token, MONITOR_NAME_LEN);
+                       continue;
+               }
+
+               for (num = 0; num < avail_monitors; num++) {
+                       if (!strcmp(monitors[num]->name, token)) {
+                               dprint("Found requested monitor: %s\n", token);
+                               tmp_mons[hits] = monitors[num];
+                               hits++;
+                       }
+               }
+       }
+       if (hits == 0) {
+               printf(_("No matching monitor found in %s, "
+                        "try -l option\n"), param);
+               monitor_help();
+               exit(EXIT_FAILURE);
+       }
+       /* Override detected/registerd monitors array with requested one */
+       memcpy(monitors, tmp_mons,
+               sizeof(struct cpuidle_monitor *) * MONITORS_MAX);
+       avail_monitors = hits;
+}
+
+void list_monitors(void)
+{
+       unsigned int mon;
+       int state;
+       cstate_t s;
+
+       for (mon = 0; mon < avail_monitors; mon++) {
+               printf(_("Monitor \"%s\" (%d states) - Might overflow after %u "
+                        "s\n"),
+                       monitors[mon]->name, monitors[mon]->hw_states_num,
+                       monitors[mon]->overflow_s);
+
+               for (state = 0; state < monitors[mon]->hw_states_num; state++) {
+                       s = monitors[mon]->hw_states[state];
+                       /*
+                        * ToDo show more state capabilities:
+                        * percent, time (granlarity)
+                        */
+                       printf("%s\t[%c] -> %s\n", s.name, range_abbr[s.range],
+                              gettext(s.desc));
+               }
+       }
+}
+
+int fork_it(char **argv)
+{
+       int status;
+       unsigned int num;
+       unsigned long long timediff;
+       pid_t child_pid;
+       struct timespec start, end;
+
+       child_pid = fork();
+       clock_gettime(CLOCK_REALTIME, &start);
+
+       for (num = 0; num < avail_monitors; num++)
+               monitors[num]->start();
+
+       if (!child_pid) {
+               /* child */
+               execvp(argv[0], argv);
+       } else {
+               /* parent */
+               if (child_pid == -1) {
+                       perror("fork");
+                       exit(1);
+               }
+
+               signal(SIGINT, SIG_IGN);
+               signal(SIGQUIT, SIG_IGN);
+               if (waitpid(child_pid, &status, 0) == -1) {
+                       perror("wait");
+                       exit(1);
+               }
+       }
+       clock_gettime(CLOCK_REALTIME, &end);
+       for (num = 0; num < avail_monitors; num++)
+               monitors[num]->stop();
+
+       timediff = timespec_diff_us(start, end);
+       if (WIFEXITED(status))
+               printf(_("%s took %.5f seconds and exited with status %d\n"),
+                       argv[0], timediff / (1000.0 * 1000),
+                       WEXITSTATUS(status));
+       return 0;
+}
+
+int do_interval_measure(int i)
+{
+       unsigned int num;
+
+       for (num = 0; num < avail_monitors; num++) {
+               dprint("HW C-state residency monitor: %s - States: %d\n",
+                      monitors[num]->name, monitors[num]->hw_states_num);
+               monitors[num]->start();
+       }
+       sleep(i);
+       for (num = 0; num < avail_monitors; num++)
+               monitors[num]->stop();
+
+       return 0;
+}
+
+static void cmdline(int argc, char *argv[])
+{
+       int opt;
+       progname = basename(argv[0]);
+
+       while ((opt = getopt(argc, argv, "+hli:m:")) != -1) {
+               switch (opt) {
+               case 'h':
+                       monitor_help();
+                       exit(EXIT_SUCCESS);
+               case 'l':
+                       if (mode) {
+                               monitor_help();
+                               exit(EXIT_FAILURE);
+                       }
+                       mode = list;
+                       break;
+               case 'i':
+                       /* only allow -i with -m or no option */
+                       if (mode && mode != show) {
+                               monitor_help();
+                               exit(EXIT_FAILURE);
+                       }
+                       interval = atoi(optarg);
+                       break;
+               case 'm':
+                       if (mode) {
+                               monitor_help();
+                               exit(EXIT_FAILURE);
+                       }
+                       mode = show;
+                       show_monitors_param = optarg;
+                       break;
+               default:
+                       monitor_help();
+                       exit(EXIT_FAILURE);
+               }
+       }
+       if (!mode)
+               mode = show_all;
+}
+
+int cmd_monitor(int argc, char **argv)
+{
+       unsigned int num;
+       struct cpuidle_monitor *test_mon;
+       int cpu;
+
+       cmdline(argc, argv);
+       cpu_count = get_cpu_topology(&cpu_top);
+       if (cpu_count < 0) {
+               printf(_("Cannot read number of available processors\n"));
+               return EXIT_FAILURE;
+       }
+
+       dprint("System has up to %d CPU cores\n", cpu_count);
+
+       for (num = 0; all_monitors[num]; num++) {
+               dprint("Try to register: %s\n", all_monitors[num]->name);
+               test_mon = all_monitors[num]->do_register();
+               if (test_mon) {
+                       if (test_mon->needs_root && !run_as_root) {
+                               fprintf(stderr, _("Available monitor %s needs "
+                                         "root access\n"), test_mon->name);
+                               continue;
+                       }
+                       monitors[avail_monitors] = test_mon;
+                       dprint("%s registered\n", all_monitors[num]->name);
+                       avail_monitors++;
+               }
+       }
+
+       if (avail_monitors == 0) {
+               printf(_("No HW Cstate monitors found\n"));
+               return 1;
+       }
+
+       if (mode == list) {
+               list_monitors();
+               exit(EXIT_SUCCESS);
+       }
+
+       if (mode == show)
+               parse_monitor_param(show_monitors_param);
+
+       dprint("Packages: %d - Cores: %d - CPUs: %d\n",
+              cpu_top.pkgs, cpu_top.cores, cpu_count);
+
+       /*
+        * if any params left, it must be a command to fork
+        */
+       if (argc - optind)
+               fork_it(argv + optind);
+       else
+               do_interval_measure(interval);
+
+       /* ToDo: Topology parsing needs fixing first to do
+          this more generically */
+       if (cpu_top.pkgs > 1)
+               print_header(3);
+       else
+               print_header(1);
+
+       for (cpu = 0; cpu < cpu_count; cpu++) {
+               if (cpu_top.pkgs > 1)
+                       print_results(3, cpu);
+               else
+                       print_results(1, cpu);
+       }
+
+       for (num = 0; num < avail_monitors; num++)
+               monitors[num]->unregister();
+
+       cpu_topology_release(cpu_top);
+       return 0;
+}
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
new file mode 100644 (file)
index 0000000..9312ee1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ */
+
+#ifndef __CPUIDLE_INFO_HW__
+#define __CPUIDLE_INFO_HW__
+
+#include <stdarg.h>
+#include <time.h>
+
+#include "idle_monitor/idle_monitors.h"
+
+#define MONITORS_MAX 20
+#define MONITOR_NAME_LEN 20
+#define CSTATE_NAME_LEN 5
+#define CSTATE_DESC_LEN 60
+
+int cpu_count;
+
+/* Hard to define the right names ...: */
+enum power_range_e {
+       RANGE_THREAD,   /* Lowest in topology hierarcy, AMD: core, Intel: thread
+                          kernel sysfs: cpu */
+       RANGE_CORE,     /* AMD: unit, Intel: core, kernel_sysfs: core_id */
+       RANGE_PACKAGE,  /* Package, processor socket */
+       RANGE_MACHINE,  /* Machine, platform wide */
+       RANGE_MAX };
+
+typedef struct cstate {
+       int  id;
+       enum power_range_e range;
+       char name[CSTATE_NAME_LEN];
+       char desc[CSTATE_DESC_LEN];
+
+       /* either provide a percentage or a general count */
+       int (*get_count_percent)(unsigned int self_id, double *percent,
+                                unsigned int cpu);
+       int (*get_count)(unsigned int self_id, unsigned long long *count,
+                        unsigned int cpu);
+} cstate_t;
+
+struct cpuidle_monitor {
+       /* Name must not contain whitespaces */
+       char name[MONITOR_NAME_LEN];
+       int name_len;
+       int hw_states_num;
+       cstate_t *hw_states;
+       int (*start) (void);
+       int (*stop) (void);
+       struct cpuidle_monitor* (*do_register) (void);
+       void (*unregister)(void);
+       unsigned int overflow_s;
+       int needs_root;
+};
+
+extern long long timespec_diff_us(struct timespec start, struct timespec end);
+
+#define print_overflow_err(mes, ov)                                            \
+{                                                                              \
+       fprintf(stderr, gettext("Measure took %u seconds, but registers could " \
+                               "overflow at %u seconds, results "              \
+                               "could be inaccurate\n"), mes, ov);             \
+}
+
+#endif /* __CPUIDLE_INFO_HW__ */
diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.def b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
new file mode 100644 (file)
index 0000000..e3f8d9b
--- /dev/null
@@ -0,0 +1,7 @@
+#if defined(__i386__) || defined(__x86_64__)
+DEF(amd_fam14h)
+DEF(intel_nhm)
+DEF(intel_snb)
+DEF(mperf)
+#endif
+DEF(cpuidle_sysfs)
diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.h b/tools/power/cpupower/utils/idle_monitor/idle_monitors.h
new file mode 100644 (file)
index 0000000..4fcdeb1
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  Based on the idea from Michael Matz <matz@suse.de>
+ *
+ */
+
+#ifndef _CPUIDLE_IDLE_MONITORS_H_
+#define _CPUIDLE_IDLE_MONITORS_H_
+
+#define DEF(x) extern struct cpuidle_monitor x ##_monitor;
+#include "idle_monitors.def"
+#undef DEF
+extern struct cpuidle_monitor *all_monitors[];
+
+#endif /* _CPUIDLE_IDLE_MONITORS_H_ */
diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
new file mode 100644 (file)
index 0000000..63ca87a
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <cpufreq.h>
+
+#include "helpers/helpers.h"
+#include "idle_monitor/cpupower-monitor.h"
+
+#define MSR_APERF      0xE8
+#define MSR_MPERF      0xE7
+
+#define MSR_TSC        0x10
+
+enum mperf_id { C0 = 0, Cx, AVG_FREQ, MPERF_CSTATE_COUNT };
+
+static int mperf_get_count_percent(unsigned int self_id, double *percent,
+                                  unsigned int cpu);
+static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
+                               unsigned int cpu);
+
+static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
+       {
+               .name                   = "C0",
+               .desc                   = N_("Processor Core not idle"),
+               .id                     = C0,
+               .range                  = RANGE_THREAD,
+               .get_count_percent      = mperf_get_count_percent,
+       },
+       {
+               .name                   = "Cx",
+               .desc                   = N_("Processor Core in an idle state"),
+               .id                     = Cx,
+               .range                  = RANGE_THREAD,
+               .get_count_percent      = mperf_get_count_percent,
+       },
+
+       {
+               .name                   = "Freq",
+               .desc                   = N_("Average Frequency (including boost) in MHz"),
+               .id                     = AVG_FREQ,
+               .range                  = RANGE_THREAD,
+               .get_count              = mperf_get_count_freq,
+       },
+};
+
+static unsigned long long tsc_at_measure_start;
+static unsigned long long tsc_at_measure_end;
+static unsigned long max_frequency;
+static unsigned long long *mperf_previous_count;
+static unsigned long long *aperf_previous_count;
+static unsigned long long *mperf_current_count;
+static unsigned long long *aperf_current_count;
+/* valid flag for all CPUs. If a MSR read failed it will be zero */
+static int *is_valid;
+
+static int mperf_get_tsc(unsigned long long *tsc)
+{
+       return read_msr(0, MSR_TSC, tsc);
+}
+
+static int mperf_init_stats(unsigned int cpu)
+{
+       unsigned long long val;
+       int ret;
+
+       ret = read_msr(cpu, MSR_APERF, &val);
+       aperf_previous_count[cpu] = val;
+       ret |= read_msr(cpu, MSR_MPERF, &val);
+       mperf_previous_count[cpu] = val;
+       is_valid[cpu] = !ret;
+
+       return 0;
+}
+
+static int mperf_measure_stats(unsigned int cpu)
+{
+       unsigned long long val;
+       int ret;
+
+       ret = read_msr(cpu, MSR_APERF, &val);
+       aperf_current_count[cpu] = val;
+       ret |= read_msr(cpu, MSR_MPERF, &val);
+       mperf_current_count[cpu] = val;
+       is_valid[cpu] = !ret;
+
+       return 0;
+}
+
+/*
+ * get_average_perf()
+ *
+ * Returns the average performance (also considers boosted frequencies)
+ *
+ * Input:
+ *   aperf_diff: Difference of the aperf register over a time period
+ *   mperf_diff: Difference of the mperf register over the same time period
+ *   max_freq:   Maximum frequency (P0)
+ *
+ * Returns:
+ *   Average performance over the time period
+ */
+static unsigned long get_average_perf(unsigned long long aperf_diff,
+                                     unsigned long long mperf_diff)
+{
+       unsigned int perf_percent = 0;
+       if (((unsigned long)(-1) / 100) < aperf_diff) {
+               int shift_count = 7;
+               aperf_diff >>= shift_count;
+               mperf_diff >>= shift_count;
+       }
+       perf_percent = (aperf_diff * 100) / mperf_diff;
+       return (max_frequency * perf_percent) / 100;
+}
+
+static int mperf_get_count_percent(unsigned int id, double *percent,
+                                  unsigned int cpu)
+{
+       unsigned long long aperf_diff, mperf_diff, tsc_diff;
+
+       if (!is_valid[cpu])
+               return -1;
+
+       if (id != C0 && id != Cx)
+               return -1;
+
+       mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
+       aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
+       tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
+
+       *percent = 100.0 * mperf_diff / tsc_diff;
+       dprint("%s: mperf_diff: %llu, tsc_diff: %llu\n",
+              mperf_cstates[id].name, mperf_diff, tsc_diff);
+
+       if (id == Cx)
+               *percent = 100.0 - *percent;
+
+       dprint("%s: previous: %llu - current: %llu - (%u)\n",
+               mperf_cstates[id].name, mperf_diff, aperf_diff, cpu);
+       dprint("%s: %f\n", mperf_cstates[id].name, *percent);
+       return 0;
+}
+
+static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
+                               unsigned int cpu)
+{
+       unsigned long long aperf_diff, mperf_diff;
+
+       if (id != AVG_FREQ)
+               return 1;
+
+       if (!is_valid[cpu])
+               return -1;
+
+       mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
+       aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
+
+       /* Return MHz for now, might want to return KHz if column width is more
+          generic */
+       *count = get_average_perf(aperf_diff, mperf_diff) / 1000;
+       dprint("%s: %llu\n", mperf_cstates[id].name, *count);
+
+       return 0;
+}
+
+static int mperf_start(void)
+{
+       int cpu;
+       unsigned long long dbg;
+
+       mperf_get_tsc(&tsc_at_measure_start);
+
+       for (cpu = 0; cpu < cpu_count; cpu++)
+               mperf_init_stats(cpu);
+
+       mperf_get_tsc(&dbg);
+       dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
+       return 0;
+}
+
+static int mperf_stop(void)
+{
+       unsigned long long dbg;
+       int cpu;
+
+       mperf_get_tsc(&tsc_at_measure_end);
+
+       for (cpu = 0; cpu < cpu_count; cpu++)
+               mperf_measure_stats(cpu);
+
+       mperf_get_tsc(&dbg);
+       dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
+
+       return 0;
+}
+
+struct cpuidle_monitor mperf_monitor;
+
+struct cpuidle_monitor *mperf_register(void)
+{
+       unsigned long min;
+
+       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
+               return NULL;
+
+       /* Assume min/max all the same on all cores */
+       if (cpufreq_get_hardware_limits(0, &min, &max_frequency)) {
+               dprint("Cannot retrieve max freq from cpufreq kernel "
+                      "subsystem\n");
+               return NULL;
+       }
+
+       /* Free this at program termination */
+       is_valid = calloc(cpu_count, sizeof(int));
+       mperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
+       aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
+       mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
+       aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
+
+       mperf_monitor.name_len = strlen(mperf_monitor.name);
+       return &mperf_monitor;
+}
+
+void mperf_unregister(void)
+{
+       free(mperf_previous_count);
+       free(aperf_previous_count);
+       free(mperf_current_count);
+       free(aperf_current_count);
+       free(is_valid);
+}
+
+struct cpuidle_monitor mperf_monitor = {
+       .name                   = "Mperf",
+       .hw_states_num          = MPERF_CSTATE_COUNT,
+       .hw_states              = mperf_cstates,
+       .start                  = mperf_start,
+       .stop                   = mperf_stop,
+       .do_register            = mperf_register,
+       .unregister             = mperf_unregister,
+       .needs_root             = 1,
+       .overflow_s             = 922000000 /* 922337203 seconds TSC overflow
+                                              at 20GHz */
+};
+#endif /* #if defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c
new file mode 100644 (file)
index 0000000..d2a91dd
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  Based on Len Brown's <lenb@kernel.org> turbostat tool.
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "helpers/helpers.h"
+#include "idle_monitor/cpupower-monitor.h"
+
+#define MSR_PKG_C3_RESIDENCY   0x3F8
+#define MSR_PKG_C6_RESIDENCY   0x3F9
+#define MSR_CORE_C3_RESIDENCY  0x3FC
+#define MSR_CORE_C6_RESIDENCY  0x3FD
+
+#define MSR_TSC        0x10
+
+#define NHM_CSTATE_COUNT 4
+
+enum intel_nhm_id { C3 = 0, C6, PC3, PC6, TSC = 0xFFFF };
+
+static int nhm_get_count_percent(unsigned int self_id, double *percent,
+                                unsigned int cpu);
+
+static cstate_t nhm_cstates[NHM_CSTATE_COUNT] = {
+       {
+               .name                   = "C3",
+               .desc                   = N_("Processor Core C3"),
+               .id                     = C3,
+               .range                  = RANGE_CORE,
+               .get_count_percent      = nhm_get_count_percent,
+       },
+       {
+               .name                   = "C6",
+               .desc                   = N_("Processor Core C6"),
+               .id                     = C6,
+               .range                  = RANGE_CORE,
+               .get_count_percent      = nhm_get_count_percent,
+       },
+
+       {
+               .name                   = "PC3",
+               .desc                   = N_("Processor Package C3"),
+               .id                     = PC3,
+               .range                  = RANGE_PACKAGE,
+               .get_count_percent      = nhm_get_count_percent,
+       },
+       {
+               .name                   = "PC6",
+               .desc                   = N_("Processor Package C6"),
+               .id                     = PC6,
+               .range                  = RANGE_PACKAGE,
+               .get_count_percent      = nhm_get_count_percent,
+       },
+};
+
+static unsigned long long tsc_at_measure_start;
+static unsigned long long tsc_at_measure_end;
+static unsigned long long *previous_count[NHM_CSTATE_COUNT];
+static unsigned long long *current_count[NHM_CSTATE_COUNT];
+/* valid flag for all CPUs. If a MSR read failed it will be zero */
+static int *is_valid;
+
+static int nhm_get_count(enum intel_nhm_id id, unsigned long long *val,
+                       unsigned int cpu)
+{
+       int msr;
+
+       switch (id) {
+       case C3:
+               msr = MSR_CORE_C3_RESIDENCY;
+               break;
+       case C6:
+               msr = MSR_CORE_C6_RESIDENCY;
+               break;
+       case PC3:
+               msr = MSR_PKG_C3_RESIDENCY;
+               break;
+       case PC6:
+               msr = MSR_PKG_C6_RESIDENCY;
+               break;
+       case TSC:
+               msr = MSR_TSC;
+               break;
+       default:
+               return -1;
+       };
+       if (read_msr(cpu, msr, val))
+               return -1;
+
+       return 0;
+}
+
+static int nhm_get_count_percent(unsigned int id, double *percent,
+                                unsigned int cpu)
+{
+       *percent = 0.0;
+
+       if (!is_valid[cpu])
+               return -1;
+
+       *percent = (100.0 *
+               (current_count[id][cpu] - previous_count[id][cpu])) /
+               (tsc_at_measure_end - tsc_at_measure_start);
+
+       dprint("%s: previous: %llu - current: %llu - (%u)\n",
+               nhm_cstates[id].name, previous_count[id][cpu],
+               current_count[id][cpu], cpu);
+
+       dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n",
+              nhm_cstates[id].name,
+              (unsigned long long) tsc_at_measure_end - tsc_at_measure_start,
+              current_count[id][cpu] - previous_count[id][cpu],
+              *percent, cpu);
+
+       return 0;
+}
+
+static int nhm_start(void)
+{
+       int num, cpu;
+       unsigned long long dbg, val;
+
+       nhm_get_count(TSC, &tsc_at_measure_start, 0);
+
+       for (num = 0; num < NHM_CSTATE_COUNT; num++) {
+               for (cpu = 0; cpu < cpu_count; cpu++) {
+                       is_valid[cpu] = !nhm_get_count(num, &val, cpu);
+                       previous_count[num][cpu] = val;
+               }
+       }
+       nhm_get_count(TSC, &dbg, 0);
+       dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
+       return 0;
+}
+
+static int nhm_stop(void)
+{
+       unsigned long long val;
+       unsigned long long dbg;
+       int num, cpu;
+
+       nhm_get_count(TSC, &tsc_at_measure_end, 0);
+
+       for (num = 0; num < NHM_CSTATE_COUNT; num++) {
+               for (cpu = 0; cpu < cpu_count; cpu++) {
+                       is_valid[cpu] = !nhm_get_count(num, &val, cpu);
+                       current_count[num][cpu] = val;
+               }
+       }
+       nhm_get_count(TSC, &dbg, 0);
+       dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
+
+       return 0;
+}
+
+struct cpuidle_monitor intel_nhm_monitor;
+
+struct cpuidle_monitor *intel_nhm_register(void)
+{
+       int num;
+
+       if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
+               return NULL;
+
+       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC))
+               return NULL;
+
+       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
+               return NULL;
+
+       /* Free this at program termination */
+       is_valid = calloc(cpu_count, sizeof(int));
+       for (num = 0; num < NHM_CSTATE_COUNT; num++) {
+               previous_count[num] = calloc(cpu_count,
+                                       sizeof(unsigned long long));
+               current_count[num]  = calloc(cpu_count,
+                                       sizeof(unsigned long long));
+       }
+
+       intel_nhm_monitor.name_len = strlen(intel_nhm_monitor.name);
+       return &intel_nhm_monitor;
+}
+
+void intel_nhm_unregister(void)
+{
+       int num;
+
+       for (num = 0; num < NHM_CSTATE_COUNT; num++) {
+               free(previous_count[num]);
+               free(current_count[num]);
+       }
+       free(is_valid);
+}
+
+struct cpuidle_monitor intel_nhm_monitor = {
+       .name                   = "Nehalem",
+       .hw_states_num          = NHM_CSTATE_COUNT,
+       .hw_states              = nhm_cstates,
+       .start                  = nhm_start,
+       .stop                   = nhm_stop,
+       .do_register            = intel_nhm_register,
+       .unregister             = intel_nhm_unregister,
+       .needs_root             = 1,
+       .overflow_s             = 922000000 /* 922337203 seconds TSC overflow
+                                              at 20GHz */
+};
+#endif
diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
new file mode 100644 (file)
index 0000000..a1bc07c
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  Based on Len Brown's <lenb@kernel.org> turbostat tool.
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "helpers/helpers.h"
+#include "idle_monitor/cpupower-monitor.h"
+
+#define MSR_PKG_C2_RESIDENCY   0x60D
+#define MSR_PKG_C7_RESIDENCY   0x3FA
+#define MSR_CORE_C7_RESIDENCY  0x3FE
+
+#define MSR_TSC        0x10
+
+enum intel_snb_id { C7 = 0, PC2, PC7, SNB_CSTATE_COUNT, TSC = 0xFFFF };
+
+static int snb_get_count_percent(unsigned int self_id, double *percent,
+                                unsigned int cpu);
+
+static cstate_t snb_cstates[SNB_CSTATE_COUNT] = {
+       {
+               .name                   = "C7",
+               .desc                   = N_("Processor Core C7"),
+               .id                     = C7,
+               .range                  = RANGE_CORE,
+               .get_count_percent      = snb_get_count_percent,
+       },
+       {
+               .name                   = "PC2",
+               .desc                   = N_("Processor Package C2"),
+               .id                     = PC2,
+               .range                  = RANGE_PACKAGE,
+               .get_count_percent      = snb_get_count_percent,
+       },
+       {
+               .name                   = "PC7",
+               .desc                   = N_("Processor Package C7"),
+               .id                     = PC7,
+               .range                  = RANGE_PACKAGE,
+               .get_count_percent      = snb_get_count_percent,
+       },
+};
+
+static unsigned long long tsc_at_measure_start;
+static unsigned long long tsc_at_measure_end;
+static unsigned long long *previous_count[SNB_CSTATE_COUNT];
+static unsigned long long *current_count[SNB_CSTATE_COUNT];
+/* valid flag for all CPUs. If a MSR read failed it will be zero */
+static int *is_valid;
+
+static int snb_get_count(enum intel_snb_id id, unsigned long long *val,
+                       unsigned int cpu)
+{
+       int msr;
+
+       switch (id) {
+       case C7:
+               msr = MSR_CORE_C7_RESIDENCY;
+               break;
+       case PC2:
+               msr = MSR_PKG_C2_RESIDENCY;
+               break;
+       case PC7:
+               msr = MSR_PKG_C7_RESIDENCY;
+               break;
+       case TSC:
+               msr = MSR_TSC;
+               break;
+       default:
+               return -1;
+       };
+       if (read_msr(cpu, msr, val))
+               return -1;
+       return 0;
+}
+
+static int snb_get_count_percent(unsigned int id, double *percent,
+                                unsigned int cpu)
+{
+       *percent = 0.0;
+
+       if (!is_valid[cpu])
+               return -1;
+
+       *percent = (100.0 *
+               (current_count[id][cpu] - previous_count[id][cpu])) /
+               (tsc_at_measure_end - tsc_at_measure_start);
+
+       dprint("%s: previous: %llu - current: %llu - (%u)\n",
+               snb_cstates[id].name, previous_count[id][cpu],
+               current_count[id][cpu], cpu);
+
+       dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n",
+              snb_cstates[id].name,
+              (unsigned long long) tsc_at_measure_end - tsc_at_measure_start,
+              current_count[id][cpu] - previous_count[id][cpu],
+              *percent, cpu);
+
+       return 0;
+}
+
+static int snb_start(void)
+{
+       int num, cpu;
+       unsigned long long val;
+
+       for (num = 0; num < SNB_CSTATE_COUNT; num++) {
+               for (cpu = 0; cpu < cpu_count; cpu++) {
+                       snb_get_count(num, &val, cpu);
+                       previous_count[num][cpu] = val;
+               }
+       }
+       snb_get_count(TSC, &tsc_at_measure_start, 0);
+       return 0;
+}
+
+static int snb_stop(void)
+{
+       unsigned long long val;
+       int num, cpu;
+
+       snb_get_count(TSC, &tsc_at_measure_end, 0);
+
+       for (num = 0; num < SNB_CSTATE_COUNT; num++) {
+               for (cpu = 0; cpu < cpu_count; cpu++) {
+                       is_valid[cpu] = !snb_get_count(num, &val, cpu);
+                       current_count[num][cpu] = val;
+               }
+       }
+       return 0;
+}
+
+struct cpuidle_monitor intel_snb_monitor;
+
+static struct cpuidle_monitor *snb_register(void)
+{
+       int num;
+
+       if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL
+           || cpupower_cpu_info.family != 6)
+               return NULL;
+
+       if (cpupower_cpu_info.model != 0x2A
+           && cpupower_cpu_info.model != 0x2D)
+               return NULL;
+
+       is_valid = calloc(cpu_count, sizeof(int));
+       for (num = 0; num < SNB_CSTATE_COUNT; num++) {
+               previous_count[num] = calloc(cpu_count,
+                                       sizeof(unsigned long long));
+               current_count[num]  = calloc(cpu_count,
+                                       sizeof(unsigned long long));
+       }
+       intel_snb_monitor.name_len = strlen(intel_snb_monitor.name);
+       return &intel_snb_monitor;
+}
+
+void snb_unregister(void)
+{
+       int num;
+       free(is_valid);
+       for (num = 0; num < SNB_CSTATE_COUNT; num++) {
+               free(previous_count[num]);
+               free(current_count[num]);
+       }
+}
+
+struct cpuidle_monitor intel_snb_monitor = {
+       .name                   = "SandyBridge",
+       .hw_states              = snb_cstates,
+       .hw_states_num          = SNB_CSTATE_COUNT,
+       .start                  = snb_start,
+       .stop                   = snb_stop,
+       .do_register            = snb_register,
+       .unregister             = snb_unregister,
+       .needs_root             = 1,
+       .overflow_s             = 922000000 /* 922337203 seconds TSC overflow
+                                              at 20GHz */
+};
+#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/version-gen.sh b/tools/power/cpupower/utils/version-gen.sh
new file mode 100755 (executable)
index 0000000..5ec41c5
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Script which prints out the version to use for building cpupowerutils.
+# Must be called from tools/power/cpupower/
+# 
+# Heavily based on tools/perf/util/PERF-VERSION-GEN .
+
+LF='
+'
+
+# First check if there is a .git to get the version from git describe
+# otherwise try to get the version from the kernel makefile
+if test -d ../../../.git -o -f ../../../.git &&
+       VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
+       case "$VN" in
+       *$LF*) (exit 1) ;;
+       v[0-9]*)
+               git update-index -q --refresh
+               test -z "$(git diff-index --name-only HEAD --)" ||
+               VN="$VN-dirty" ;;
+       esac
+then
+       VN=$(echo "$VN" | sed -e 's/-/./g');
+else
+       eval $(grep '^VERSION[[:space:]]*=' ../../../Makefile|tr -d ' ')
+       eval $(grep '^PATCHLEVEL[[:space:]]*=' ../../../Makefile|tr -d ' ')
+       eval $(grep '^SUBLEVEL[[:space:]]*=' ../../../Makefile|tr -d ' ')
+       eval $(grep '^EXTRAVERSION[[:space:]]*=' ../../../Makefile|tr -d ' ')
+
+       VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}"
+fi
+
+VN=$(expr "$VN" : v*'\(.*\)')
+
+echo $VN