Skip to content

Commit

Permalink
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…davej/cpufreq

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq: (35 commits)
  [CPUFREQ] Prevent p4-clockmod from auto-binding to the ondemand governor.
  [CPUFREQ] Make cpufreq-nforce2 less obnoxious
  [CPUFREQ] p4-clockmod reports wrong frequency.
  [CPUFREQ] powernow-k8: Use a common exit path.
  [CPUFREQ] Change link order of x86 cpufreq modules
  [CPUFREQ] conservative: remove 10x from def_sampling_rate
  [CPUFREQ] conservative: fixup governor to function more like ondemand logic
  [CPUFREQ] conservative: fix dbs_cpufreq_notifier so freq is not locked
  [CPUFREQ] conservative: amend author's email address
  [CPUFREQ] Use swap() in longhaul.c
  [CPUFREQ] checkpatch cleanups for acpi-cpufreq
  [CPUFREQ] powernow-k8: Only print error message once, not per core.
  [CPUFREQ] ondemand/conservative: sanitize sampling_rate restrictions
  [CPUFREQ] ondemand/conservative: deprecate sampling_rate{min,max}
  [CPUFREQ] powernow-k8: Always compile powernow-k8 driver with ACPI support
  [CPUFREQ] Introduce /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_transition_latency
  [CPUFREQ] checkpatch cleanups for powernow-k8
  [CPUFREQ] checkpatch cleanups for ondemand governor.
  [CPUFREQ] checkpatch cleanups for powernow-k7
  [CPUFREQ] checkpatch cleanups for speedstep related drivers.
  ...
  • Loading branch information
torvalds committed Mar 26, 2009
2 parents 8d80ce8 + 36e8abf commit ada19a3
Show file tree
Hide file tree
Showing 30 changed files with 1,372 additions and 995 deletions.
26 changes: 22 additions & 4 deletions Documentation/cpu-freq/governors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,28 @@ accessible parameters:
sampling_rate: measured in uS (10^-6 seconds), this is how often you
want the kernel to look at the CPU usage and to make decisions on
what to do about the frequency. Typically this is set to values of
around '10000' or more.

show_sampling_rate_(min|max): the minimum and maximum sampling rates
available that you may set 'sampling_rate' to.
around '10000' or more. It's default value is (cmp. with users-guide.txt):
transition_latency * 1000
The lowest value you can set is:
transition_latency * 100 or it may get restricted to a value where it
makes not sense for the kernel anymore to poll that often which depends
on your HZ config variable (HZ=1000: max=20000us, HZ=250: max=5000).
Be aware that transition latency is in ns and sampling_rate is in us, so you
get the same sysfs value by default.
Sampling rate should always get adjusted considering the transition latency
To set the sampling rate 750 times as high as the transition latency
in the bash (as said, 1000 is default), do:
echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) \
>ondemand/sampling_rate

show_sampling_rate_(min|max): THIS INTERFACE IS DEPRECATED, DON'T USE IT.
You can use wider ranges now and the general
cpuinfo_transition_latency variable (cmp. with user-guide.txt) can be
used to obtain exactly the same info:
show_sampling_rate_min = transtition_latency * 500 / 1000
show_sampling_rate_max = transtition_latency * 500000 / 1000
(divided by 1000 is to illustrate that sampling rate is in us and
transition latency is exported ns).

up_threshold: defines what the average CPU usage between the samplings
of 'sampling_rate' needs to be for the kernel to make a decision on
Expand Down
12 changes: 12 additions & 0 deletions Documentation/cpu-freq/user-guide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,18 @@ cpuinfo_min_freq : this file shows the minimum operating
frequency the processor can run at(in kHz)
cpuinfo_max_freq : this file shows the maximum operating
frequency the processor can run at(in kHz)
cpuinfo_transition_latency The time it takes on this CPU to
switch between two frequencies in nano
seconds. If unknown or known to be
that high that the driver does not
work with the ondemand governor, -1
(CPUFREQ_ETERNAL) will be returned.
Using this information can be useful
to choose an appropriate polling
frequency for a kernel governor or
userspace daemon. Make sure to not
switch the frequency too often
resulting in performance loss.
scaling_driver : this file shows what cpufreq driver is
used to set the frequency on this CPU

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ unsigned long native_calibrate_tsc(void);

#ifdef CONFIG_X86_32
extern int timer_ack;
#endif
extern int recalibrate_cpu_khz(void);
#endif /* CONFIG_X86_32 */

extern int no_timer_check;

Expand Down
19 changes: 2 additions & 17 deletions arch/x86/kernel/cpu/cpufreq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -87,30 +87,15 @@ config X86_POWERNOW_K7_ACPI
config X86_POWERNOW_K8
tristate "AMD Opteron/Athlon64 PowerNow!"
select CPU_FREQ_TABLE
depends on ACPI && ACPI_PROCESSOR
help
This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors.

To compile this driver as a module, choose M here: the
module will be called powernow-k8.

For details, take a look at <file:Documentation/cpu-freq/>.

If in doubt, say N.

config X86_POWERNOW_K8_ACPI
bool
prompt "ACPI Support" if X86_32
depends on ACPI && X86_POWERNOW_K8 && ACPI_PROCESSOR
depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m)
default y
help
This provides access to the K8s Processor Performance States via ACPI.
This driver is probably required for CPUFreq to work with multi-socket and
SMP systems. It is not required on at least some single-socket yet
multi-core systems, even if SMP is enabled.

It is safe to say Y here.

config X86_GX_SUSPMOD
tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
depends on X86_32 && PCI
Expand Down
8 changes: 6 additions & 2 deletions arch/x86/kernel/cpu/cpufreq/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
# K8 systems. ACPI is preferred to all other hardware-specific drivers.
# speedstep-* is preferred over p4-clockmod.

obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o
obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
Expand All @@ -10,7 +15,6 @@ obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o
obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
36 changes: 18 additions & 18 deletions arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
* acpi-cpufreq.c - ACPI Processor P-States Driver
*
* Copyright (C) 2001, 2002 Andy Grover <[email protected]>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
Expand Down Expand Up @@ -36,16 +36,18 @@
#include <linux/ftrace.h>

#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/uaccess.h>

#include <acpi/processor.h>

#include <asm/io.h>
#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>
#include <asm/delay.h>
#include <asm/uaccess.h>

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
"acpi-cpufreq", msg)

MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
MODULE_DESCRIPTION("ACPI Processor P-States Driver");
Expand Down Expand Up @@ -95,7 +97,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)

perf = data->acpi_data;

for (i=0; i<perf->state_count; i++) {
for (i = 0; i < perf->state_count; i++) {
if (value == perf->states[i].status)
return data->freq_table[i].frequency;
}
Expand All @@ -110,7 +112,7 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
msr &= INTEL_MSR_RANGE;
perf = data->acpi_data;

for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
if (msr == perf->states[data->freq_table[i].index].status)
return data->freq_table[i].frequency;
}
Expand Down Expand Up @@ -138,15 +140,13 @@ struct io_addr {
u8 bit_width;
};

typedef union {
struct msr_addr msr;
struct io_addr io;
} drv_addr_union;

struct drv_cmd {
unsigned int type;
const struct cpumask *mask;
drv_addr_union addr;
union {
struct msr_addr msr;
struct io_addr io;
} addr;
u32 val;
};

Expand Down Expand Up @@ -369,7 +369,7 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
unsigned int cur_freq;
unsigned int i;

for (i=0; i<100; i++) {
for (i = 0; i < 100; i++) {
cur_freq = extract_freq(get_cur_val(mask), data);
if (cur_freq == freq)
return 1;
Expand Down Expand Up @@ -494,7 +494,7 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
unsigned long freq;
unsigned long freqn = perf->states[0].core_frequency * 1000;

for (i=0; i<(perf->state_count-1); i++) {
for (i = 0; i < (perf->state_count-1); i++) {
freq = freqn;
freqn = perf->states[i+1].core_frequency * 1000;
if ((2 * cpu_khz) > (freqn + freq)) {
Expand Down Expand Up @@ -673,7 +673,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)

/* detect transition latency */
policy->cpuinfo.transition_latency = 0;
for (i=0; i<perf->state_count; i++) {
for (i = 0; i < perf->state_count; i++) {
if ((perf->states[i].transition_latency * 1000) >
policy->cpuinfo.transition_latency)
policy->cpuinfo.transition_latency =
Expand All @@ -682,8 +682,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)

data->max_freq = perf->states[0].core_frequency * 1000;
/* table init */
for (i=0; i<perf->state_count; i++) {
if (i>0 && perf->states[i].core_frequency >=
for (i = 0; i < perf->state_count; i++) {
if (i > 0 && perf->states[i].core_frequency >=
data->freq_table[valid_states-1].frequency / 1000)
continue;

Expand Down
54 changes: 29 additions & 25 deletions arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* nforce2_chipset:
* FSB is changed using the chipset
*/
static struct pci_dev *nforce2_chipset_dev;
static struct pci_dev *nforce2_dev;

/* fid:
* multiplier * 10
Expand All @@ -56,7 +56,9 @@ MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)");
MODULE_PARM_DESC(min_fsb,
"Minimum FSB to use, if not defined: current FSB - 50");

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg)
#define PFX "cpufreq-nforce2: "
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
"cpufreq-nforce2", msg)

/**
* nforce2_calc_fsb - calculate FSB
Expand Down Expand Up @@ -118,11 +120,11 @@ static void nforce2_write_pll(int pll)
int temp;

/* Set the pll addr. to 0x00 */
pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, 0);
pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0);

/* Now write the value in all 64 registers */
for (temp = 0; temp <= 0x3f; temp++)
pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, pll);
pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll);

return;
}
Expand All @@ -139,22 +141,22 @@ static unsigned int nforce2_fsb_read(int bootfsb)
u32 fsb, temp = 0;

/* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */
nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
0x01EF, PCI_ANY_ID, PCI_ANY_ID, NULL);
nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, 0x01EF,
PCI_ANY_ID, PCI_ANY_ID, NULL);
if (!nforce2_sub5)
return 0;

pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb);
fsb /= 1000000;

