提交 eeb91e4f 编写于 作者: L Linus Torvalds

Merge tag 'pm+acpi-3.15-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more ACPI and power management fixes and updates from Rafael Wysocki:
 "This is PM and ACPI material that has emerged over the last two weeks
  and one fix for a CPU hotplug regression introduced by the recent CPU
  hotplug notifiers registration series.

  Included are intel_idle and turbostat updates from Len Brown (these
  have been in linux-next for quite some time), a new cpufreq driver for
  powernv (that might spend some more time in linux-next, but BenH was
  asking me so nicely to push it for 3.15 that I couldn't resist), some
  cpufreq fixes and cleanups (including fixes for some silly breakage in
  a couple of cpufreq drivers introduced during the 3.14 cycle),
  assorted ACPI cleanups, wakeup framework documentation fixes, a new
  sysfs attribute for cpuidle and a new command line argument for power
  domains diagnostics.

  Specifics:

   - Fix for a recently introduced CPU hotplug regression in ARM KVM
     from Ming Lei.

   - Fixes for breakage in the at32ap, loongson2_cpufreq, and unicore32
     cpufreq drivers introduced during the 3.14 cycle (-stable material)
     from Chen Gang and Viresh Kumar.

   - New powernv cpufreq driver from Vaidyanathan Srinivasan, with bits
     from Gautham R Shenoy and Srivatsa S Bhat.

   - Exynos cpufreq driver fix preventing it from being included into
     multiplatform builds that aren't supported by it from Sachin Kamat.

   - cpufreq cleanups related to the usage of the driver_data field in
     struct cpufreq_frequency_table from Viresh Kumar.

   - cpufreq ppc driver cleanup from Sachin Kamat.

   - Intel BayTrail support for intel_idle and ACPI idle from Len Brown.

   - Intel CPU model 54 (Atom N2000 series) support for intel_idle from
     Jan Kiszka.

   - intel_idle fix for Intel Ivy Town residency targets from Len Brown.

   - turbostat updates (Intel Broadwell support and output cleanups)
     from Len Brown.

   - New cpuidle sysfs attribute for exporting C-states' target
     residency information to user space from Daniel Lezcano.

   - New kernel command line argument to prevent power domains enabled
     by the bootloader from being turned off even if they are not in use
     (for diagnostics purposes) from Tushar Behera.

   - Fixes for wakeup sysfs attributes documentation from Geert
     Uytterhoeven.

   - New ACPI video blacklist entry for ThinkPad Helix from Stephen
     Chandler Paul.

   - Assorted ACPI cleanups and a Kconfig help update from Jonghwan
     Choi, Zhihui Zhang, Hanjun Guo"

* tag 'pm+acpi-3.15-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (28 commits)
  ACPI: Update the ACPI spec information in Kconfig
  arm, kvm: fix double lock on cpu_add_remove_lock
  cpuidle: sysfs: Export target residency information
  cpufreq: ppc: Remove duplicate inclusion of fsl_soc.h
  cpufreq: create another field .flags in cpufreq_frequency_table
  cpufreq: use kzalloc() to allocate memory for cpufreq_frequency_table
  cpufreq: don't print value of .driver_data from core
  cpufreq: ia64: don't set .driver_data to index
  cpufreq: powernv: Select CPUFreq related Kconfig options for powernv
  cpufreq: powernv: Use cpufreq_frequency_table.driver_data to store pstate ids
  cpufreq: powernv: cpufreq driver for powernv platform
  cpufreq: at32ap: don't declare local variable as static
  cpufreq: loongson2_cpufreq: don't declare local variable as static
  cpufreq: unicore32: fix typo issue for 'clk'
  cpufreq: exynos: Disable on multiplatform build
  PM / wakeup: Correct presence vs. emptiness of wakeup_* attributes
  PM / domains: Add pd_ignore_unused to keep power domains enabled
  ACPI / dock: Drop dock_device_ids[] table
  ACPI / video: Favor native backlight interface for ThinkPad Helix
  ACPI / thermal: Fix wrong variable usage in debug statement
  ...
......@@ -83,8 +83,10 @@ Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
Description:
The /sys/devices/.../wakeup_count attribute contains the number
of signaled wakeup events associated with the device. This
attribute is read-only. If the device is not enabled to wake up
attribute is read-only. If the device is not capable to wake up
the system from sleep states, this attribute is not present.
If the device is not enabled to wake up the system from sleep
states, this attribute is empty.
What: /sys/devices/.../power/wakeup_active_count
Date: September 2010
......@@ -93,8 +95,10 @@ Description:
The /sys/devices/.../wakeup_active_count attribute contains the
number of times the processing of wakeup events associated with
the device was completed (at the kernel level). This attribute
is read-only. If the device is not enabled to wake up the
system from sleep states, this attribute is not present.
is read-only. If the device is not capable to wake up the
system from sleep states, this attribute is not present. If
the device is not enabled to wake up the system from sleep
states, this attribute is empty.
What: /sys/devices/.../power/wakeup_abort_count
Date: February 2012
......@@ -104,8 +108,9 @@ Description:
number of times the processing of a wakeup event associated with
the device might have aborted system transition into a sleep
state in progress. This attribute is read-only. If the device
is not enabled to wake up the system from sleep states, this
attribute is not present.
is not capable to wake up the system from sleep states, this
attribute is not present. If the device is not enabled to wake
up the system from sleep states, this attribute is empty.
What: /sys/devices/.../power/wakeup_expire_count
Date: February 2012
......@@ -114,8 +119,10 @@ Description:
The /sys/devices/.../wakeup_expire_count attribute contains the
number of times a wakeup event associated with the device has
been reported with a timeout that expired. This attribute is
read-only. If the device is not enabled to wake up the system
from sleep states, this attribute is not present.
read-only. If the device is not capable to wake up the system
from sleep states, this attribute is not present. If the
device is not enabled to wake up the system from sleep states,
this attribute is empty.
What: /sys/devices/.../power/wakeup_active
Date: September 2010
......@@ -124,8 +131,10 @@ Description:
The /sys/devices/.../wakeup_active attribute contains either 1,
or 0, depending on whether or not a wakeup event associated with
the device is being processed (1). This attribute is read-only.
If the device is not enabled to wake up the system from sleep
states, this attribute is not present.
If the device is not capable to wake up the system from sleep
states, this attribute is not present. If the device is not
enabled to wake up the system from sleep states, this attribute
is empty.
What: /sys/devices/.../power/wakeup_total_time_ms
Date: September 2010
......@@ -134,8 +143,9 @@ Description:
The /sys/devices/.../wakeup_total_time_ms attribute contains
the total time of processing wakeup events associated with the
device, in milliseconds. This attribute is read-only. If the
device is not enabled to wake up the system from sleep states,
this attribute is not present.
device is not capable to wake up the system from sleep states,
this attribute is not present. If the device is not enabled to
wake up the system from sleep states, this attribute is empty.
What: /sys/devices/.../power/wakeup_max_time_ms
Date: September 2010
......@@ -144,8 +154,10 @@ Description:
The /sys/devices/.../wakeup_max_time_ms attribute contains
the maximum time of processing a single wakeup event associated
with the device, in milliseconds. This attribute is read-only.
If the device is not enabled to wake up the system from sleep
states, this attribute is not present.
If the device is not capable to wake up the system from sleep
states, this attribute is not present. If the device is not
enabled to wake up the system from sleep states, this attribute
is empty.
What: /sys/devices/.../power/wakeup_last_time_ms
Date: September 2010
......@@ -156,7 +168,8 @@ Description:
signaling the last wakeup event associated with the device, in
milliseconds. This attribute is read-only. If the device is
not enabled to wake up the system from sleep states, this
attribute is not present.
attribute is not present. If the device is not enabled to wake
up the system from sleep states, this attribute is empty.
What: /sys/devices/.../power/wakeup_prevent_sleep_time_ms
Date: February 2012
......@@ -165,9 +178,10 @@ Description:
The /sys/devices/.../wakeup_prevent_sleep_time_ms attribute
contains the total time the device has been preventing
opportunistic transitions to sleep states from occurring.
This attribute is read-only. If the device is not enabled to
This attribute is read-only. If the device is not capable to
wake up the system from sleep states, this attribute is not
present.
present. If the device is not enabled to wake up the system
from sleep states, this attribute is empty.
What: /sys/devices/.../power/autosuspend_delay_ms
Date: September 2010
......
......@@ -2563,6 +2563,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
pcmv= [HW,PCMCIA] BadgePAD 4
pd_ignore_unused
[PM]
Keep all power-domains already enabled by bootloader on,
even if no driver has claimed them. This is useful
for debug and development, but should not be
needed on a platform with proper driver support.
pd. [PARIDE]
See Documentation/blockdev/paride.txt.
......
......@@ -28,16 +28,16 @@ enum {
};
struct cpufreq_frequency_table loongson2_clockmod_table[] = {
{DC_RESV, CPUFREQ_ENTRY_INVALID},
{DC_ZERO, CPUFREQ_ENTRY_INVALID},
{DC_25PT, 0},
{DC_37PT, 0},
{DC_50PT, 0},
{DC_62PT, 0},
{DC_75PT, 0},
{DC_87PT, 0},
{DC_DISABLE, 0},
{DC_RESV, CPUFREQ_TABLE_END},
{0, DC_RESV, CPUFREQ_ENTRY_INVALID},
{0, DC_ZERO, CPUFREQ_ENTRY_INVALID},
{0, DC_25PT, 0},
{0, DC_37PT, 0},
{0, DC_50PT, 0},
{0, DC_62PT, 0},
{0, DC_75PT, 0},
{0, DC_87PT, 0},
{0, DC_DISABLE, 0},
{0, DC_RESV, CPUFREQ_TABLE_END},
};
EXPORT_SYMBOL_GPL(loongson2_clockmod_table);
......
......@@ -306,3 +306,4 @@ CONFIG_KVM_BOOK3S_64=m
CONFIG_KVM_BOOK3S_64_HV=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
......@@ -301,3 +301,4 @@ CONFIG_CRYPTO_LZO=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_DEV_NX=y
CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
......@@ -272,6 +272,10 @@
#define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */
#define SPRN_IC 0x350 /* Virtual Instruction Count */
#define SPRN_VTB 0x351 /* Virtual Time Base */
#define SPRN_PMICR 0x354 /* Power Management Idle Control Reg */
#define SPRN_PMSR 0x355 /* Power Management Status Reg */
#define SPRN_PMCR 0x374 /* Power Management Control Register */
/* HFSCR and FSCR bit numbers are the same */
#define FSCR_TAR_LG 8 /* Enable Target Address Register */
#define FSCR_EBB_LG 7 /* Enable Event Based Branching */
......
......@@ -11,6 +11,12 @@ config PPC_POWERNV
select PPC_UDBG_16550
select PPC_SCOM
select ARCH_RANDOM
select CPU_FREQ
select CPU_FREQ_GOV_PERFORMANCE
select CPU_FREQ_GOV_POWERSAVE
select CPU_FREQ_GOV_USERSPACE
select CPU_FREQ_GOV_ONDEMAND
select CPU_FREQ_GOV_CONSERVATIVE
default y
config PPC_POWERNV_RTAS
......
......@@ -87,7 +87,9 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
retval = 0;
if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) {
/* If the HW does not support any sub-states in this C-state */
if (num_cstate_subtype == 0) {
pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", cx->address, edx_part);
retval = -1;
goto out;
}
......
......@@ -31,10 +31,14 @@ menuconfig ACPI
ACPI CA, see:
<http://acpica.org/>
ACPI is an open industry specification co-developed by
Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.
ACPI is an open industry specification originally co-developed by
Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba. Currently,
it is developed by the ACPI Specification Working Group (ASWG) under
the UEFI Forum and any UEFI member can join the ASWG and contribute
to the ACPI specification.
The specification is available at:
<http://www.acpi.info>
<http://www.uefi.org/acpi/specs>
if ACPI
......
......@@ -51,12 +51,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
" the driver to wait for userspace to write the undock sysfs file "
" before undocking");
static const struct acpi_device_id dock_device_ids[] = {
{"LNXDOCK", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, dock_device_ids);
struct dock_station {
acpi_handle handle;
unsigned long last_dock_time;
......
......@@ -1219,10 +1219,9 @@ acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
{
struct semaphore *sem = NULL;
sem = acpi_os_allocate(sizeof(struct semaphore));
sem = acpi_os_allocate_zeroed(sizeof(struct semaphore));
if (!sem)
return AE_NO_MEMORY;
memset(sem, 0, sizeof(struct semaphore));
sema_init(sem, initial_units);
......
......@@ -344,7 +344,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
tz->trips.hot.flags.valid = 1;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Found hot threshold [%lu]\n",
tz->trips.critical.temperature));
tz->trips.hot.temperature));
}
}
......
......@@ -164,11 +164,10 @@ acpi_extract_package(union acpi_object *package,
* Validate output buffer.
*/
if (buffer->length == ACPI_ALLOCATE_BUFFER) {
buffer->pointer = ACPI_ALLOCATE(size_required);
buffer->pointer = ACPI_ALLOCATE_ZEROED(size_required);
if (!buffer->pointer)
return AE_NO_MEMORY;
buffer->length = size_required;
memset(buffer->pointer, 0, size_required);
} else {
if (buffer->length < size_required) {
buffer->length = size_required;
......
......@@ -487,6 +487,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga 13"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "Thinkpad Helix",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "Dell Inspiron 7520",
......
......@@ -705,6 +705,14 @@ static int pm_genpd_runtime_resume(struct device *dev)
return 0;
}
static bool pd_ignore_unused;
static int __init pd_ignore_unused_setup(char *__unused)
{
pd_ignore_unused = true;
return 1;
}
__setup("pd_ignore_unused", pd_ignore_unused_setup);
/**
* pm_genpd_poweroff_unused - Power off all PM domains with no devices in use.
*/
......@@ -712,6 +720,11 @@ void pm_genpd_poweroff_unused(void)
{
struct generic_pm_domain *genpd;
if (pd_ignore_unused) {
pr_warn("genpd: Not disabling unused power domains\n");
return;
}
mutex_lock(&gpd_list_lock);
list_for_each_entry(genpd, &gpd_list, gpd_list_node)
......
......@@ -30,7 +30,7 @@ config ARM_EXYNOS_CPUFREQ
config ARM_EXYNOS4210_CPUFREQ
bool "SAMSUNG EXYNOS4210"
depends on CPU_EXYNOS4210
depends on CPU_EXYNOS4210 && !ARCH_MULTIPLATFORM
default y
select ARM_EXYNOS_CPUFREQ
help
......@@ -41,7 +41,7 @@ config ARM_EXYNOS4210_CPUFREQ
config ARM_EXYNOS4X12_CPUFREQ
bool "SAMSUNG EXYNOS4x12"
depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412)
depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
default y
select ARM_EXYNOS_CPUFREQ
help
......@@ -52,7 +52,7 @@ config ARM_EXYNOS4X12_CPUFREQ
config ARM_EXYNOS5250_CPUFREQ
bool "SAMSUNG EXYNOS5250"
depends on SOC_EXYNOS5250
depends on SOC_EXYNOS5250 && !ARCH_MULTIPLATFORM
default y
select ARM_EXYNOS_CPUFREQ
help
......
......@@ -54,3 +54,11 @@ config PPC_PASEMI_CPUFREQ
help
This adds the support for frequency switching on PA Semi
PWRficient processors.
config POWERNV_CPUFREQ
tristate "CPU frequency scaling for IBM POWERNV platform"
depends on PPC_POWERNV
default y
help
This adds support for CPU frequency switching on IBM POWERNV
platform
......@@ -86,6 +86,7 @@ obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o
obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o
obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o
obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o
obj-$(CONFIG_POWERNV_CPUFREQ) += powernv-cpufreq.o
##################################################################################
# Other platform drivers
......
......@@ -754,7 +754,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto err_unreg;
}
data->freq_table = kmalloc(sizeof(*data->freq_table) *
data->freq_table = kzalloc(sizeof(*data->freq_table) *
(perf->state_count+1), GFP_KERNEL);
if (!data->freq_table) {
result = -ENOMEM;
......
......@@ -52,7 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
{
unsigned int frequency, rate, min_freq;
static struct clk *cpuclk;
struct clk *cpuclk;
int retval, steps, i;
if (policy->cpu != 0)
......
......@@ -15,9 +15,9 @@ static struct notifier_block cris_sdram_freq_notifier_block = {
};
static struct cpufreq_frequency_table cris_freq_table[] = {
{0x01, 6000},
{0x02, 200000},
{0, CPUFREQ_TABLE_END},
{0, 0x01, 6000},
{0, 0x02, 200000},
{0, 0, CPUFREQ_TABLE_END},
};
static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
......
......@@ -15,9 +15,9 @@ static struct notifier_block cris_sdram_freq_notifier_block = {
};
static struct cpufreq_frequency_table cris_freq_table[] = {
{0x01, 6000},
{0x02, 200000},
{0, CPUFREQ_TABLE_END},
{0, 0x01, 6000},
{0, 0x02, 200000},
{0, 0, CPUFREQ_TABLE_END},
};
static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
......
......@@ -56,15 +56,15 @@ static struct s_elan_multiplier elan_multiplier[] = {
};
static struct cpufreq_frequency_table elanfreq_table[] = {
{0, 1000},
{1, 2000},
{2, 4000},
{3, 8000},
{4, 16000},
{5, 33000},
{6, 66000},
{7, 99000},
{0, CPUFREQ_TABLE_END},
{0, 0, 1000},
{0, 1, 2000},
{0, 2, 4000},
{0, 3, 8000},
{0, 4, 16000},
{0, 5, 33000},
{0, 6, 66000},
{0, 7, 99000},
{0, 0, CPUFREQ_TABLE_END},
};
......
......@@ -29,12 +29,12 @@ static unsigned int exynos4210_volt_table[] = {
};
static struct cpufreq_frequency_table exynos4210_freq_table[] = {
{L0, 1200 * 1000},
{L1, 1000 * 1000},
{L2, 800 * 1000},
{L3, 500 * 1000},
{L4, 200 * 1000},
{0, CPUFREQ_TABLE_END},
{0, L0, 1200 * 1000},
{0, L1, 1000 * 1000},
{0, L2, 800 * 1000},
{0, L3, 500 * 1000},
{0, L4, 200 * 1000},
{0, 0, CPUFREQ_TABLE_END},
};
static struct apll_freq apll_freq_4210[] = {
......
......@@ -30,21 +30,21 @@ static unsigned int exynos4x12_volt_table[] = {
};
static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
{CPUFREQ_BOOST_FREQ, 1500 * 1000},
{L1, 1400 * 1000},
{L2, 1300 * 1000},
{L3, 1200 * 1000},
{L4, 1100 * 1000},
{L5, 1000 * 1000},
{L6, 900 * 1000},
{L7, 800 * 1000},
{L8, 700 * 1000},
{L9, 600 * 1000},
{L10, 500 * 1000},
{L11, 400 * 1000},
{L12, 300 * 1000},
{L13, 200 * 1000},
{0, CPUFREQ_TABLE_END},
{CPUFREQ_BOOST_FREQ, L0, 1500 * 1000},
{0, L1, 1400 * 1000},
{0, L2, 1300 * 1000},
{0, L3, 1200 * 1000},
{0, L4, 1100 * 1000},
{0, L5, 1000 * 1000},
{0, L6, 900 * 1000},
{0, L7, 800 * 1000},
{0, L8, 700 * 1000},
{0, L9, 600 * 1000},
{0, L10, 500 * 1000},
{0, L11, 400 * 1000},
{0, L12, 300 * 1000},
{0, L13, 200 * 1000},
{0, 0, CPUFREQ_TABLE_END},
};
static struct apll_freq *apll_freq_4x12;
......
......@@ -34,23 +34,23 @@ static unsigned int exynos5250_volt_table[] = {
};
static struct cpufreq_frequency_table exynos5250_freq_table[] = {
{L0, 1700 * 1000},
{L1, 1600 * 1000},
{L2, 1500 * 1000},
{L3, 1400 * 1000},
{L4, 1300 * 1000},
{L5, 1200 * 1000},
{L6, 1100 * 1000},
{L7, 1000 * 1000},
{L8, 900 * 1000},
{L9, 800 * 1000},
{L10, 700 * 1000},
{L11, 600 * 1000},
{L12, 500 * 1000},
{L13, 400 * 1000},
{L14, 300 * 1000},
{L15, 200 * 1000},
{0, CPUFREQ_TABLE_END},
{0, L0, 1700 * 1000},
{0, L1, 1600 * 1000},
{0, L2, 1500 * 1000},
{0, L3, 1400 * 1000},
{0, L4, 1300 * 1000},
{0, L5, 1200 * 1000},
{0, L6, 1100 * 1000},
{0, L7, 1000 * 1000},
{0, L8, 900 * 1000},
{0, L9, 800 * 1000},
{0, L10, 700 * 1000},
{0, L11, 600 * 1000},
{0, L12, 500 * 1000},
{0, L13, 400 * 1000},
{0, L14, 300 * 1000},
{0, L15, 200 * 1000},
{0, 0, CPUFREQ_TABLE_END},
};
static struct apll_freq apll_freq_5250[] = {
......
......@@ -33,11 +33,10 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
continue;
}
if (!cpufreq_boost_enabled()
&& table[i].driver_data == CPUFREQ_BOOST_FREQ)
&& (table[i].flags & CPUFREQ_BOOST_FREQ))
continue;
pr_debug("table entry %u: %u kHz, %u driver_data\n",
i, freq, table[i].driver_data);
pr_debug("table entry %u: %u kHz\n", i, freq);
if (freq < min_freq)
min_freq = freq;
if (freq > max_freq)
......@@ -175,8 +174,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
} else
*index = optimal.driver_data;
pr_debug("target is %u (%u kHz, %u)\n", *index, table[*index].frequency,
table[*index].driver_data);
pr_debug("target index is %u, freq is:%u kHz\n", *index,
table[*index].frequency);
return 0;
}
......@@ -230,7 +229,7 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
* show_boost = false and driver_data != BOOST freq
* display NON BOOST freqs
*/
if (show_boost ^ (table[i].driver_data == CPUFREQ_BOOST_FREQ))
if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ))
continue;
count += sprintf(&buf[count], "%d ", table[i].frequency);
......
......@@ -254,7 +254,7 @@ acpi_cpufreq_cpu_init (
}
/* alloc freq_table */
data->freq_table = kmalloc(sizeof(*data->freq_table) *
data->freq_table = kzalloc(sizeof(*data->freq_table) *
(data->acpi_data.state_count + 1),
GFP_KERNEL);
if (!data->freq_table) {
......@@ -275,7 +275,6 @@ acpi_cpufreq_cpu_init (
/* table init */
for (i = 0; i <= data->acpi_data.state_count; i++)
{
data->freq_table[i].driver_data = i;
if (i < data->acpi_data.state_count) {
data->freq_table[i].frequency =
data->acpi_data.states[i].core_frequency * 1000;
......
......@@ -43,9 +43,9 @@ static struct priv
* table.
*/
static struct cpufreq_frequency_table kirkwood_freq_table[] = {
{STATE_CPU_FREQ, 0}, /* CPU uses cpuclk */
{STATE_DDR_FREQ, 0}, /* CPU uses ddrclk */
{0, CPUFREQ_TABLE_END},
{0, STATE_CPU_FREQ, 0}, /* CPU uses cpuclk */
{0, STATE_DDR_FREQ, 0}, /* CPU uses ddrclk */
{0, 0, CPUFREQ_TABLE_END},
};
static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu)
......
......@@ -475,7 +475,7 @@ static int longhaul_get_ranges(void)
return -EINVAL;
}
longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
longhaul_table = kzalloc((numscales + 1) * sizeof(*longhaul_table),
GFP_KERNEL);
if (!longhaul_table)
return -ENOMEM;
......
......@@ -69,7 +69,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
static struct clk *cpuclk;
struct clk *cpuclk;
int i;
unsigned long rate;
int ret;
......
......@@ -59,9 +59,9 @@
#define CPUFREQ_LOW 1
static struct cpufreq_frequency_table maple_cpu_freqs[] = {
{CPUFREQ_HIGH, 0},
{CPUFREQ_LOW, 0},
{0, CPUFREQ_TABLE_END},
{0, CPUFREQ_HIGH, 0},
{0, CPUFREQ_LOW, 0},
{0, 0, CPUFREQ_TABLE_END},
};
/* Power mode data is an array of the 32 bits PCR values to use for
......
......@@ -92,16 +92,16 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
static struct cpufreq_frequency_table p4clockmod_table[] = {
{DC_RESV, CPUFREQ_ENTRY_INVALID},
{DC_DFLT, 0},
{DC_25PT, 0},
{DC_38PT, 0},
{DC_50PT, 0},
{DC_64PT, 0},
{DC_75PT, 0},
{DC_88PT, 0},
{DC_DISABLE, 0},
{DC_RESV, CPUFREQ_TABLE_END},
{0, DC_RESV, CPUFREQ_ENTRY_INVALID},
{0, DC_DFLT, 0},
{0, DC_25PT, 0},
{0, DC_38PT, 0},
{0, DC_50PT, 0},
{0, DC_64PT, 0},
{0, DC_75PT, 0},
{0, DC_88PT, 0},
{0, DC_DISABLE, 0},
{0, DC_RESV, CPUFREQ_TABLE_END},
};
......
......@@ -60,12 +60,12 @@ static int current_astate;
/* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */
static struct cpufreq_frequency_table pas_freqs[] = {
{0, 0},
{1, 0},
{2, 0},
{3, 0},
{4, 0},
{0, CPUFREQ_TABLE_END},
{0, 0, 0},
{0, 1, 0},
{0, 2, 0},
{0, 3, 0},
{0, 4, 0},
{0, 0, CPUFREQ_TABLE_END},
};
/*
......
......@@ -81,9 +81,9 @@ static int is_pmu_based;
#define CPUFREQ_LOW 1
static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
{CPUFREQ_HIGH, 0},
{CPUFREQ_LOW, 0},
{0, CPUFREQ_TABLE_END},
{0, CPUFREQ_HIGH, 0},
{0, CPUFREQ_LOW, 0},
{0, 0, CPUFREQ_TABLE_END},
};
static inline void local_delay(unsigned long ms)
......
......@@ -65,9 +65,9 @@
#define CPUFREQ_LOW 1
static struct cpufreq_frequency_table g5_cpu_freqs[] = {
{CPUFREQ_HIGH, 0},
{CPUFREQ_LOW, 0},
{0, CPUFREQ_TABLE_END},
{0, CPUFREQ_HIGH, 0},
{0, CPUFREQ_LOW, 0},
{0, 0, CPUFREQ_TABLE_END},
};
/* Power mode data is an array of the 32 bits PCR values to use for
......
......@@ -37,15 +37,15 @@ MODULE_PARM_DESC(bus_frequency, "Bus frequency in kHz");
/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
static struct cpufreq_frequency_table clock_ratio[] = {
{60, /* 110 -> 6.0x */ 0},
{55, /* 011 -> 5.5x */ 0},
{50, /* 001 -> 5.0x */ 0},
{45, /* 000 -> 4.5x */ 0},
{40, /* 010 -> 4.0x */ 0},
{35, /* 111 -> 3.5x */ 0},
{30, /* 101 -> 3.0x */ 0},
{20, /* 100 -> 2.0x */ 0},
{0, CPUFREQ_TABLE_END}
{0, 60, /* 110 -> 6.0x */ 0},
{0, 55, /* 011 -> 5.5x */ 0},
{0, 50, /* 001 -> 5.0x */ 0},
{0, 45, /* 000 -> 4.5x */ 0},
{0, 40, /* 010 -> 4.0x */ 0},
{0, 35, /* 111 -> 3.5x */ 0},
{0, 30, /* 101 -> 3.0x */ 0},
{0, 20, /* 100 -> 2.0x */ 0},
{0, 0, CPUFREQ_TABLE_END}
};
static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 };
......
......@@ -623,7 +623,7 @@ static int fill_powernow_table(struct powernow_k8_data *data,
if (check_pst_table(data, pst, maxvid))
return -EINVAL;
powernow_table = kmalloc((sizeof(*powernow_table)
powernow_table = kzalloc((sizeof(*powernow_table)
* (data->numps + 1)), GFP_KERNEL);
if (!powernow_table) {
printk(KERN_ERR PFX "powernow_table memory alloc failure\n");
......@@ -793,7 +793,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
}
/* fill in data->powernow_table */
powernow_table = kmalloc((sizeof(*powernow_table)
powernow_table = kzalloc((sizeof(*powernow_table)
* (data->acpi_data.state_count + 1)), GFP_KERNEL);
if (!powernow_table) {
pr_debug("powernow_table memory alloc failure\n");
......@@ -810,7 +810,6 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
powernow_table[data->acpi_data.state_count].frequency =
CPUFREQ_TABLE_END;
powernow_table[data->acpi_data.state_count].driver_data = 0;
data->powernow_table = powernow_table;
if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
......
/*
* POWERNV cpufreq driver for the IBM POWER processors
*
* (C) Copyright IBM 2014
*
* Author: Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.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, 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.
*
*/
#define pr_fmt(fmt) "powernv-cpufreq: " fmt
#include <linux/kernel.h>
#include <linux/sysfs.h>
#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/cpufreq.h>
#include <linux/smp.h>
#include <linux/of.h>
#include <asm/cputhreads.h>
#include <asm/reg.h>
#define POWERNV_MAX_PSTATES 256
static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
/*
* Note: The set of pstates consists of contiguous integers, the
* smallest of which is indicated by powernv_pstate_info.min, the
* largest of which is indicated by powernv_pstate_info.max.
*
* The nominal pstate is the highest non-turbo pstate in this
* platform. This is indicated by powernv_pstate_info.nominal.
*/
static struct powernv_pstate_info {
int min;
int max;
int nominal;
int nr_pstates;
} powernv_pstate_info;
/*
* Initialize the freq table based on data obtained
* from the firmware passed via device-tree
*/
static int init_powernv_pstates(void)
{
struct device_node *power_mgt;
int i, pstate_min, pstate_max, pstate_nominal, nr_pstates = 0;
const __be32 *pstate_ids, *pstate_freqs;
u32 len_ids, len_freqs;
power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
if (!power_mgt) {
pr_warn("power-mgt node not found\n");
return -ENODEV;
}
if (of_property_read_u32(power_mgt, "ibm,pstate-min", &pstate_min)) {
pr_warn("ibm,pstate-min node not found\n");
return -ENODEV;
}
if (of_property_read_u32(power_mgt, "ibm,pstate-max", &pstate_max)) {
pr_warn("ibm,pstate-max node not found\n");
return -ENODEV;
}
if (of_property_read_u32(power_mgt, "ibm,pstate-nominal",
&pstate_nominal)) {
pr_warn("ibm,pstate-nominal not found\n");
return -ENODEV;
}
pr_info("cpufreq pstate min %d nominal %d max %d\n", pstate_min,
pstate_nominal, pstate_max);
pstate_ids = of_get_property(power_mgt, "ibm,pstate-ids", &len_ids);
if (!pstate_ids) {
pr_warn("ibm,pstate-ids not found\n");
return -ENODEV;
}
pstate_freqs = of_get_property(power_mgt, "ibm,pstate-frequencies-mhz",
&len_freqs);
if (!pstate_freqs) {
pr_warn("ibm,pstate-frequencies-mhz not found\n");
return -ENODEV;
}
WARN_ON(len_ids != len_freqs);
nr_pstates = min(len_ids, len_freqs) / sizeof(u32);
if (!nr_pstates) {
pr_warn("No PStates found\n");
return -ENODEV;
}
pr_debug("NR PStates %d\n", nr_pstates);
for (i = 0; i < nr_pstates; i++) {
u32 id = be32_to_cpu(pstate_ids[i]);
u32 freq = be32_to_cpu(pstate_freqs[i]);
pr_debug("PState id %d freq %d MHz\n", id, freq);
powernv_freqs[i].frequency = freq * 1000; /* kHz */
powernv_freqs[i].driver_data = id;
}
/* End of list marker entry */
powernv_freqs[i].frequency = CPUFREQ_TABLE_END;
powernv_pstate_info.min = pstate_min;
powernv_pstate_info.max = pstate_max;
powernv_pstate_info.nominal = pstate_nominal;
powernv_pstate_info.nr_pstates = nr_pstates;
return 0;
}
/* Returns the CPU frequency corresponding to the pstate_id. */
static unsigned int pstate_id_to_freq(int pstate_id)
{
int i;
i = powernv_pstate_info.max - pstate_id;
BUG_ON(i >= powernv_pstate_info.nr_pstates || i < 0);
return powernv_freqs[i].frequency;
}
/*
* cpuinfo_nominal_freq_show - Show the nominal CPU frequency as indicated by
* the firmware
*/
static ssize_t cpuinfo_nominal_freq_show(struct cpufreq_policy *policy,
char *buf)
{
return sprintf(buf, "%u\n",
pstate_id_to_freq(powernv_pstate_info.nominal));
}
struct freq_attr cpufreq_freq_attr_cpuinfo_nominal_freq =
__ATTR_RO(cpuinfo_nominal_freq);
static struct freq_attr *powernv_cpu_freq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
&cpufreq_freq_attr_cpuinfo_nominal_freq,
NULL,
};
/* Helper routines */
/* Access helpers to power mgt SPR */
static inline unsigned long get_pmspr(unsigned long sprn)
{
switch (sprn) {
case SPRN_PMCR:
return mfspr(SPRN_PMCR);
case SPRN_PMICR:
return mfspr(SPRN_PMICR);
case SPRN_PMSR:
return mfspr(SPRN_PMSR);
}
BUG();
}
static inline void set_pmspr(unsigned long sprn, unsigned long val)
{
switch (sprn) {
case SPRN_PMCR:
mtspr(SPRN_PMCR, val);
return;
case SPRN_PMICR:
mtspr(SPRN_PMICR, val);
return;
}
BUG();
}
/*
* Use objects of this type to query/update
* pstates on a remote CPU via smp_call_function.
*/
struct powernv_smp_call_data {
unsigned int freq;
int pstate_id;
};
/*
* powernv_read_cpu_freq: Reads the current frequency on this CPU.
*
* Called via smp_call_function.
*
* Note: The caller of the smp_call_function should pass an argument of
* the type 'struct powernv_smp_call_data *' along with this function.
*
* The current frequency on this CPU will be returned via
* ((struct powernv_smp_call_data *)arg)->freq;
*/
static void powernv_read_cpu_freq(void *arg)
{
unsigned long pmspr_val;
s8 local_pstate_id;
struct powernv_smp_call_data *freq_data = arg;
pmspr_val = get_pmspr(SPRN_PMSR);
/*
* The local pstate id corresponds bits 48..55 in the PMSR.
* Note: Watch out for the sign!
*/
local_pstate_id = (pmspr_val >> 48) & 0xFF;
freq_data->pstate_id = local_pstate_id;
freq_data->freq = pstate_id_to_freq(freq_data->pstate_id);
pr_debug("cpu %d pmsr %016lX pstate_id %d frequency %d kHz\n",
raw_smp_processor_id(), pmspr_val, freq_data->pstate_id,
freq_data->freq);
}
/*
* powernv_cpufreq_get: Returns the CPU frequency as reported by the
* firmware for CPU 'cpu'. This value is reported through the sysfs
* file cpuinfo_cur_freq.
*/
unsigned int powernv_cpufreq_get(unsigned int cpu)
{
struct powernv_smp_call_data freq_data;
smp_call_function_any(cpu_sibling_mask(cpu), powernv_read_cpu_freq,
&freq_data, 1);
return freq_data.freq;
}
/*
* set_pstate: Sets the pstate on this CPU.
*
* This is called via an smp_call_function.
*
* The caller must ensure that freq_data is of the type
* (struct powernv_smp_call_data *) and the pstate_id which needs to be set
* on this CPU should be present in freq_data->pstate_id.
*/
static void set_pstate(void *freq_data)
{
unsigned long val;
unsigned long pstate_ul =
((struct powernv_smp_call_data *) freq_data)->pstate_id;
val = get_pmspr(SPRN_PMCR);
val = val & 0x0000FFFFFFFFFFFFULL;
pstate_ul = pstate_ul & 0xFF;
/* Set both global(bits 56..63) and local(bits 48..55) PStates */
val = val | (pstate_ul << 56) | (pstate_ul << 48);
pr_debug("Setting cpu %d pmcr to %016lX\n",
raw_smp_processor_id(), val);
set_pmspr(SPRN_PMCR, val);
}
/*
* powernv_cpufreq_target_index: Sets the frequency corresponding to
* the cpufreq table entry indexed by new_index on the cpus in the
* mask policy->cpus
*/
static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
unsigned int new_index)
{
struct powernv_smp_call_data freq_data;
freq_data.pstate_id = powernv_freqs[new_index].driver_data;
/*
* Use smp_call_function to send IPI and execute the
* mtspr on target CPU. We could do that without IPI
* if current CPU is within policy->cpus (core)
*/
smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1);
return 0;
}
static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
int base, i;
base = cpu_first_thread_sibling(policy->cpu);
for (i = 0; i < threads_per_core; i++)
cpumask_set_cpu(base + i, policy->cpus);
return cpufreq_table_validate_and_show(policy, powernv_freqs);
}
static struct cpufreq_driver powernv_cpufreq_driver = {
.name = "powernv-cpufreq",
.flags = CPUFREQ_CONST_LOOPS,
.init = powernv_cpufreq_cpu_init,
.verify = cpufreq_generic_frequency_table_verify,
.target_index = powernv_cpufreq_target_index,
.get = powernv_cpufreq_get,
.attr = powernv_cpu_freq_attr,
};
static int __init powernv_cpufreq_init(void)
{
int rc = 0;
/* Discover pstates from device tree and init */
rc = init_powernv_pstates();
if (rc) {
pr_info("powernv-cpufreq disabled. System does not support PState control\n");
return rc;
}
return cpufreq_register_driver(&powernv_cpufreq_driver);
}
module_init(powernv_cpufreq_init);
static void __exit powernv_cpufreq_exit(void)
{
cpufreq_unregister_driver(&powernv_cpufreq_driver);
}
module_exit(powernv_cpufreq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>");
......@@ -13,7 +13,6 @@
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/errno.h>
#include <sysdev/fsl_soc.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
......
......@@ -32,15 +32,15 @@
/* the CBE supports an 8 step frequency scaling */
static struct cpufreq_frequency_table cbe_freqs[] = {
{1, 0},
{2, 0},
{3, 0},
{4, 0},
{5, 0},
{6, 0},
{8, 0},
{10, 0},
{0, CPUFREQ_TABLE_END},
{0, 1, 0},
{0, 2, 0},
{0, 3, 0},
{0, 4, 0},
{0, 5, 0},
{0, 6, 0},
{0, 8, 0},
{0, 10, 0},
{0, 0, CPUFREQ_TABLE_END},
};
/*
......
......@@ -72,19 +72,19 @@ static struct s3c2416_dvfs s3c2416_dvfs_table[] = {
#endif
static struct cpufreq_frequency_table s3c2416_freq_table[] = {
{ SOURCE_HCLK, FREQ_DVS },
{ SOURCE_ARMDIV, 133333 },
{ SOURCE_ARMDIV, 266666 },
{ SOURCE_ARMDIV, 400000 },
{ 0, CPUFREQ_TABLE_END },
{ 0, SOURCE_HCLK, FREQ_DVS },
{ 0, SOURCE_ARMDIV, 133333 },
{ 0, SOURCE_ARMDIV, 266666 },
{ 0, SOURCE_ARMDIV, 400000 },
{ 0, 0, CPUFREQ_TABLE_END },
};
static struct cpufreq_frequency_table s3c2450_freq_table[] = {
{ SOURCE_HCLK, FREQ_DVS },
{ SOURCE_ARMDIV, 133500 },
{ SOURCE_ARMDIV, 267000 },
{ SOURCE_ARMDIV, 534000 },
{ 0, CPUFREQ_TABLE_END },
{ 0, SOURCE_HCLK, FREQ_DVS },
{ 0, SOURCE_ARMDIV, 133500 },
{ 0, SOURCE_ARMDIV, 267000 },
{ 0, SOURCE_ARMDIV, 534000 },
{ 0, 0, CPUFREQ_TABLE_END },
};
static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu)
......
......@@ -586,7 +586,7 @@ static int s3c_cpufreq_build_freq(void)
size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
size++;
ftab = kmalloc(sizeof(*ftab) * size, GFP_KERNEL);
ftab = kzalloc(sizeof(*ftab) * size, GFP_KERNEL);
if (!ftab) {
printk(KERN_ERR "%s: no memory for tables\n", __func__);
return -ENOMEM;
......@@ -664,7 +664,7 @@ int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
size = sizeof(*vals) * (plls_no + 1);
vals = kmalloc(size, GFP_KERNEL);
vals = kzalloc(size, GFP_KERNEL);
if (vals) {
memcpy(vals, plls, size);
pll_reg = vals;
......
......@@ -37,19 +37,19 @@ static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
};
static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
{ 0, 66000 },
{ 0, 100000 },
{ 0, 133000 },
{ 1, 200000 },
{ 1, 222000 },
{ 1, 266000 },
{ 2, 333000 },
{ 2, 400000 },
{ 2, 532000 },
{ 2, 533000 },
{ 3, 667000 },
{ 4, 800000 },
{ 0, CPUFREQ_TABLE_END },
{ 0, 0, 66000 },
{ 0, 0, 100000 },
{ 0, 0, 133000 },
{ 0, 1, 200000 },
{ 0, 1, 222000 },
{ 0, 1, 266000 },
{ 0, 2, 333000 },
{ 0, 2, 400000 },
{ 0, 2, 532000 },
{ 0, 2, 533000 },
{ 0, 3, 667000 },
{ 0, 4, 800000 },
{ 0, 0, CPUFREQ_TABLE_END },
};
#endif
......
......@@ -64,12 +64,12 @@ enum s5pv210_dmc_port {
};
static struct cpufreq_frequency_table s5pv210_freq_table[] = {
{L0, 1000*1000},
{L1, 800*1000},
{L2, 400*1000},
{L3, 200*1000},
{L4, 100*1000},
{0, CPUFREQ_TABLE_END},
{0, L0, 1000*1000},
{0, L1, 800*1000},
{0, L2, 400*1000},
{0, L3, 200*1000},
{0, L4, 100*1000},
{0, 0, CPUFREQ_TABLE_END},
};
static struct regulator *arm_regulator;
......
......@@ -33,9 +33,9 @@ static __u8 __iomem *cpuctl;
#define PFX "sc520_freq: "
static struct cpufreq_frequency_table sc520_freq_table[] = {
{0x01, 100000},
{0x02, 133000},
{0, CPUFREQ_TABLE_END},
{0, 0x01, 100000},
{0, 0x02, 133000},
{0, 0, CPUFREQ_TABLE_END},
};
static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
......
......@@ -195,18 +195,15 @@ static int spear_cpufreq_probe(struct platform_device *pdev)
cnt = prop->length / sizeof(u32);
val = prop->value;
freq_tbl = kmalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL);
freq_tbl = kzalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL);
if (!freq_tbl) {
ret = -ENOMEM;
goto out_put_node;
}
for (i = 0; i < cnt; i++) {
freq_tbl[i].driver_data = i;
for (i = 0; i < cnt; i++)
freq_tbl[i].frequency = be32_to_cpup(val++);
}
freq_tbl[i].driver_data = i;
freq_tbl[i].frequency = CPUFREQ_TABLE_END;
spear_cpufreq.freq_tbl = freq_tbl;
......
......@@ -49,9 +49,9 @@ static u32 pmbase;
* are in kHz for the time being.
*/
static struct cpufreq_frequency_table speedstep_freqs[] = {
{SPEEDSTEP_HIGH, 0},
{SPEEDSTEP_LOW, 0},
{0, CPUFREQ_TABLE_END},
{0, SPEEDSTEP_HIGH, 0},
{0, SPEEDSTEP_LOW, 0},
{0, 0, CPUFREQ_TABLE_END},
};
......
......@@ -42,9 +42,9 @@ static enum speedstep_processor speedstep_processor;
* are in kHz for the time being.
*/
static struct cpufreq_frequency_table speedstep_freqs[] = {
{SPEEDSTEP_HIGH, 0},
{SPEEDSTEP_LOW, 0},
{0, CPUFREQ_TABLE_END},
{0, SPEEDSTEP_HIGH, 0},
{0, SPEEDSTEP_LOW, 0},
{0, 0, CPUFREQ_TABLE_END},
};
#define GET_SPEEDSTEP_OWNER 0
......
......@@ -45,7 +45,7 @@ static int ucv2_target(struct cpufreq_policy *policy,
freqs.new = target_freq;
cpufreq_freq_transition_begin(policy, &freqs);
ret = clk_set_rate(policy->mclk, target_freq * 1000);
ret = clk_set_rate(policy->clk, target_freq * 1000);
cpufreq_freq_transition_end(policy, &freqs, ret);
return ret;
......
......@@ -293,6 +293,7 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
}
define_show_state_function(exit_latency)
define_show_state_function(target_residency)
define_show_state_function(power_usage)
define_show_state_ull_function(usage)
define_show_state_ull_function(time)
......@@ -304,6 +305,7 @@ define_store_state_ull_function(disable)
define_one_state_ro(name, show_state_name);
define_one_state_ro(desc, show_state_desc);
define_one_state_ro(latency, show_state_exit_latency);
define_one_state_ro(residency, show_state_target_residency);
define_one_state_ro(power, show_state_power_usage);
define_one_state_ro(usage, show_state_usage);
define_one_state_ro(time, show_state_time);
......@@ -313,6 +315,7 @@ static struct attribute *cpuidle_state_default_attrs[] = {
&attr_name.attr,
&attr_desc.attr,
&attr_latency.attr,
&attr_residency.attr,
&attr_power.attr,
&attr_usage.attr,
&attr_time.attr,
......
......@@ -196,6 +196,53 @@ static struct cpuidle_state snb_cstates[] = {
.enter = NULL }
};
static struct cpuidle_state byt_cstates[] = {
{
.name = "C1-BYT",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 1,
.target_residency = 1,
.enter = &intel_idle },
{
.name = "C1E-BYT",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 15,
.target_residency = 30,
.enter = &intel_idle },
{
.name = "C6N-BYT",
.desc = "MWAIT 0x58",
.flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 40,
.target_residency = 275,
.enter = &intel_idle },
{
.name = "C6S-BYT",
.desc = "MWAIT 0x52",
.flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 140,
.target_residency = 560,
.enter = &intel_idle },
{
.name = "C7-BYT",
.desc = "MWAIT 0x60",
.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 1200,
.target_residency = 1500,
.enter = &intel_idle },
{
.name = "C7S-BYT",
.desc = "MWAIT 0x64",
.flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 10000,
.target_residency = 20000,
.enter = &intel_idle },
{
.enter = NULL }
};
static struct cpuidle_state ivb_cstates[] = {
{
.name = "C1-IVB",
......@@ -236,6 +283,105 @@ static struct cpuidle_state ivb_cstates[] = {
.enter = NULL }
};
static struct cpuidle_state ivt_cstates[] = {
{
.name = "C1-IVT",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 1,
.target_residency = 1,
.enter = &intel_idle },
{
.name = "C1E-IVT",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 10,
.target_residency = 80,
.enter = &intel_idle },
{
.name = "C3-IVT",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 156,
.enter = &intel_idle },
{
.name = "C6-IVT",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 82,
.target_residency = 300,
.enter = &intel_idle },
{
.enter = NULL }
};
static struct cpuidle_state ivt_cstates_4s[] = {
{
.name = "C1-IVT-4S",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 1,
.target_residency = 1,
.enter = &intel_idle },
{
.name = "C1E-IVT-4S",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 10,
.target_residency = 250,
.enter = &intel_idle },
{
.name = "C3-IVT-4S",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 300,
.enter = &intel_idle },
{
.name = "C6-IVT-4S",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 84,
.target_residency = 400,
.enter = &intel_idle },
{
.enter = NULL }
};
static struct cpuidle_state ivt_cstates_8s[] = {
{
.name = "C1-IVT-8S",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 1,
.target_residency = 1,
.enter = &intel_idle },
{
.name = "C1E-IVT-8S",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 10,
.target_residency = 500,
.enter = &intel_idle },
{
.name = "C3-IVT-8S",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 600,
.enter = &intel_idle },
{
.name = "C6-IVT-8S",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 88,
.target_residency = 700,
.enter = &intel_idle },
{
.enter = NULL }
};
static struct cpuidle_state hsw_cstates[] = {
{
.name = "C1-HSW",
......@@ -464,11 +610,21 @@ static const struct idle_cpu idle_cpu_snb = {
.disable_promotion_to_c1e = true,
};
static const struct idle_cpu idle_cpu_byt = {
.state_table = byt_cstates,
.disable_promotion_to_c1e = true,
};
static const struct idle_cpu idle_cpu_ivb = {
.state_table = ivb_cstates,
.disable_promotion_to_c1e = true,
};
static const struct idle_cpu idle_cpu_ivt = {
.state_table = ivt_cstates,
.disable_promotion_to_c1e = true,
};
static const struct idle_cpu idle_cpu_hsw = {
.state_table = hsw_cstates,
.disable_promotion_to_c1e = true,
......@@ -494,8 +650,10 @@ static const struct x86_cpu_id intel_idle_ids[] = {
ICPU(0x2f, idle_cpu_nehalem),
ICPU(0x2a, idle_cpu_snb),
ICPU(0x2d, idle_cpu_snb),
ICPU(0x36, idle_cpu_atom),
ICPU(0x37, idle_cpu_byt),
ICPU(0x3a, idle_cpu_ivb),
ICPU(0x3e, idle_cpu_ivb),
ICPU(0x3e, idle_cpu_ivt),
ICPU(0x3c, idle_cpu_hsw),
ICPU(0x3f, idle_cpu_hsw),
ICPU(0x45, idle_cpu_hsw),
......@@ -572,6 +730,39 @@ static void intel_idle_cpuidle_devices_uninit(void)
free_percpu(intel_idle_cpuidle_devices);
return;
}
/*
* intel_idle_state_table_update()
*
* Update the default state_table for this CPU-id
*
* Currently used to access tuned IVT multi-socket targets
* Assumption: num_sockets == (max_package_num + 1)
*/
void intel_idle_state_table_update(void)
{
/* IVT uses a different table for 1-2, 3-4, and > 4 sockets */
if (boot_cpu_data.x86_model == 0x3e) { /* IVT */
int cpu, package_num, num_sockets = 1;
for_each_online_cpu(cpu) {
package_num = topology_physical_package_id(cpu);
if (package_num + 1 > num_sockets) {
num_sockets = package_num + 1;
if (num_sockets > 4)
cpuidle_state_table = ivt_cstates_8s;
return;
}
}
if (num_sockets > 2)
cpuidle_state_table = ivt_cstates_4s;
/* else, 1 and 2 socket systems use default ivt_cstates */
}
return;
}
/*
* intel_idle_cpuidle_driver_init()
* allocate, initialize cpuidle_states
......@@ -581,10 +772,12 @@ static int __init intel_idle_cpuidle_driver_init(void)
int cstate;
struct cpuidle_driver *drv = &intel_idle_driver;
intel_idle_state_table_update();
drv->state_count = 1;
for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {
int num_substates, mwait_hint, mwait_cstate, mwait_substate;
int num_substates, mwait_hint, mwait_cstate;
if (cpuidle_state_table[cstate].enter == NULL)
break;
......@@ -597,14 +790,13 @@ static int __init intel_idle_cpuidle_driver_init(void)
mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags);
mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint);
mwait_substate = MWAIT_HINT2SUBSTATE(mwait_hint);
/* does the state exist in CPUID.MWAIT? */
/* number of sub-states for this state in CPUID.MWAIT */
num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4))
& MWAIT_SUBSTATE_MASK;
/* if sub-state in table is not enumerated by CPUID */
if ((mwait_substate + 1) > num_substates)
/* if NO sub-states for this state in CPUID, skip it */
if (num_substates == 0)
continue;
if (((mwait_cstate + 1) > 2) &&
......
......@@ -455,11 +455,14 @@ extern struct cpufreq_governor cpufreq_gov_conservative;
* FREQUENCY TABLE HELPERS *
*********************************************************************/
#define CPUFREQ_ENTRY_INVALID ~0
#define CPUFREQ_TABLE_END ~1
#define CPUFREQ_BOOST_FREQ ~2
/* Special Values of .frequency field */
#define CPUFREQ_ENTRY_INVALID ~0
#define CPUFREQ_TABLE_END ~1
/* Special Values of .flags field */
#define CPUFREQ_BOOST_FREQ (1 << 0)
struct cpufreq_frequency_table {
unsigned int flags;
unsigned int driver_data; /* driver specific data, not used by core */
unsigned int frequency; /* kHz - doesn't need to be in ascending
* order */
......
......@@ -47,21 +47,22 @@ displays the statistics gathered since it was forked.
.PP
.SH FIELD DESCRIPTIONS
.nf
\fBpk\fP processor package number.
\fBcor\fP processor core number.
\fBPackage\fP processor package number.
\fBCore\fP processor core number.
\fBCPU\fP Linux CPU (logical processor) number.
Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology.
\fB%c0\fP percent of the interval that the CPU retired instructions.
\fBGHz\fP average clock rate while the CPU was in c0 state.
\fBTSC\fP average GHz that the TSC ran during the entire interval.
\fB%c1, %c3, %c6, %c7\fP show the percentage residency in hardware core idle states.
\fBCTMP\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
\fBPTMP\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
\fB%pc2, %pc3, %pc6, %pc7\fP percentage residency in hardware package idle states.
\fBPkg_W\fP Watts consumed by the whole package.
\fBCor_W\fP Watts consumed by the core part of the package.
\fBGFX_W\fP Watts consumed by the Graphics part of the package -- available only on client processors.
\fBRAM_W\fP Watts consumed by the DRAM DIMMS -- available only on server processors.
\fBAVG_MHz\fP number of cycles executed divided by time elapsed.
\fB%Buzy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
\fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state).
\fBTSC_MHz\fP average MHz that the TSC ran during the entire interval.
\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states.
\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
\fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
\fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states.
\fBPkgWatt\fP Watts consumed by the whole package.
\fBCorWatt\fP Watts consumed by the core part of the package.
\fBGFXWatt\fP Watts consumed by the Graphics part of the package -- available only on client processors.
\fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors.
\fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package.
\fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM.
.fi
......@@ -78,29 +79,17 @@ For Watts columns, the summary is a system total.
Subsequent rows show per-CPU statistics.
.nf
[root@sandy]# ./turbostat
cor CPU %c0 GHz TSC %c1 %c3 %c6 %c7 CTMP PTMP %pc2 %pc3 %pc6 %pc7 Pkg_W Cor_W GFX_W
0.06 0.80 2.29 0.11 0.00 0.00 99.83 47 40 0.26 0.01 0.44 98.78 3.49 0.12 0.14
0 0 0.07 0.80 2.29 0.07 0.00 0.00 99.86 40 40 0.26 0.01 0.44 98.78 3.49 0.12 0.14
0 4 0.03 0.80 2.29 0.12
1 1 0.04 0.80 2.29 0.25 0.01 0.00 99.71 40
1 5 0.16 0.80 2.29 0.13
2 2 0.05 0.80 2.29 0.06 0.01 0.00 99.88 40
2 6 0.03 0.80 2.29 0.08
3 3 0.05 0.80 2.29 0.08 0.00 0.00 99.87 47
3 7 0.04 0.84 2.29 0.09
.fi
.SH SUMMARY EXAMPLE
The "-s" option prints the column headers just once,
and then the one line system summary for each sample interval.
.nf
[root@wsm]# turbostat -S
%c0 GHz TSC %c1 %c3 %c6 CTMP %pc3 %pc6
1.40 2.81 3.38 10.78 43.47 44.35 42 13.67 2.09
1.34 2.90 3.38 11.48 58.96 28.23 41 19.89 0.15
1.55 2.72 3.38 26.73 37.66 34.07 42 2.53 2.80
1.37 2.83 3.38 16.95 60.05 21.63 42 5.76 0.20
[root@ivy]# ./turbostat
Core CPU Avg_MHz %Busy Bzy_MHz TSC_MHz SMI CPU%c1 CPU%c3 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
- - 6 0.36 1596 3492 0 0.59 0.01 99.04 0.00 23 24 23.82 0.01 72.47 0.00 6.40 1.01 0.00
0 0 9 0.58 1596 3492 0 0.28 0.01 99.13 0.00 23 24 23.82 0.01 72.47 0.00 6.40 1.01 0.00
0 4 1 0.07 1596 3492 0 0.79
1 1 10 0.65 1596 3492 0 0.59 0.00 98.76 0.00 23
1 5 5 0.28 1596 3492 0 0.95
2 2 10 0.66 1596 3492 0 0.41 0.01 98.92 0.00 23
2 6 2 0.10 1597 3492 0 0.97
3 3 3 0.20 1596 3492 0 0.44 0.00 99.37 0.00 23
3 7 5 0.31 1596 3492 0 0.33
.fi
.SH VERBOSE EXAMPLE
The "-v" option adds verbosity to the output:
......@@ -154,55 +143,35 @@ eg. Here a cycle soaker is run on 1 CPU (see %c0) for a few seconds
until ^C while the other CPUs are mostly idle:
.nf
[root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null
root@ivy: turbostat cat /dev/zero > /dev/null
^C
cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6
8.86 3.61 3.38 15.06 31.19 44.89 0.00 0.00
0 0 1.46 3.22 3.38 16.84 29.48 52.22 0.00 0.00
0 6 0.21 3.06 3.38 18.09
1 2 0.53 3.33 3.38 2.80 46.40 50.27
1 8 0.89 3.47 3.38 2.44
2 4 1.36 3.43 3.38 9.04 23.71 65.89
2 10 0.18 2.86 3.38 10.22
8 1 0.04 2.87 3.38 99.96 0.01 0.00
8 7 99.72 3.63 3.38 0.27
9 3 0.31 3.21 3.38 7.64 56.55 35.50
9 9 0.08 2.95 3.38 7.88
10 5 1.42 3.43 3.38 2.14 30.99 65.44
10 11 0.16 2.88 3.38 3.40
Core CPU Avg_MHz %Busy Bzy_MHz TSC_MHz SMI CPU%c1 CPU%c3 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
- - 496 12.75 3886 3492 0 13.16 0.04 74.04 0.00 36 36 0.00 0.00 0.00 0.00 23.15 17.65 0.00
0 0 22 0.57 3830 3492 0 0.83 0.02 98.59 0.00 27 36 0.00 0.00 0.00 0.00 23.15 17.65 0.00
0 4 9 0.24 3829 3492 0 1.15
1 1 4 0.09 3783 3492 0 99.91 0.00 0.00 0.00 36
1 5 3880 99.82 3888 3492 0 0.18
2 2 17 0.44 3813 3492 0 0.77 0.04 98.75 0.00 28
2 6 12 0.32 3823 3492 0 0.89
3 3 16 0.43 3844 3492 0 0.63 0.11 98.84 0.00 30
3 7 4 0.11 3827 3492 0 0.94
30.372243 sec
.fi
Above the cycle soaker drives cpu7 up its 3.6 GHz turbo limit
Above the cycle soaker drives cpu5 up its 3.8 GHz turbo limit
while the other processors are generally in various states of idle.
Note that cpu1 and cpu7 are HT siblings within core8.
As cpu7 is very busy, it prevents its sibling, cpu1,
Note that cpu1 and cpu5 are HT siblings within core1.
As cpu5 is very busy, it prevents its sibling, cpu1,
from entering a c-state deeper than c1.
Note that turbostat reports average GHz of 3.63, while
the arithmetic average of the GHz column above is lower.
This is a weighted average, where the weight is %c0. ie. it is the total number of
un-halted cycles elapsed per time divided by the number of CPUs.
.SH SMI COUNTING EXAMPLE
On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
This counter is shown by default under the "SMI" column.
.nf
[root@x980 ~]# turbostat
cor CPU %c0 GHz TSC SMI %c1 %c3 %c6 CTMP %pc3 %pc6
0.11 1.91 3.38 0 1.84 0.26 97.79 29 0.82 83.87
0 0 0.40 1.63 3.38 0 10.27 0.12 89.20 20 0.82 83.88
0 6 0.06 1.63 3.38 0 10.61
1 2 0.37 2.63 3.38 0 0.02 0.10 99.51 22
1 8 0.01 1.62 3.38 0 0.39
2 4 0.07 1.62 3.38 0 0.04 0.07 99.82 23
2 10 0.02 1.62 3.38 0 0.09
8 1 0.23 1.64 3.38 0 0.10 1.07 98.60 24
8 7 0.02 1.64 3.38 0 0.31
9 3 0.03 1.62 3.38 0 0.03 0.05 99.89 29
9 9 0.02 1.62 3.38 0 0.05
10 5 0.07 1.62 3.38 0 0.08 0.12 99.73 27
10 11 0.03 1.62 3.38 0 0.13
^C
.fi
Note that the Avg_MHz column reflects the total number of cycles executed
divided by the measurement interval. If the %Busy column is 100%,
then the processor was running at that speed the entire interval.
The Avg_MHz multiplied by the %Busy results in the Bzy_MHz --
which is the average frequency while the processor was executing --
not including any non-busy idle time.
.SH NOTES
.B "turbostat "
......
......@@ -56,7 +56,7 @@ unsigned int do_slm_cstates;
unsigned int use_c1_residency_msr;
unsigned int has_aperf;
unsigned int has_epb;
unsigned int units = 1000000000; /* Ghz etc */
unsigned int units = 1000000; /* MHz etc */
unsigned int genuine_intel;
unsigned int has_invariant_tsc;
unsigned int do_nehalem_platform_info;
......@@ -264,88 +264,93 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
return 0;
}
/*
* Example Format w/ field column widths:
*
* Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
* 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567
*/
void print_header(void)
{
if (show_pkg)
outp += sprintf(outp, "pk");
if (show_pkg)
outp += sprintf(outp, " ");
outp += sprintf(outp, "Package ");
if (show_core)
outp += sprintf(outp, "cor");
outp += sprintf(outp, " Core ");
if (show_cpu)
outp += sprintf(outp, " CPU");
if (show_pkg || show_core || show_cpu)
outp += sprintf(outp, " ");
outp += sprintf(outp, " CPU ");
if (has_aperf)
outp += sprintf(outp, "Avg_MHz ");
if (do_nhm_cstates)
outp += sprintf(outp, " %%c0");
outp += sprintf(outp, " %%Busy ");
if (has_aperf)
outp += sprintf(outp, " GHz");
outp += sprintf(outp, " TSC");
outp += sprintf(outp, "Bzy_MHz ");
outp += sprintf(outp, "TSC_MHz ");
if (do_smi)
outp += sprintf(outp, " SMI");
outp += sprintf(outp, " SMI ");
if (extra_delta_offset32)
outp += sprintf(outp, " count 0x%03X", extra_delta_offset32);
outp += sprintf(outp, " count 0x%03X ", extra_delta_offset32);
if (extra_delta_offset64)
outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64);
outp += sprintf(outp, " COUNT 0x%03X ", extra_delta_offset64);
if (extra_msr_offset32)
outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32);
outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset32);
if (extra_msr_offset64)
outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset64);
if (do_nhm_cstates)
outp += sprintf(outp, " %%c1");
outp += sprintf(outp, " CPU%%c1 ");
if (do_nhm_cstates && !do_slm_cstates)
outp += sprintf(outp, " %%c3");
outp += sprintf(outp, " CPU%%c3 ");
if (do_nhm_cstates)
outp += sprintf(outp, " %%c6");
outp += sprintf(outp, " CPU%%c6 ");
if (do_snb_cstates)
outp += sprintf(outp, " %%c7");
outp += sprintf(outp, " CPU%%c7 ");
if (do_dts)
outp += sprintf(outp, " CTMP");
outp += sprintf(outp, "CoreTmp ");
if (do_ptm)
outp += sprintf(outp, " PTMP");
outp += sprintf(outp, " PkgTmp ");
if (do_snb_cstates)
outp += sprintf(outp, " %%pc2");
outp += sprintf(outp, "Pkg%%pc2 ");
if (do_nhm_cstates && !do_slm_cstates)
outp += sprintf(outp, " %%pc3");
outp += sprintf(outp, "Pkg%%pc3 ");
if (do_nhm_cstates && !do_slm_cstates)
outp += sprintf(outp, " %%pc6");
outp += sprintf(outp, "Pkg%%pc6 ");
if (do_snb_cstates)
outp += sprintf(outp, " %%pc7");
outp += sprintf(outp, "Pkg%%pc7 ");
if (do_c8_c9_c10) {
outp += sprintf(outp, " %%pc8");
outp += sprintf(outp, " %%pc9");
outp += sprintf(outp, " %%pc10");
outp += sprintf(outp, "Pkg%%pc8 ");
outp += sprintf(outp, "Pkg%%pc9 ");
outp += sprintf(outp, "Pk%%pc10 ");
}
if (do_rapl && !rapl_joules) {
if (do_rapl & RAPL_PKG)
outp += sprintf(outp, " Pkg_W");
outp += sprintf(outp, "PkgWatt ");
if (do_rapl & RAPL_CORES)
outp += sprintf(outp, " Cor_W");
outp += sprintf(outp, "CorWatt ");
if (do_rapl & RAPL_GFX)
outp += sprintf(outp, " GFX_W");
outp += sprintf(outp, "GFXWatt ");
if (do_rapl & RAPL_DRAM)
outp += sprintf(outp, " RAM_W");
outp += sprintf(outp, "RAMWatt ");
if (do_rapl & RAPL_PKG_PERF_STATUS)
outp += sprintf(outp, " PKG_%%");
outp += sprintf(outp, " PKG_%% ");
if (do_rapl & RAPL_DRAM_PERF_STATUS)
outp += sprintf(outp, " RAM_%%");
outp += sprintf(outp, " RAM_%% ");
} else {
if (do_rapl & RAPL_PKG)
outp += sprintf(outp, " Pkg_J");
outp += sprintf(outp, " Pkg_J ");
if (do_rapl & RAPL_CORES)
outp += sprintf(outp, " Cor_J");
outp += sprintf(outp, " Cor_J ");
if (do_rapl & RAPL_GFX)
outp += sprintf(outp, " GFX_J");
outp += sprintf(outp, " GFX_J ");
if (do_rapl & RAPL_DRAM)
outp += sprintf(outp, " RAM_W");
outp += sprintf(outp, " RAM_W ");
if (do_rapl & RAPL_PKG_PERF_STATUS)
outp += sprintf(outp, " PKG_%%");
outp += sprintf(outp, " PKG_%% ");
if (do_rapl & RAPL_DRAM_PERF_STATUS)
outp += sprintf(outp, " RAM_%%");
outp += sprintf(outp, " time");
outp += sprintf(outp, " RAM_%% ");
outp += sprintf(outp, " time ");
}
outp += sprintf(outp, "\n");
......@@ -410,25 +415,12 @@ int dump_counters(struct thread_data *t, struct core_data *c,
/*
* column formatting convention & formats
* package: "pk" 2 columns %2d
* core: "cor" 3 columns %3d
* CPU: "CPU" 3 columns %3d
* Pkg_W: %6.2
* Cor_W: %6.2
* GFX_W: %5.2
* RAM_W: %5.2
* GHz: "GHz" 3 columns %3.2
* TSC: "TSC" 3 columns %3.2
* SMI: "SMI" 4 columns %4d
* percentage " %pc3" %6.2
* Perf Status percentage: %5.2
* "CTMP" 4 columns %4d
*/
int format_counters(struct thread_data *t, struct core_data *c,
struct pkg_data *p)
{
double interval_float;
char *fmt5, *fmt6;
char *fmt8;
/* if showing only 1st thread in core and this isn't one, bail out */
if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
......@@ -443,65 +435,52 @@ int format_counters(struct thread_data *t, struct core_data *c,
/* topo columns, print blanks on 1st (average) line */
if (t == &average.threads) {
if (show_pkg)
outp += sprintf(outp, " ");
if (show_pkg && show_core)
outp += sprintf(outp, " ");
outp += sprintf(outp, " -");
if (show_core)
outp += sprintf(outp, " ");
outp += sprintf(outp, " -");
if (show_cpu)
outp += sprintf(outp, " " " ");
outp += sprintf(outp, " -");
} else {
if (show_pkg) {
if (p)
outp += sprintf(outp, "%2d", p->package_id);
outp += sprintf(outp, "%8d", p->package_id);
else
outp += sprintf(outp, " ");
outp += sprintf(outp, " -");
}
if (show_pkg && show_core)
outp += sprintf(outp, " ");
if (show_core) {
if (c)
outp += sprintf(outp, "%3d", c->core_id);
outp += sprintf(outp, "%8d", c->core_id);
else
outp += sprintf(outp, " ");
outp += sprintf(outp, " -");
}
if (show_cpu)
outp += sprintf(outp, " %3d", t->cpu_id);
outp += sprintf(outp, "%8d", t->cpu_id);
}
/* AvgMHz */
if (has_aperf)
outp += sprintf(outp, "%8.0f",
1.0 / units * t->aperf / interval_float);
/* %c0 */
if (do_nhm_cstates) {
if (show_pkg || show_core || show_cpu)
outp += sprintf(outp, " ");
if (!skip_c0)
outp += sprintf(outp, "%6.2f", 100.0 * t->mperf/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc);
else
outp += sprintf(outp, " ****");
outp += sprintf(outp, "********");
}
/* GHz */
if (has_aperf) {
if (!aperf_mperf_unstable) {
outp += sprintf(outp, " %3.2f",
1.0 * t->tsc / units * t->aperf /
t->mperf / interval_float);
} else {
if (t->aperf > t->tsc || t->mperf > t->tsc) {
outp += sprintf(outp, " ***");
} else {
outp += sprintf(outp, "%3.1f*",
1.0 * t->tsc /
units * t->aperf /
t->mperf / interval_float);
}
}
}
/* BzyMHz */
if (has_aperf)
outp += sprintf(outp, "%8.0f",
1.0 * t->tsc / units * t->aperf / t->mperf / interval_float);
/* TSC */
outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float);
/* SMI */
if (do_smi)
outp += sprintf(outp, "%4d", t->smi_count);
outp += sprintf(outp, "%8d", t->smi_count);
/* delta */
if (extra_delta_offset32)
......@@ -520,9 +499,9 @@ int format_counters(struct thread_data *t, struct core_data *c,
if (do_nhm_cstates) {
if (!skip_c1)
outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * t->c1/t->tsc);
else
outp += sprintf(outp, " ****");
outp += sprintf(outp, "********");
}
/* print per-core data only for 1st thread in core */
......@@ -530,79 +509,76 @@ int format_counters(struct thread_data *t, struct core_data *c,
goto done;
if (do_nhm_cstates && !do_slm_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * c->c3/t->tsc);
if (do_nhm_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * c->c6/t->tsc);
if (do_snb_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * c->c7/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * c->c7/t->tsc);
if (do_dts)
outp += sprintf(outp, " %4d", c->core_temp_c);
outp += sprintf(outp, "%8d", c->core_temp_c);
/* print per-package data only for 1st core in package */
if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
goto done;
if (do_ptm)
outp += sprintf(outp, " %4d", p->pkg_temp_c);
outp += sprintf(outp, "%8d", p->pkg_temp_c);
if (do_snb_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc);
if (do_nhm_cstates && !do_slm_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc);
if (do_nhm_cstates && !do_slm_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc);
if (do_snb_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc);
if (do_c8_c9_c10) {
outp += sprintf(outp, " %6.2f", 100.0 * p->pc8/t->tsc);
outp += sprintf(outp, " %6.2f", 100.0 * p->pc9/t->tsc);
outp += sprintf(outp, " %6.2f", 100.0 * p->pc10/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * p->pc9/t->tsc);
outp += sprintf(outp, "%8.2f", 100.0 * p->pc10/t->tsc);
}
/*
* If measurement interval exceeds minimum RAPL Joule Counter range,
* indicate that results are suspect by printing "**" in fraction place.
*/
if (interval_float < rapl_joule_counter_range) {
fmt5 = " %5.2f";
fmt6 = " %6.2f";
} else {
fmt5 = " %3.0f**";
fmt6 = " %4.0f**";
}
if (interval_float < rapl_joule_counter_range)
fmt8 = "%8.2f";
else
fmt8 = " %6.0f**";
if (do_rapl && !rapl_joules) {
if (do_rapl & RAPL_PKG)
outp += sprintf(outp, fmt6, p->energy_pkg * rapl_energy_units / interval_float);
outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float);
if (do_rapl & RAPL_CORES)
outp += sprintf(outp, fmt6, p->energy_cores * rapl_energy_units / interval_float);
outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float);
if (do_rapl & RAPL_GFX)
outp += sprintf(outp, fmt5, p->energy_gfx * rapl_energy_units / interval_float);
outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float);
if (do_rapl & RAPL_DRAM)
outp += sprintf(outp, fmt5, p->energy_dram * rapl_energy_units / interval_float);
outp += sprintf(outp, fmt8, p->energy_dram * rapl_energy_units / interval_float);
if (do_rapl & RAPL_PKG_PERF_STATUS)
outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
if (do_rapl & RAPL_DRAM_PERF_STATUS)
outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
} else {
if (do_rapl & RAPL_PKG)
outp += sprintf(outp, fmt6,
outp += sprintf(outp, fmt8,
p->energy_pkg * rapl_energy_units);
if (do_rapl & RAPL_CORES)
outp += sprintf(outp, fmt6,
outp += sprintf(outp, fmt8,
p->energy_cores * rapl_energy_units);
if (do_rapl & RAPL_GFX)
outp += sprintf(outp, fmt5,
outp += sprintf(outp, fmt8,
p->energy_gfx * rapl_energy_units);
if (do_rapl & RAPL_DRAM)
outp += sprintf(outp, fmt5,
outp += sprintf(outp, fmt8,
p->energy_dram * rapl_energy_units);
if (do_rapl & RAPL_PKG_PERF_STATUS)
outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
if (do_rapl & RAPL_DRAM_PERF_STATUS)
outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
outp += sprintf(outp, fmt5, interval_float);
outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
outp += sprintf(outp, fmt8, interval_float);
}
done:
......@@ -1516,6 +1492,9 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
case 0x46: /* HSW */
case 0x37: /* BYT */
case 0x4D: /* AVN */
case 0x3D: /* BDW */
case 0x4F: /* BDX */
case 0x56: /* BDX-DE */
return 1;
case 0x2E: /* Nehalem-EX Xeon - Beckton */
case 0x2F: /* Westmere-EX Xeon - Eagleton */
......@@ -1629,9 +1608,12 @@ void rapl_probe(unsigned int family, unsigned int model)
case 0x3C: /* HSW */
case 0x45: /* HSW */
case 0x46: /* HSW */
case 0x3D: /* BDW */
do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
break;
case 0x3F: /* HSX */
case 0x4F: /* BDX */
case 0x56: /* BDX-DE */
do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
break;
case 0x2D:
......@@ -1875,6 +1857,9 @@ int is_snb(unsigned int family, unsigned int model)
case 0x3F: /* HSW */
case 0x45: /* HSW */
case 0x46: /* HSW */
case 0x3D: /* BDW */
case 0x4F: /* BDX */
case 0x56: /* BDX-DE */
return 1;
}
return 0;
......@@ -1886,7 +1871,8 @@ int has_c8_c9_c10(unsigned int family, unsigned int model)
return 0;
switch (model) {
case 0x45:
case 0x45: /* HSW */
case 0x3D: /* BDW */
return 1;
}
return 0;
......@@ -2455,7 +2441,7 @@ int main(int argc, char **argv)
cmdline(argc, argv);
if (verbose)
fprintf(stderr, "turbostat v3.6 Dec 2, 2013"
fprintf(stderr, "turbostat v3.7 Feb 6, 2014"
" - Len Brown <lenb@kernel.org>\n");
turbostat_init();
......
......@@ -277,7 +277,7 @@ int kvm_timer_hyp_init(void)
host_vtimer_irq = ppi;
err = register_cpu_notifier(&kvm_timer_cpu_nb);
err = __register_cpu_notifier(&kvm_timer_cpu_nb);
if (err) {
kvm_err("Cannot register timer CPU notifier\n");
goto out_free;
......
......@@ -1496,7 +1496,7 @@ int kvm_vgic_hyp_init(void)
goto out;
}
ret = register_cpu_notifier(&vgic_cpu_nb);
ret = __register_cpu_notifier(&vgic_cpu_nb);
if (ret) {
kvm_err("Cannot register vgic CPU notifier\n");
goto out_free_irq;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册