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:
  [ACPI/CPUFREQ] Introduce bios_limit per cpu cpufreq sysfs interface
  [CPUFREQ] make internal cpufreq_add_dev_* static
  [CPUFREQ] use an enum for speedstep processor identification
  [CPUFREQ] Document units for transition latency
  [CPUFREQ] Use global sysfs cpufreq structure for conservative governor tunings
  [CPUFREQ] Documentation: ABI: /sys/devices/system/cpu/cpu#/cpufreq/
  [CPUFREQ] powernow-k6: set transition latency value so ondemand governor can be used
  [CPUFREQ] cpumask: don't put a cpumask on the stack in x86...cpufreq/powernow-k8.c
  • Loading branch information
Linus Torvalds committed Dec 11, 2009
2 parents cb5228a + e2f74f3 commit 2fe77b8
Show file tree
Hide file tree
Showing 16 changed files with 248 additions and 74 deletions.
18 changes: 18 additions & 0 deletions Documentation/ABI/testing/sysfs-devices-system-cpu
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,24 @@ Description: Discover cpuidle policy and mechanism
See files in Documentation/cpuidle/ for more information.


What: /sys/devices/system/cpu/cpu#/cpufreq/*
Date: pre-git history
Contact: cpufreq@vger.kernel.org
Description: Discover and change clock speed of CPUs

Clock scaling allows you to change the clock speed of the
CPUs on the fly. This is a nice method to save battery
power, because the lower the clock speed, the less power
the CPU consumes.

There are many knobs to tweak in this directory.

See files in Documentation/cpu-freq/ for more information.

In particular, read Documentation/cpu-freq/user-guide.txt
to learn how to control the knobs.


What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
Date: August 2008
KernelVersion: 2.6.27
Expand Down
6 changes: 3 additions & 3 deletions Documentation/cpu-freq/cpu-drivers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ policy->cpuinfo.max_freq - the minimum and maximum frequency
(in kHz) which is supported by
this CPU
policy->cpuinfo.transition_latency the time it takes on this CPU to
switch between two frequencies (if
appropriate, else specify
CPUFREQ_ETERNAL)
switch between two frequencies in
nanoseconds (if appropriate, else
specify CPUFREQ_ETERNAL)

policy->cur The current operating frequency of
this CPU (if appropriate)
Expand Down
11 changes: 11 additions & 0 deletions Documentation/cpu-freq/user-guide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ scaling_cur_freq : Current frequency of the CPU as determined by
the frequency the kernel thinks the CPU runs
at.

bios_limit : If the BIOS tells the OS to limit a CPU to
lower frequencies, the user can read out the
maximum available frequency from this file.
This typically can happen through (often not
intended) BIOS settings, restrictions
triggered through a service processor or other
BIOS/HW based implementations.
This does not cover thermal ACPI limitations
which can be detected through the generic
thermal driver.

If you have selected the "userspace" governor which allows you to
set the CPU operating frequency to a specific value, you can read out
the current frequency in
Expand Down
17 changes: 9 additions & 8 deletions arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,14 +764,15 @@ static struct freq_attr *acpi_cpufreq_attr[] = {
};

static struct cpufreq_driver acpi_cpufreq_driver = {
.verify = acpi_cpufreq_verify,
.target = acpi_cpufreq_target,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
.resume = acpi_cpufreq_resume,
.name = "acpi-cpufreq",
.owner = THIS_MODULE,
.attr = acpi_cpufreq_attr,
.verify = acpi_cpufreq_verify,
.target = acpi_cpufreq_target,
.bios_limit = acpi_processor_get_bios_limit,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
.resume = acpi_cpufreq_resume,
.name = "acpi-cpufreq",
.owner = THIS_MODULE,
.attr = acpi_cpufreq_attr,
};

static int __init acpi_cpufreq_init(void)
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/cpufreq/powernow-k6.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
}

/* cpuinfo and default policy values */
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cpuinfo.transition_latency = 200000;
policy->cur = busfreq * max_multiplier;

result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
Expand Down
19 changes: 11 additions & 8 deletions arch/x86/kernel/cpu/cpufreq/powernow-k7.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,14 +714,17 @@ static struct freq_attr *powernow_table_attr[] = {
};

static struct cpufreq_driver powernow_driver = {
.verify = powernow_verify,
.target = powernow_target,
.get = powernow_get,
.init = powernow_cpu_init,
.exit = powernow_cpu_exit,
.name = "powernow-k7",
.owner = THIS_MODULE,
.attr = powernow_table_attr,
.verify = powernow_verify,
.target = powernow_target,
.get = powernow_get,
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
.bios_limit = acpi_processor_get_bios_limit,
#endif
.init = powernow_cpu_init,
.exit = powernow_cpu_exit,
.name = "powernow-k7",
.owner = THIS_MODULE,
.attr = powernow_table_attr,
};

static int __init powernow_init(void)
Expand Down
32 changes: 19 additions & 13 deletions arch/x86/kernel/cpu/cpufreq/powernow-k8.c
Original file line number Diff line number Diff line change
Expand Up @@ -1118,7 +1118,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
static int powernowk8_target(struct cpufreq_policy *pol,
unsigned targfreq, unsigned relation)
{
cpumask_t oldmask;
cpumask_var_t oldmask;
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
u32 checkfid;
u32 checkvid;
Expand All @@ -1131,9 +1131,13 @@ static int powernowk8_target(struct cpufreq_policy *pol,
checkfid = data->currfid;
checkvid = data->currvid;

/* only run on specific CPU from here on */
oldmask = current->cpus_allowed;
set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu));
/* only run on specific CPU from here on. */
/* This is poor form: use a workqueue or smp_call_function_single */
if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
return -ENOMEM;

cpumask_copy(oldmask, tsk_cpumask(current));
set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));

if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
Expand Down Expand Up @@ -1193,7 +1197,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
ret = 0;

err_out:
set_cpus_allowed_ptr(current, &oldmask);
set_cpus_allowed_ptr(current, oldmask);
free_cpumask_var(oldmask);
return ret;
}

Expand Down Expand Up @@ -1393,14 +1398,15 @@ static struct freq_attr *powernow_k8_attr[] = {
};

static struct cpufreq_driver cpufreq_amd64_driver = {
.verify = powernowk8_verify,
.target = powernowk8_target,
.init = powernowk8_cpu_init,
.exit = __devexit_p(powernowk8_cpu_exit),
.get = powernowk8_get,
.name = "powernow-k8",
.owner = THIS_MODULE,
.attr = powernow_k8_attr,
.verify = powernowk8_verify,
.target = powernowk8_target,
.bios_limit = acpi_processor_get_bios_limit,
.init = powernowk8_cpu_init,
.exit = __devexit_p(powernowk8_cpu_exit),
.get = powernowk8_get,
.name = "powernow-k8",
.owner = THIS_MODULE,
.attr = powernow_k8_attr,
};

/* driver entry point for init */
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static struct pci_dev *speedstep_chipset_dev;

/* speedstep_processor
*/
static unsigned int speedstep_processor;
static enum speedstep_processor speedstep_processor;

static u32 pmbase;

Expand Down
6 changes: 3 additions & 3 deletions arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static int relaxed_check;
* GET PROCESSOR CORE SPEED IN KHZ *
*********************************************************************/

static unsigned int pentium3_get_frequency(unsigned int processor)
static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
{
/* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
struct {
Expand Down Expand Up @@ -227,7 +227,7 @@ static unsigned int pentium4_get_frequency(void)


/* Warning: may get called from smp_call_function_single. */
unsigned int speedstep_get_frequency(unsigned int processor)
unsigned int speedstep_get_frequency(enum speedstep_processor processor)
{
switch (processor) {
case SPEEDSTEP_CPU_PCORE:
Expand Down Expand Up @@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor);
* DETECT SPEEDSTEP SPEEDS *
*********************************************************************/

unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int speedstep_get_freqs(enum speedstep_processor processor,
unsigned int *low_speed,
unsigned int *high_speed,
unsigned int *transition_latency,
Expand Down
24 changes: 12 additions & 12 deletions arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@


/* processors */

#define SPEEDSTEP_CPU_PIII_C_EARLY 0x00000001 /* Coppermine core */
#define SPEEDSTEP_CPU_PIII_C 0x00000002 /* Coppermine core */
#define SPEEDSTEP_CPU_PIII_T 0x00000003 /* Tualatin core */
#define SPEEDSTEP_CPU_P4M 0x00000004 /* P4-M */

enum speedstep_processor {
SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001, /* Coppermine core */
SPEEDSTEP_CPU_PIII_C = 0x00000002, /* Coppermine core */
SPEEDSTEP_CPU_PIII_T = 0x00000003, /* Tualatin core */
SPEEDSTEP_CPU_P4M = 0x00000004, /* P4-M */
/* the following processors are not speedstep-capable and are not auto-detected
* in speedstep_detect_processor(). However, their speed can be detected using
* the speedstep_get_frequency() call. */
#define SPEEDSTEP_CPU_PM 0xFFFFFF03 /* Pentium M */
#define SPEEDSTEP_CPU_P4D 0xFFFFFF04 /* desktop P4 */
#define SPEEDSTEP_CPU_PCORE 0xFFFFFF05 /* Core */
SPEEDSTEP_CPU_PM = 0xFFFFFF03, /* Pentium M */
SPEEDSTEP_CPU_P4D = 0xFFFFFF04, /* desktop P4 */
SPEEDSTEP_CPU_PCORE = 0xFFFFFF05, /* Core */
};

/* speedstep states -- only two of them */

Expand All @@ -31,18 +31,18 @@


/* detect a speedstep-capable processor */
extern unsigned int speedstep_detect_processor (void);
extern enum speedstep_processor speedstep_detect_processor(void);

/* detect the current speed (in khz) of the processor */
extern unsigned int speedstep_get_frequency(unsigned int processor);
extern unsigned int speedstep_get_frequency(enum speedstep_processor processor);


/* detect the low and high speeds of the processor. The callback
* set_state"'s first argument is either SPEEDSTEP_HIGH or
* SPEEDSTEP_LOW; the second argument is zero so that no
* cpufreq_notify_transition calls are initiated.
*/
extern unsigned int speedstep_get_freqs(unsigned int processor,
extern unsigned int speedstep_get_freqs(enum speedstep_processor processor,
unsigned int *low_speed,
unsigned int *high_speed,
unsigned int *transition_latency,
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static int smi_cmd;
static unsigned int smi_sig;

/* info about the processor */
static unsigned int speedstep_processor;
static enum speedstep_processor speedstep_processor;

/*
* There are only two frequency states for each processor. Values
Expand Down
13 changes: 13 additions & 0 deletions drivers/acpi/processor_perflib.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,19 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
return cpufreq_update_policy(pr->id);
}

int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
{
struct acpi_processor *pr;

pr = per_cpu(processors, cpu);
if (!pr || !pr->performance || !pr->performance->state_count)
return -ENODEV;
*limit = pr->performance->states[pr->performance_platform_limit].
core_frequency * 1000;
return 0;
}
EXPORT_SYMBOL(acpi_processor_get_bios_limit);

void acpi_processor_ppc_init(void)
{
if (!cpufreq_register_notifier
Expand Down
34 changes: 29 additions & 5 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,21 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
return policy->governor->show_setspeed(policy, buf);
}

/**
* show_scaling_driver - show the current cpufreq HW/BIOS limitation
*/
static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
{
unsigned int limit;
int ret;
if (cpufreq_driver->bios_limit) {
ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
if (!ret)
return sprintf(buf, "%u\n", limit);
}
return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
}

#define define_one_ro(_name) \
static struct freq_attr _name = \
__ATTR(_name, 0444, show_##_name, NULL)
Expand All @@ -666,6 +681,7 @@ define_one_ro(cpuinfo_transition_latency);
define_one_ro(scaling_available_governors);
define_one_ro(scaling_driver);
define_one_ro(scaling_cur_freq);
define_one_ro(bios_limit);
define_one_ro(related_cpus);
define_one_ro(affected_cpus);
define_one_rw(scaling_min_freq);
Expand Down Expand Up @@ -767,8 +783,9 @@ static struct kobj_type ktype_cpufreq = {
* 0: Success
* Positive: When we have a managed CPU and the sysfs got symlinked
*/
int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
struct sys_device *sys_dev)
static int cpufreq_add_dev_policy(unsigned int cpu,
struct cpufreq_policy *policy,
struct sys_device *sys_dev)
{
int ret = 0;
#ifdef CONFIG_SMP
Expand Down Expand Up @@ -842,7 +859,8 @@ int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,


/* symlink affected CPUs */
int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy)
static int cpufreq_add_dev_symlink(unsigned int cpu,
struct cpufreq_policy *policy)
{
unsigned int j;
int ret = 0;
Expand All @@ -869,8 +887,9 @@ int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy)
return ret;
}

int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
struct sys_device *sys_dev)
static int cpufreq_add_dev_interface(unsigned int cpu,
struct cpufreq_policy *policy,
struct sys_device *sys_dev)
{
struct cpufreq_policy new_policy;
struct freq_attr **drv_attr;
Expand Down Expand Up @@ -902,6 +921,11 @@ int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
if (ret)
goto err_out_kobj_put;
}
if (cpufreq_driver->bios_limit) {
ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
if (ret)
goto err_out_kobj_put;
}

spin_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu(j, policy->cpus) {
Expand Down
Loading

0 comments on commit 2fe77b8

Please sign in to comment.