/* Check if PLL register is already set */
pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);

if (bootfsb || !temp)
return fsb;

/* Use PLL register FSB value */
pci_read_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, &temp);
pci_read_config_dword(nforce2_dev, NFORCE2_PLLREG, &temp);
fsb = nforce2_calc_fsb(temp);

return fsb;
Expand All @@ -174,18 +176,18 @@ static int nforce2_set_fsb(unsigned int fsb)
int pll = 0;

if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
printk(KERN_ERR PFX "FSB %d is out of range!\n", fsb);
return -EINVAL;
}

tfsb = nforce2_fsb_read(0);
if (!tfsb) {
printk(KERN_ERR "cpufreq: Error while reading the FSB\n");
printk(KERN_ERR PFX "Error while reading the FSB\n");
return -EINVAL;
}

/* First write? Then set actual value */
pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
if (!temp) {
pll = nforce2_calc_pll(tfsb);

Expand All @@ -197,7 +199,7 @@ static int nforce2_set_fsb(unsigned int fsb)

/* Enable write access */
temp = 0x01;
pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8)temp);
pci_write_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8)temp);

diff = tfsb - fsb;

Expand All @@ -222,7 +224,7 @@ static int nforce2_set_fsb(unsigned int fsb)
}

temp = 0x40;
pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLADR, (u8)temp);
pci_write_config_byte(nforce2_dev, NFORCE2_PLLADR, (u8)temp);

return 0;
}
Expand All @@ -244,7 +246,8 @@ static unsigned int nforce2_get(unsigned int cpu)
* nforce2_target - set a new CPUFreq policy
* @policy: new policy
* @target_freq: the target frequency
* @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
* @relation: how that frequency relates to achieved frequency
* (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* Sets a new CPUFreq policy.
*/
Expand Down Expand Up @@ -276,7 +279,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
/* local_irq_save(flags); */

if (nforce2_set_fsb(target_fsb) < 0)
printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n",
printk(KERN_ERR PFX "Changing FSB to %d failed\n",
target_fsb);
else
dprintk("Changed FSB successfully to %d\n",
Expand Down Expand Up @@ -327,8 +330,8 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy)
/* FIX: Get FID from CPU */
if (!fid) {
if (!cpu_khz) {
printk(KERN_WARNING
"cpufreq: cpu_khz not set, can't calculate multiplier!\n");
printk(KERN_WARNING PFX
"cpu_khz not set, can't calculate multiplier!\n");
return -ENODEV;
}

Expand All @@ -343,7 +346,7 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy)
}
}

printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb,
printk(KERN_INFO PFX "FSB currently at %i MHz, FID %d.%d\n", fsb,
fid / 10, fid % 10);

/* Set maximum FSB to FSB at boot time */
Expand Down Expand Up @@ -392,17 +395,18 @@ static struct cpufreq_driver nforce2_driver = {
*/
static unsigned int nforce2_detect_chipset(void)
{
nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NFORCE2,
PCI_ANY_ID, PCI_ANY_ID, NULL);

if (nforce2_chipset_dev == NULL)
if (nforce2_dev == NULL)
return -ENODEV;

printk(KERN_INFO "cpufreq: Detected nForce2 chipset revision %X\n",
nforce2_chipset_dev->revision);
printk(KERN_INFO
"cpufreq: FSB changing is maybe unstable and can lead to crashes and data loss.\n");
printk(KERN_INFO PFX "Detected nForce2 chipset revision %X\n",
nforce2_dev->revision);
printk(KERN_INFO PFX
"FSB changing is maybe unstable and can lead to "
"crashes and data loss.\n");

return 0;
}
Expand All @@ -420,7 +424,7 @@ static int __init nforce2_init(void)

/* detect chipset */
if (nforce2_detect_chipset()) {
printk(KERN_ERR "cpufreq: No nForce2 chipset.\n");
printk(KERN_INFO PFX "No nForce2 chipset.\n");
return -ENODEV;
}

Expand Down
Loading

0 comments on commit ada19a3

Please sign in to comment.