Commit 055f27cd authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-dj.bkbits.net/cpufreq

into home.transmeta.com:/home/torvalds/v2.5/linux
parents f8546efb 4656c707
......@@ -35,6 +35,10 @@ speed limits (like LCD drivers on ARM architecture). Additionally, the
kernel "constant" loops_per_jiffy is updated on frequency changes
here.
Reference counting is done by cpufreq_get_cpu and cpufreq_put_cpu,
which make sure that the cpufreq processor driver is correctly
registered with the core, and will not be unloaded until
cpufreq_put_cpu is called.
2. CPUFreq notifiers
====================
......
......@@ -63,6 +63,9 @@ And optionally
cpufreq_driver.exit - A pointer to a per-CPU cleanup function.
cpufreq_driver.attr - A pointer to a NULL-terminated list of
"struct freq_attr" which allow to
export values to sysfs.
1.2 Per-CPU Initialization
......
......@@ -114,9 +114,9 @@ the processor shall run at.
------------------------------
The preferred interface is located in the sysfs filesystem. If you
mounted it at /sys, the cpufreq interface is located in the
cpu-device directory (e.g. /sys/devices/sys/cpu0/ for the first
CPU).
mounted it at /sys, the cpufreq interface is located in a subdirectory
"cpufreq" within the cpu-device directory
(e.g. /sys/devices/sys/cpu0/cpufreq/ for the first CPU).
cpuinfo_min_freq : this file shows the minimum operating
frequency the processor can run at(in kHz)
......@@ -125,7 +125,7 @@ cpuinfo_max_freq : this file shows the maximum operating
scaling_driver : this file shows what cpufreq driver is
used to set the frequency on this CPU
available_scaling_governors : this file shows the CPUfreq governors
scaling_available_governors : this file shows the CPUfreq governors
available in this kernel. You can see the
currently activated governor in
......
......@@ -619,6 +619,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
.name = "acpi-cpufreq",
.owner = THIS_MODULE,
};
......
......@@ -250,6 +250,7 @@ static struct cpufreq_driver elanfreq_driver = {
.target = elanfreq_target,
.init = elanfreq_cpu_init,
.name = "elanfreq",
.owner = THIS_MODULE,
};
......
......@@ -451,6 +451,7 @@ static struct cpufreq_driver gx_suspmod_driver = {
.target = cpufreq_gx_target,
.init = cpufreq_gx_cpu_init,
.name = "gx-suspmod",
.owner = THIS_MODULE,
};
static int __init cpufreq_gx_init(void)
......
......@@ -649,6 +649,7 @@ static struct cpufreq_driver longhaul_driver = {
.target = longhaul_target,
.init = longhaul_cpu_init,
.name = "longhaul",
.owner = THIS_MODULE,
};
static int __init longhaul_init (void)
......
......@@ -253,6 +253,7 @@ static struct cpufreq_driver longrun_driver = {
.setpolicy = longrun_set_policy,
.init = longrun_cpu_init,
.name = "longrun",
.owner = THIS_MODULE,
};
......
......@@ -214,6 +214,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
else
p4clockmod_table[i].frequency = (stock_freq * i)/8;
}
cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu);
/* cpuinfo and default policy values */
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
......@@ -226,9 +227,14 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy)
{
cpufreq_frequency_table_put_attr(policy->cpu);
return cpufreq_p4_setdc(policy->cpu, DC_DISABLE);
}
static struct freq_attr* p4clockmod_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
static struct cpufreq_driver p4clockmod_driver = {
.verify = cpufreq_p4_verify,
......@@ -236,6 +242,8 @@ static struct cpufreq_driver p4clockmod_driver = {
.init = cpufreq_p4_cpu_init,
.exit = cpufreq_p4_cpu_exit,
.name = "p4-clockmod",
.owner = THIS_MODULE,
.attr = p4clockmod_attr,
};
......
......@@ -190,6 +190,7 @@ static struct cpufreq_driver powernow_k6_driver = {
.init = powernow_k6_cpu_init,
.exit = powernow_k6_cpu_exit,
.name = "powernow-k6",
.owner = THIS_MODULE,
};
......
......@@ -377,6 +377,7 @@ static struct cpufreq_driver powernow_driver = {
.target = powernow_target,
.init = powernow_cpu_init,
.name = "powernow-k7",
.owner = THIS_MODULE,
};
static int __init powernow_init (void)
......
......@@ -29,7 +29,6 @@
#include <asm/msr.h>
/* speedstep_chipset:
* It is necessary to know which chipset is used. As accesses to
* this device occur at various places in this module, we need a
......@@ -40,7 +39,7 @@ static struct pci_dev *speedstep_chipset_dev;
#define SPEEDSTEP_CHIPSET_ICH2M 0x00000002
#define SPEEDSTEP_CHIPSET_ICH3M 0x00000003
#define SPEEDSTEP_CHIPSET_ICH4M 0x00000004
/* speedstep_processor
*/
......@@ -106,6 +105,7 @@ static int speedstep_get_state (unsigned int *state)
switch (speedstep_chipset) {
case SPEEDSTEP_CHIPSET_ICH2M:
case SPEEDSTEP_CHIPSET_ICH3M:
case SPEEDSTEP_CHIPSET_ICH4M:
/* get PMBASE */
pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
if (!(pmbase & 0x01))
......@@ -166,6 +166,7 @@ static void speedstep_set_state (unsigned int state, int notify)
switch (speedstep_chipset) {
case SPEEDSTEP_CHIPSET_ICH2M:
case SPEEDSTEP_CHIPSET_ICH3M:
case SPEEDSTEP_CHIPSET_ICH4M:
/* get PMBASE */
pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
if (!(pmbase & 0x01))
......@@ -245,6 +246,7 @@ static int speedstep_activate (void)
switch (speedstep_chipset) {
case SPEEDSTEP_CHIPSET_ICH2M:
case SPEEDSTEP_CHIPSET_ICH3M:
case SPEEDSTEP_CHIPSET_ICH4M:
{
u16 value = 0;
......@@ -276,6 +278,14 @@ static int speedstep_activate (void)
*/
static unsigned int speedstep_detect_chipset (void)
{
speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82801DB_12,
PCI_ANY_ID,
PCI_ANY_ID,
NULL);
if (speedstep_chipset_dev)
return SPEEDSTEP_CHIPSET_ICH4M;
speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82801CA_12,
PCI_ANY_ID,
......@@ -658,6 +668,7 @@ static struct cpufreq_driver speedstep_driver = {
.verify = speedstep_verify,
.target = speedstep_target,
.init = speedstep_cpu_init,
.owner = THIS_MODULE,
};
......
......@@ -276,6 +276,7 @@ static int __init us3freq_init(void)
driver->target = us3freq_target;
driver->init = us3freq_cpu_init;
driver->exit = us3freq_cpu_exit;
driver->owner = THIS_MODULE,
strcpy(driver->name, "UltraSPARC-III");
cpufreq_us3_driver = driver;
......
......@@ -77,56 +77,6 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
int cpufreq_frequency_table_setpolicy(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table,
unsigned int *index)
{
struct cpufreq_frequency_table optimal = { .index = ~0, };
unsigned int i;
switch (policy->policy) {
case CPUFREQ_POLICY_PERFORMANCE:
optimal.frequency = 0;
break;
case CPUFREQ_POLICY_POWERSAVE:
optimal.frequency = ~0;
break;
}
if (!cpu_online(policy->cpu))
return -EINVAL;
for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
if ((freq < policy->min) || (freq > policy->max))
continue;
switch(policy->policy) {
case CPUFREQ_POLICY_PERFORMANCE:
if (optimal.frequency <= freq) {
optimal.frequency = freq;
optimal.index = i;
}
break;
case CPUFREQ_POLICY_POWERSAVE:
if (optimal.frequency >= freq) {
optimal.frequency = freq;
optimal.index = i;
}
break;
}
}
if (optimal.index > i)
return -EINVAL;
*index = optimal.index;
return 0;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_setpolicy);
int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table,
unsigned int target_freq,
......@@ -197,6 +147,56 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
static struct cpufreq_frequency_table *show_table[NR_CPUS];
/**
* show_scaling_governor - show the current policy for the specified CPU
*/
static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
{
unsigned int i = 0;
unsigned int cpu = policy->cpu;
ssize_t count = 0;
struct cpufreq_frequency_table *table;
if (!show_table[cpu])
return -ENODEV;
table = show_table[cpu];
for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
continue;
count += sprintf(&buf[count], "%d ", table[i].frequency);
}
count += sprintf(&buf[count], "\n");
return count;
}
struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
.attr = { .name = "scaling_available_frequencies", .mode = 0444 },
.show = show_available_freqs,
};
EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs);
/*
* if you use these, you must assure that the frequency table is valid
* all the time between get_attr and put_attr!
*/
void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
unsigned int cpu)
{
show_table[cpu] = table;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr);
void cpufreq_frequency_table_put_attr(unsigned int cpu)
{
show_table[cpu] = NULL;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
......
......@@ -23,6 +23,7 @@
#include <linux/sysctl.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/sysfs.h>
#include <asm/uaccess.h>
......@@ -112,7 +113,7 @@ int cpufreq_set(unsigned int freq, unsigned int cpu)
if (freq > cpu_max_freq[cpu])
freq = cpu_max_freq[cpu];
ret = cpufreq_driver_target_l(&current_policy[cpu], freq,
ret = cpufreq_driver_target(&current_policy[cpu], freq,
CPUFREQ_RELATION_L);
err:
......@@ -465,23 +466,14 @@ static inline void cpufreq_sysctl_exit(void)
/************************** sysfs interface ************************/
static inline int to_cpu_nr (struct device *dev)
static ssize_t show_speed (struct cpufreq_policy *policy, char *buf)
{
struct sys_device * cpu_sys_dev = container_of(dev, struct sys_device, dev);
return (cpu_sys_dev->id);
}
static ssize_t show_speed (struct device *dev, char *buf)
{
unsigned int cpu = to_cpu_nr(dev);
return sprintf (buf, "%u\n", cpu_cur_freq[cpu]);
return sprintf (buf, "%u\n", cpu_cur_freq[policy->cpu]);
}
static ssize_t
store_speed (struct device *dev, const char *buf, size_t count)
store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
{
unsigned int cpu = to_cpu_nr(dev);
unsigned int freq = 0;
unsigned int ret;
......@@ -489,13 +481,16 @@ store_speed (struct device *dev, const char *buf, size_t count)
if (ret != 1)
return -EINVAL;
cpufreq_set(freq, cpu);
cpufreq_set(freq, policy->cpu);
return count;
}
static DEVICE_ATTR(scaling_setspeed, (S_IRUGO | S_IWUSR), show_speed, store_speed);
static struct freq_attr freq_attr_scaling_setspeed = {
.attr = { .name = "scaling_setspeed", .mode = 0644 },
.show = show_speed,
.store = store_speed,
};
static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
unsigned int event)
......@@ -511,7 +506,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
cpu_min_freq[cpu] = policy->min;
cpu_max_freq[cpu] = policy->max;
cpu_cur_freq[cpu] = policy->cur;
device_create_file (policy->dev, &dev_attr_scaling_setspeed);
sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
up(&userspace_sem);
break;
......@@ -520,7 +515,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
cpu_is_managed[cpu] = 0;
cpu_min_freq[cpu] = 0;
cpu_max_freq[cpu] = 0;
device_remove_file (policy->dev, &dev_attr_scaling_setspeed);
sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
up(&userspace_sem);
module_put(THIS_MODULE);
break;
......
......@@ -18,7 +18,8 @@
#include <linux/notifier.h>
#include <linux/threads.h>
#include <linux/device.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#define CPUFREQ_NAME_LEN 16
......@@ -69,6 +70,8 @@ struct cpufreq_policy {
struct cpufreq_cpuinfo cpuinfo; /* see above */
struct device * dev;
struct kobject kobj;
struct semaphore lock; /* CPU ->setpolicy or ->target may
only be called once a time */
};
#define CPUFREQ_ADJUST (0)
......@@ -131,18 +134,13 @@ struct cpufreq_governor {
};
/* pass a target to the cpufreq driver
* _l : (cpufreq_driver_sem is not held)
*/
inline int cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
inline int cpufreq_driver_target_l(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
/* pass an event to the cpufreq governor */
int cpufreq_governor_l(unsigned int cpu, unsigned int event);
int cpufreq_governor(unsigned int cpu, unsigned int event);
int cpufreq_register_governor(struct cpufreq_governor *governor);
void cpufreq_unregister_governor(struct cpufreq_governor *governor);
......@@ -154,6 +152,8 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor);
#define CPUFREQ_RELATION_L 0 /* lowest frequency at or above target */
#define CPUFREQ_RELATION_H 1 /* highest frequency below or at target */
struct freq_attr;
struct cpufreq_driver {
/* needed by all drivers */
int (*verify) (struct cpufreq_policy *policy);
......@@ -164,16 +164,15 @@ struct cpufreq_driver {
int (*target) (struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
struct module *owner;
/* optional, for the moment */
int (*init) (struct cpufreq_policy *policy);
int (*exit) (struct cpufreq_policy *policy);
struct freq_attr **attr;
};
int cpufreq_register_driver(struct cpufreq_driver *driver_data);
int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);
/* deprecated */
#define cpufreq_register(x) cpufreq_register_driver(x)
#define cpufreq_unregister() cpufreq_unregister_driver(NULL)
void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state);
......@@ -194,6 +193,13 @@ static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, u
return;
}
struct freq_attr {
struct attribute attr;
ssize_t (*show)(struct cpufreq_policy *, char *);
ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
};
/*********************************************************************
* CPUFREQ 2.6. INTERFACE *
*********************************************************************/
......@@ -289,16 +295,21 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table);
int cpufreq_frequency_table_setpolicy(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table,
unsigned int *index);
int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table,
unsigned int target_freq,
unsigned int relation,
unsigned int *index);
/* the following are really really optional */
extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
unsigned int cpu);
void cpufreq_frequency_table_put_attr(unsigned int cpu);
#endif /* CONFIG_CPU_FREQ_TABLE */
#endif /* _LINUX_CPUFREQ_H */
......@@ -1854,6 +1854,7 @@
#define PCI_DEVICE_ID_INTEL_82801DB_7 0x24c7
#define PCI_DEVICE_ID_INTEL_82801DB_9 0x24cb
#define PCI_DEVICE_ID_INTEL_82801DB_11 PCI_DEVICE_ID_INTEL_82801DB_9
#define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc
#define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd
#define PCI_DEVICE_ID_INTEL_82820_HB 0x2500
#define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment