Commit 7e285bef authored by Linus Torvalds's avatar Linus Torvalds

Merge home.transmeta.com:/home/torvalds/v2.5/hotplug

into home.transmeta.com:/home/torvalds/v2.5/linux
parents c198a0a4 bcca07c1
......@@ -56,6 +56,8 @@ computone.txt
- info on Computone Intelliport II/Plus Multiport Serial Driver
cpqarray.txt
- info on using Compaq's SMART2 Intelligent Disk Array Controllers.
cpufreq/
- info on CPU frequency and voltage scaling
cris/
- directory with info about Linux on CRIS architecture.
devices.txt
......
CPU frequency and voltage scaling code in the Linux(TM) kernel
L i n u x C P U F r e q
C P U F r e q C o r e
Dominik Brodowski <linux@brodo.de>
David Kimdon <dwhedon@debian.org>
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.
Contents:
---------
1. CPUFreq core and interfaces
2. CPUFreq notifiers
1. General Information
=======================
The CPUFreq core code is located in linux/kernel/cpufreq.c. This
cpufreq code offers a standardized interface for the CPUFreq
architecture drivers (those pieces of code that do actual
frequency transitions), as well as to "notifiers". These are device
drivers or other part of the kernel that need to be informed of
policy changes (ex. thermal modules like ACPI) or of all
frequency changes (ex. timing code) or even need to force certain
speed limits (like LCD drivers on ARM architecture). Additionally, the
kernel "constant" loops_per_jiffy is updated on frequency changes
here.
2. CPUFreq notifiers
====================
CPUFreq notifiers conform to the standard kernel notifier interface.
See linux/include/linux/notifier.h for details on notifiers.
There are two different CPUFreq notifiers - policy notifiers and
transition notifiers.
2.1 CPUFreq policy notifiers
----------------------------
These are notified when a new policy is intended to be set. Each
CPUFreq policy notifier is called three times for a policy transition:
1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
they see a need for this - may it be thermal considerations or
hardware limitations.
2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
hardware failure.
3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
- if two hardware drivers failed to agree on a new policy before this
stage, the incompatible hardware shall be shut down, and the user
informed of this.
The phase is specified in the second argument to the notifier.
The third argument, a void *pointer, points to a struct cpufreq_policy
consisting of five values: cpu, min, max, policy and max_cpu_freq. min
and max are the lower and upper frequencies (in kHz) of the new
policy, policy the new policy, cpu the number of the affected CPU or
CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
CPU frequency. This value is given for informational purposes only.
2.2 CPUFreq transition notifiers
--------------------------------
These are notified twice when the CPUfreq driver switches the CPU core
frequency and this change has any external implications.
The second argument specifies the phase - CPUFREQ_PRECHANGE or
CPUFREQ_POSTCHANGE.
The third argument is a struct cpufreq_freqs with the following
values:
cpu - number of the affected CPU or CPUFREQ_ALL_CPUS
old - old frequency
new - new frequency
CPU frequency and voltage scaling code in the Linux(TM) kernel
L i n u x C P U F r e q
C P U D r i v e r s
- information for developers -
Dominik Brodowski <linux@brodo.de>
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.
Contents:
---------
1. What To Do?
1.1 Initialization
1.2 Per-CPU Initialization
1.3 verify
1.4 target or setpolicy?
1.5 target
1.6 setpolicy
2. Frequency Table Helpers
1. What To Do?
==============
So, you just got a brand-new CPU / chipset with datasheets and want to
add cpufreq support for this CPU / chipset? Great. Here are some hints
on what is neccessary:
1.1 Initialization
------------------
First of all, in an __initcall level 7 or later (preferrably
module_init() so that your driver is modularized) function check
whether this kernel runs on the right CPU and the right chipset. If
so, register a struct cpufreq_driver with the CPUfreq core using
cpufreq_register_driver()
What shall this struct cpufreq_driver contain?
cpufreq_driver.name - The name of this driver.
cpufreq_driver.init - A pointer to the per-CPU initialization
function.
cpufreq_driver.verify - A pointer to a "verfication" funciton.
cpufreq_driver.setpolicy _or_
cpufreq_driver.target - See below on the differences.
And optionally
cpufreq_driver.exit - A pointer to a per-CPU cleanup function.
1.2 Per-CPU Initialization
--------------------------
Whenever a new CPU is registered with the device model, or after the
cpufreq driver registers itself, the per-CPU initialization fucntion
cpufreq_driver.init is called. It takes a struct cpufreq_policy
*policy as argument. What to do now?
If necessary, activate the CPUfreq support on your CPU (unlock that
register etc.).
Then, the driver must fill in the following values:
policy->cpuinfo.min_freq _and_
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)
policy->cur The current operating frequency of
this CPU (if appropriate)
policy->min,
policy->max,
policy->policy and, if neccessary,
policy->governor must contain the "default policy" for
this CPU. A few moments later,
cpufreq_driver.verify and either
cpufreq_driver.setpolicy or
cpufreq_driver.target is called with
these values.
For setting some of these values, the frequency table helpers might be
helpful. See the section 2 for more information on them.
1.3 verify
------------
When the user decides a new policy (consisting of
"policy,governor,min,max") shall be set, this policy must be validated
so that incompatible values can be corrected. For verifying these
values, a frequency table helper and/or the
cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned
int min_freq, unsigned int max_freq) function might be helpful. See
section 2 for details on frequency table helpers.
You need to make sure that at least one valid frequency (or operating
range) is within policy->min and policy->max. If necessary, increase
policy->max fist, and only if this is no solution, decreas policy->min.
1.4 target or setpolicy?
----------------------------
Most cpufreq drivers or even most cpu frequency scaling algorithms
only allow the CPU to be set to one frequency. For these, you use the
->target call.
Some cpufreq-capable processors switch the frequency between certain
limits on their own. These shall use the ->setpolicy call
1.4. target
-------------
The target call has three arguments: struct cpufreq_policy *policy,
unsigned int target_frequency, unsigned int relation.
The CPUfreq driver must set the new frequency when called here. The
actual frequency must be determined using the following rules:
- keep close to "target_freq"
- policy->min <= new_freq <= policy->max (THIS MUST BE VALID!!!)
- if relation==CPUFREQ_REL_L, try to select a new_freq higher than or equal
target_freq. ("L for lowest, but no lower than")
- if relation==CPUFREQ_REL_H, try to select a new_freq lower than or equal
target_freq. ("H for highest, but no higher than")
Here again the frequency table helper might assist you - see section 3
for details.
1.5 setpolicy
---------------
The setpolicy call only takes a struct cpufreq_policy *policy as
argument. You need to set the lower limit of the in-processor or
in-chipset dynamic frequency switching to policy->min, the upper limit
to policy->max, and -if supported- select a performance-oriented
setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
the reference implementation in arch/i386/kernel/cpu/cpufreq/longrun.c
2. Frequency Table Helpers
==========================
As most cpufreq processors only allow for being set to a few specific
frequencies, a "frequency table" with some functions might assist in
some work of the processor driver. Such a "frequency table" consists
of an array of struct cpufreq_freq_table entries, with any value in
"index" you want to use, and the corresponding frequency in
"frequency". At the end of the table, you need to add a
cpufreq_freq_table entry with frequency set to CPUFREQ_TABLE_END. And
if you want to skip one entry in the table, set the frequency to
CPUFREQ_ENTRY_INVALID. The entries don't need to be in ascending
order.
By calling cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table);
the cpuinfo.min_freq and cpuinfo.max_freq values are detected, and
policy->min and policy->max are set to the same values. This is
helpful for the per-CPU initialization stage.
int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table);
assures that at least one valid frequency is within policy->min and
policy->max, and all other criteria are met. This is helpful for the
->verify call.
int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table,
unsigned int target_freq,
unsigned int relation,
unsigned int *index);
is the corresponding frequency table helper for the ->target
stage. Just pass the values to this function, and the unsigned int
index returns the number of the frequency table entry which contains
the frequency the CPU shall be set to. PLEASE NOTE: This is not the
"index" which is in this cpufreq_table_entry.index, but instead
cpufreq_table[index]. So, the new frequency is
cpufreq_table[index].frequency, and the value you stored into the
frequency table "index" field is
cpufreq_table[index].index.
CPU frequency and voltage scaling code in the Linux(TM) kernel
L i n u x C P U F r e q
C P U F r e q G o v e r n o r s
- information for users and developers -
Dominik Brodowski <linux@brodo.de>
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.
Contents:
---------
1. What is a CPUFreq Governor?
2. Governors In the Linux Kernel
2.1 Performance
2.2 Powersave
2.3 Userspace
3. The Governor Interface in the CPUfreq Core
1. What Is A CPUFreq Governor?
==============================
Most cpufreq drivers (in fact, all except one, longrun) or even most
cpu frequency scaling algorithms only offer the CPU to be set to one
frequency. In order to offer dynamic frequency scaling, the cpufreq
core must be able to tell these drivers of a "target frequency". So
these specific drivers will be transformed to offer a "->target"
call instead of the existing "->setpolicy" call. For "longrun", all
stays the same, though.
How to decide what frequency within the CPUfreq policy should be used?
That's done using "cpufreq governors". Two are already in this patch
-- they're the already existing "powersave" and "performance" which
set the frequency statically to the lowest or highest frequency,
respectively. At least two more such governors will be ready for
addition in the near future, but likely many more as there are various
different theories and models about dynamic frequency scaling
around. Using such a generic interface as cpufreq offers to scaling
governors, these can be tested extensively, and the best one can be
selected for each specific use.
Basically, it's the following flow graph:
CPU can be set to switch independetly | CPU can only be set
within specific "limits" | to specific frequencies
"CPUfreq policy"
consists of frequency limits (policy->{min,max})
and CPUfreq governor to be used
/ \
/ \
/ the cpufreq governor decides
/ (dynamically or statically)
/ what target_freq to set within
/ the limits of policy->{min,max}
/ \
/ \
Using the ->setpolicy call, Using the ->target call,
the limits and the the frequency closest
"policy" is set. to target_freq is set.
It is assured that it
is within policy->{min,max}
2. Governors In the Linux Kernel
================================
2.1 Performance
---------------
The CPUfreq governor "performance" sets the CPU statically to the
highest frequency within the borders of scaling_min_freq and
scaling_max_freq.
2.1 Powersave
-------------
The CPUfreq governor "powersave" sets the CPU statically to the
lowest frequency within the borders of scaling_min_freq and
scaling_max_freq.
2.2 Userspace
-------------
The CPUfreq governor "userspace" allows the user, or any userspace
program running with UID "root", to set the CPU to a specifc frequency
by making a sysfs file "scaling_setspeed" available in the CPU-device
directory.
3. The Governor Interface in the CPUfreq Core
=============================================
A new governor must register itself with the CPUfreq core using
"cpufreq_register_governor". The struct cpufreq_governor, which has to
be passed to that function, must contain the following values:
governor->name - A unique name for this governor
governor->governor - The governor callback function
governor->owner - .THIS_MODULE for the governor module (if
appropriate)
The governor->governor callback is called with the current (or to-be-set)
cpufreq_policy struct for that CPU, and an unsigned int event. The
following events are currently defined:
CPUFREQ_GOV_START: This governor shall start its duty for the CPU
policy->cpu
CPUFREQ_GOV_STOP: This governor shall end its duty for the CPU
policy->cpu
CPUFREQ_GOV_LIMITS: The limits for CPU policy->cpu have changed to
policy->min and policy->max.
If you need other "events" externally of your driver, _only_ use the
cpufreq_governor_l(unsigned int cpu, unsigned int event) call to the
CPUfreq core to ensure proper locking.
The CPUfreq governor may call the CPU processor driver using one of
these two functions:
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);
target_freq must be within policy->min and policy->max, of course.
What's the difference between these two functions? When your governor
still is in a direct code path of a call to governor->governor, the
cpufreq_driver_sem lock is still held in the cpufreq core, and there's
no need to lock it again (in fact, this would cause a deadlock). So
use cpufreq_driver_target only in these cases. In all other cases (for
example, when there's a "daemonized" function that wakes up every
second), use cpufreq_driver_target_l to lock the cpufreq_driver_sem
before the command is passed to the cpufreq processor driver.
CPU frequency and voltage scaling code in the Linux(TM) kernel
L i n u x C P U F r e q
Dominik Brodowski <linux@brodo.de>
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.
Documents in this directory:
----------------------------
core.txt - General description of the CPUFreq core and
of CPUFreq notifiers
cpu-drivers.txt - How to implement a new cpufreq processor driver
governors.txt - What are cpufreq governors and how to
implement them?
index.txt - File index, Mailing list and Links (this document)
user-guide.txt - User Guide to CPUFreq
Mailing List
------------
There is a CPU frequency changing CVS commit and general list where
you can report bugs, problems or submit patches. To post a message,
send an email to cpufreq@www.linux.org.uk, to subscribe go to
http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
mailing list are available to subscribers at
http://www.linux.org.uk/mailman/private/cpufreq/.
Links
-----
the FTP archives:
* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
how to access the CVS repository:
* http://cvs.arm.linux.org.uk/
the CPUFreq Mailing list:
* http://www.linux.org.uk/mailman/listinfo/cpufreq
Clock and voltage scaling for the SA-1100:
* http://www.lart.tudelft.nl/projects/scaling
CPU frequency and voltage scaling code in the Linux(TM) kernel
L i n u x C P U F r e q
U S E R G U I D E
Dominik Brodowski <linux@brodo.de>
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.
Contents:
---------
1. Supported Architectures and Processors
1.1 ARM
1.2 x86
1.3 sparc64
2. "Policy" / "Governor"?
2.1 Policy
2.2 Governor
3. How to change the CPU cpufreq policy and/or speed
3.1 Preferred interface: sysfs
3.2 Deprecated interfaces
1. Supported Architectures and Processors
=========================================
1.1 ARM
-------
The following ARM processors are supported by cpufreq:
ARM Integrator
ARM-SA1100
ARM-SA1110
1.2 x86
-------
The following processors for the x86 architecture are supported by cpufreq:
AMD Elan - SC400, SC410
AMD mobile K6-2+
AMD mobile K6-3+
Cyrix Media GXm
Intel mobile PIII [*] and Intel mobile PIII-M on certain chipsets
Intel Pentium 4, Intel Xeon
National Semiconductors Geode GX
Transmeta Crusoe
varios processors on some ACPI 2.0-compatible systems [**]
[*] only certain Intel mobile PIII processors are supported. If you
know that you own a speedstep-capable processor, pass the option
"speedstep_coppermine=1" to the module speedstep.o
[**] Only if "ACPI Processor Performance States" are available
to the ACPI<->BIOS interface.
1.3 sparc64
-----------
The following processors for the sparc64 architecture are supported by
cpufreq:
UltraSPARC-III
2. "Policy" / "Governor" ?
==========================
Some CPU frequency scaling-capable processor switch between varios
frequencies and operating voltages "on the fly" without any kernel or
user involvement. This guarantuees very fast switching to a frequency
which is high enough to serve the user's needs, but low enough to save
power.
2.1 Policy
----------
On these systems, all you can do is select the lower and upper
frequency limit as well as whether you want more aggressive
power-saving or more instantly avaialble processing power.
2.2 Governor
------------
On all other cpufreq implementations, these boundaries still need to
be set. Then, a "governor" must be selected. Such a "governor" decides
what speed the processor shall run within the boundaries. One such
"governor" is the "userspace" governor. This one allows the user - or
a yet-to-implement userspace program - to decide what specific speed
the processor shall run at.
3. How to change the CPU cpufreq policy and/or speed
====================================================
3.1 Preferred Interface: sysfs
------------------------------
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).
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)
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
available in this kernel. You can see the
currently activated governor in
scaling_governor, and by "echoing" the name of another
governor you can change it. Please note
that some governors won't load - they only
work on some specific architectures or
processors.
scaling_min_freq and
scaling_max_freq show the current "policy limits" (in
kHz). By echoing new values into these
files, you can change these limits.
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
scaling_setspeed. By "echoing" a new frequency into this
you can change the speed of the CPU,
but only within the limits of
scaling_min_freq and scaling_max_freq.
3.2 Deprecated Interfaces
-------------------------
Depending on your kernel configuration, you might find the following
cpufreq-related files:
/proc/cpufreq
/proc/sys/cpu/*/speed
/proc/sys/cpu/*/speed-min
/proc/sys/cpu/*/speed-max
These are files for deprecated interfaces to cpufreq, which offer far
less functionality. Because of this, these interfaces aren't described
here.
This diff is collapsed.
......@@ -159,7 +159,7 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
AWK = awk
GENKSYMS = /sbin/genksyms
GENKSYMS = scripts/genksyms/genksyms
DEPMOD = /sbin/depmod
KALLSYMS = scripts/kallsyms
PERL = perl
......@@ -190,6 +190,7 @@ export MODVERDIR := .tmp_versions
# The temporary file to save gcc -MD generated dependencies must not
# contain a comma
comma := ,
depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
noconfig_targets := xconfig menuconfig config oldconfig randconfig \
......@@ -319,36 +320,31 @@ define cmd_vmlinux__
endef
# set -e makes the rule exit immediately on error
# Final awk script makes sure per-cpu vars are in per-cpu section, as
# old gcc (eg egcs 2.92.11) ignores section attribute if uninitialized.
define rule_vmlinux__
set -e
$(if $(filter .tmp_kallsyms%,$^),,
echo ' Generating build number'
. $(src)/scripts/mkversion > .tmp_version
mv -f .tmp_version .version
$(Q)$(MAKE) $(build)=init
set -e; \
$(if $(filter .tmp_kallsyms%,$^),, \
echo ' GEN .version'; \
. $(srctree)/scripts/mkversion > .tmp_version; \
mv -f .tmp_version .version; \
$(MAKE) $(build)=init; \
)
$(call cmd,vmlinux__)
$(call cmd,vmlinux__); \
echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
endef
define rule_vmlinux_no_percpu
$(rule_vmlinux__)
$(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
endef
ifdef CONFIG_SMP
# Final awk script makes sure per-cpu vars are in per-cpu section, as
# old gcc (eg egcs 2.92.11) ignores section attribute if uninitialized.
check_per_cpu = $(AWK) -f $(srctree)/scripts/per-cpu-check.awk < System.map
endif
define rule_vmlinux
$(rule_vmlinux_no_percpu)
$(AWK) -f $(srctree)/scripts/per-cpu-check.awk < System.map
endef
else
define rule_vmlinux
$(rule_vmlinux_no_percpu)
$(rule_vmlinux__)
$(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
$(check_per_cpu)
endef
endif
LDFLAGS_vmlinux += -T arch/$(ARCH)/vmlinux.lds.s
......@@ -377,7 +373,7 @@ cmd_kallsyms = $(NM) -n $< | scripts/kallsyms > $@
$(call cmd,kallsyms)
.tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE
$(call if_changed_rule,vmlinux__)
+$(call if_changed_rule,vmlinux__)
.tmp_vmlinux2: $(vmlinux-objs) .tmp_kallsyms1.o arch/$(ARCH)/vmlinux.lds.s FORCE
$(call if_changed_rule,vmlinux__)
......@@ -464,7 +460,7 @@ include/config/MARKER: scripts/split-include include/linux/autoconf.h
# if .config is newer than include/linux/autoconf.h, someone tinkered
# with it and forgot to run make oldconfig
include/linux/autoconf.h: .config
include/linux/autoconf.h: .config scripts
$(Q)$(MAKE) $(build)=scripts/kconfig scripts/kconfig/conf
./scripts/kconfig/conf -s arch/$(ARCH)/Kconfig
......@@ -505,8 +501,11 @@ all: modules
# Build modules
include/linux/compile.h: FORCE
$(Q)$(MAKE) $(build)=init include/linux/compile.h
.PHONY: modules
modules: $(SUBDIRS) $(if $(CONFIG_MODVERSIONS),vmlinux)
modules: $(SUBDIRS) $(if $(KBUILD_BUILTIN),vmlinux) include/linux/compile.h
@echo ' Building modules, stage 2.';
$(Q)$(MAKE) -rR -f scripts/Makefile.modpost
......@@ -571,6 +570,7 @@ define generate-asm-offsets.h
echo "#endif" )
endef
else # ifdef include_config
ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
......@@ -741,10 +741,10 @@ tags: FORCE
# If you do a make spec before packing the tarball you can rpm -ta it
spec:
. scripts/mkspec >kernel.spec
. $(srctree)/scripts/mkspec >kernel.spec
# Build a tar ball, generate an rpm from it and pack the result
# There arw two bits of magic here
# There are two bits of magic here
# 1) The use of /. to avoid tar packing just the symlink
# 2) Removing the .dep files as they have source paths in them that
# will become invalid
......@@ -815,11 +815,6 @@ checkconfig:
-name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkconfig.pl
checkhelp:
find * $(RCS_FIND_IGNORE) \
-name [cC]onfig.in -print | sort \
| xargs $(PERL) -w scripts/checkhelp.pl
checkincludes:
find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \
......
......@@ -18,20 +18,6 @@ config CPU_FREQ
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_24_API
bool "/proc/sys/cpu/ interface (2.4. / OLD)"
depends on CPU_FREQ
help
This enables the /proc/sys/cpu/ sysctl interface for controlling
CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5
uses a sysfs interface instead. Please note that some drivers do
not work well with the 2.4. /proc/sys/cpu sysctl interface,
so if in doubt, say N here.
For details, take a look at linux/Documentation/cpufreq.
If in doubt, say N.
config CPU_FREQ_TABLE
tristate "CPU frequency table helpers"
depends on CPU_FREQ
......@@ -56,6 +42,16 @@ config X86_ACPI_CPUFREQ
If in doubt, say N.
config X86_ACPI_CPUFREQ_PROC_INTF
bool "/proc/acpi/processor/../performance interface (deprecated)"
depends on X86_ACPI_CPUFREQ && PROC_FS
help
This enables the deprecated /proc/acpi/processor/../performance
interface. While it is helpful for debugging, the generic,
cross-architecture cpufreq interfaces should be used.
If in doubt, say N.
config ELAN_CPUFREQ
tristate "AMD Elan"
depends on CPU_FREQ_TABLE && MELAN
......@@ -139,7 +135,7 @@ config X86_LONGRUN
config X86_LONGHAUL
tristate "VIA Cyrix III Longhaul"
depends on CPU_FREQ
depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for VIA Samuel/CyrixIII,
VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
......
This diff is collapsed.
......@@ -31,15 +31,9 @@
#define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */
#define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */
static struct cpufreq_driver *elanfreq_driver;
/* Module parameter */
static int max_freq;
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
struct s_elan_multiplier {
int clock; /* frequency in kHz */
int val40h; /* PMU Force Mode register */
......@@ -127,11 +121,6 @@ static void elanfreq_set_cpu_state (unsigned int state) {
struct cpufreq_freqs freqs;
if (!elanfreq_driver) {
printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n");
return;
}
freqs.old = elanfreq_get_cpu_frequency();
freqs.new = elan_multiplier[state].clock;
freqs.cpu = 0; /* elanfreq.c is UP only driver */
......@@ -187,11 +176,13 @@ static int elanfreq_verify (struct cpufreq_policy *policy)
return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]);
}
static int elanfreq_setpolicy (struct cpufreq_policy *policy)
static int elanfreq_target (struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate = 0;
if (cpufreq_frequency_table_setpolicy(policy, &elanfreq_table[0], &newstate))
if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate))
return -EINVAL;
elanfreq_set_cpu_state(newstate);
......@@ -204,6 +195,35 @@ static int elanfreq_setpolicy (struct cpufreq_policy *policy)
* Module init and exit code
*/
static int elanfreq_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *c = cpu_data;
unsigned int i;
/* capability check */
if ((c->x86_vendor != X86_VENDOR_AMD) ||
(c->x86 != 4) || (c->x86_model!=10))
return -ENODEV;
/* max freq */
if (!max_freq)
max_freq = elanfreq_get_cpu_frequency();
/* table init */
for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
if (elanfreq_table[i].frequency > max_freq)
elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
}
/* cpuinfo and default policy values */
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = elanfreq_get_cpu_frequency();
return cpufreq_frequency_table_cpuinfo(policy, &elanfreq_table[0]);;
}
#ifndef MODULE
/**
* elanfreq_setup - elanfreq command line parameter parsing
......@@ -224,11 +244,18 @@ static int __init elanfreq_setup(char *str)
__setup("elanfreq=", elanfreq_setup);
#endif
static struct cpufreq_driver elanfreq_driver = {
.verify = elanfreq_verify,
.target = elanfreq_target,
.init = elanfreq_cpu_init,
.name = "elanfreq",
};
static int __init elanfreq_init(void)
{
struct cpuinfo_x86 *c = cpu_data;
struct cpufreq_driver *driver;
int ret, i;
/* Test if we have the right hardware */
if ((c->x86_vendor != X86_VENDOR_AMD) ||
......@@ -238,63 +265,22 @@ static int __init elanfreq_init(void)
return -ENODEV;
}
driver = kmalloc(sizeof(struct cpufreq_driver) +
NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
if (!driver)
return -ENOMEM;
memset(driver, 0, sizeof(struct cpufreq_driver) +
NR_CPUS * sizeof(struct cpufreq_policy));
driver->policy = (struct cpufreq_policy *) (driver + 1);
if (!max_freq)
max_freq = elanfreq_get_cpu_frequency();
/* table init */
for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
if (elanfreq_table[i].frequency > max_freq)
elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
}
#ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency();
#endif
driver->verify = &elanfreq_verify;
driver->setpolicy = &elanfreq_setpolicy;
strncpy(driver->name, "elanfreq", CPUFREQ_NAME_LEN);
driver->policy[0].cpu = 0;
ret = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &elanfreq_table[0]);
if (ret) {
kfree(driver);
return ret;
}
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
elanfreq_driver = driver;
ret = cpufreq_register(driver);
if (ret) {
elanfreq_driver = NULL;
kfree(driver);
}
return ret;
return cpufreq_register_driver(&elanfreq_driver);
}
static void __exit elanfreq_exit(void)
{
if (elanfreq_driver) {
cpufreq_unregister();
kfree(elanfreq_driver);
}
cpufreq_unregister_driver(&elanfreq_driver);
}
module_init(elanfreq_init);
module_exit(elanfreq_exit);
MODULE_PARM (max_freq, "i");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
module_init(elanfreq_init);
module_exit(elanfreq_exit);
......@@ -116,7 +116,6 @@ struct gxfreq_params {
struct pci_dev *cs55x0;
};
static struct cpufreq_driver *gx_driver;
static struct gxfreq_params *gx_params;
static int stock_freq;
......@@ -345,7 +344,7 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy)
unsigned int tmp_freq = 0;
u8 tmp1, tmp2;
if (!gx_driver || !stock_freq || !policy)
if (!stock_freq || !policy)
return -EINVAL;
policy->cpu = 0;
......@@ -375,33 +374,71 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy)
}
/*
* cpufreq_gx_setpolicy:
* cpufreq_gx_target:
*
*/
static int cpufreq_gx_setpolicy(struct cpufreq_policy *policy)
static int cpufreq_gx_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
u8 tmp1, tmp2;
unsigned int tmp_freq;
if (!gx_driver || !stock_freq || !policy)
if (!stock_freq || !policy)
return -EINVAL;
policy->cpu = 0;
if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
/* here we need to make sure that we don't set the
* frequency below policy->min (see comment in
* cpufreq_gx_verify() - guarantee of processing
* capacity.
*/
u8 tmp1, tmp2;
unsigned int tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2);
tmp_freq = gx_validate_speed(target_freq, &tmp1, &tmp2);
while (tmp_freq < policy->min) {
tmp_freq += stock_freq / max_duration;
tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
}
while (tmp_freq > policy->max) {
tmp_freq -= stock_freq / max_duration;
tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
}
gx_set_cpuspeed(tmp_freq);
return 0;
}
static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
{
int maxfreq, curfreq;
if (!policy || policy->cpu != 0)
return -ENODEV;
/* determine maximum frequency */
if (pci_busclk) {
maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
} else if (cpu_khz) {
maxfreq = cpu_khz;
} else {
gx_set_cpuspeed(policy->max);
maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
}
stock_freq = maxfreq;
curfreq = gx_get_cpuspeed();
dprintk("cpu max frequency is %d.\n", maxfreq);
dprintk("cpu current frequency is %dkHz.\n",curfreq);
/* setup basic struct for cpufreq API */
policy->cpu = 0;
if (max_duration < POLICY_MIN_DIV)
policy->min = maxfreq / max_duration;
else
policy->min = maxfreq / POLICY_MIN_DIV;
policy->max = maxfreq;
policy->cur = curfreq;
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.min_freq = maxfreq / max_duration;
policy->cpuinfo.max_freq = maxfreq;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
return 0;
}
......@@ -409,11 +446,16 @@ static int cpufreq_gx_setpolicy(struct cpufreq_policy *policy)
* cpufreq_gx_init:
* MediaGX/Geode GX initilize cpufreq driver
*/
static struct cpufreq_driver gx_suspmod_driver = {
.verify = cpufreq_gx_verify,
.target = cpufreq_gx_target,
.init = cpufreq_gx_cpu_init,
.name = "gx-suspmod",
};
static int __init cpufreq_gx_init(void)
{
int maxfreq,ret,curfreq;
struct cpufreq_driver *driver;
int ret;
struct gxfreq_params *params;
struct pci_dev *gx_pci;
u32 class_rev;
......@@ -428,21 +470,13 @@ static int __init cpufreq_gx_init(void)
dprintk("geode suspend modulation available.\n");
driver = kmalloc(sizeof(struct cpufreq_driver) + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
if (driver == NULL)
return -ENOMEM;
memset(driver, 0, sizeof(struct cpufreq_driver) +
NR_CPUS * sizeof(struct cpufreq_policy));
params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
if (params == NULL) {
kfree(driver);
if (params == NULL)
return -ENOMEM;
}
memset(params, 0, sizeof(struct gxfreq_params));
driver->policy = (struct cpufreq_policy *)(driver + 1);
params->cs55x0 = gx_pci;
gx_params = params;
/* keep cs55x0 configurations */
pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg));
......@@ -453,45 +487,7 @@ static int __init cpufreq_gx_init(void)
pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev);
params->pci_rev = class_rev && 0xff;
gx_params = params;
/* determine maximum frequency */
if (pci_busclk) {
maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
} else if (cpu_khz) {
maxfreq = cpu_khz;
} else {
maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
}
stock_freq = maxfreq;
curfreq = gx_get_cpuspeed();
dprintk("cpu max frequency is %d.\n", maxfreq);
dprintk("cpu current frequency is %dkHz.\n",curfreq);
/* setup basic struct for cpufreq API */
#ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_cur_freq[0] = curfreq;
#endif
driver->policy[0].cpu = 0;
if (max_duration < POLICY_MIN_DIV)
driver->policy[0].min = maxfreq / max_duration;
else
driver->policy[0].min = maxfreq / POLICY_MIN_DIV;
driver->policy[0].max = maxfreq;
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].cpuinfo.min_freq = maxfreq / max_duration;
driver->policy[0].cpuinfo.max_freq = maxfreq;
driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
driver->verify = &cpufreq_gx_verify;
driver->setpolicy = &cpufreq_gx_setpolicy;
strncpy(driver->name, "gx-suspmod", CPUFREQ_NAME_LEN);
gx_driver = driver;
if ((ret = cpufreq_register(driver))) {
kfree(driver);
if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) {
kfree(params);
return ret; /* register error! */
}
......@@ -501,13 +497,8 @@ static int __init cpufreq_gx_init(void)
static void __exit cpufreq_gx_exit(void)
{
if (gx_driver) {
/* disable throttling */
gx_set_cpuspeed(stock_freq);
cpufreq_unregister();
kfree(gx_driver);
cpufreq_unregister_driver(&gx_suspmod_driver);
kfree(gx_params);
}
}
MODULE_AUTHOR ("Hiroshi Miura <miura@da-cha.org>");
......
This diff is collapsed.
/*
* $Id: longrun.c,v 1.22 2003/02/10 17:31:50 db Exp $
* $Id: longrun.c,v 1.25 2003/02/28 16:03:50 db Exp $
*
* (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
*
......@@ -244,10 +244,6 @@ static int longrun_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
longrun_get_policy(policy);
#ifdef CONFIG_CPU_FREQ_24_API
longrun_driver.cpu_cur_freq[policy->cpu] = longrun_low_freq; /* dummy value */
#endif
return 0;
}
......
......@@ -49,8 +49,6 @@ enum {
static int has_N44_O17_errata[NR_CPUS];
static int stock_freq;
static struct cpufreq_driver p4clockmod_driver;
static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
{
......@@ -220,9 +218,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
/* cpuinfo and default policy values */
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = 1000;
#ifdef CONFIG_CPU_FREQ_24_API
p4clockmod_driver.cpu_cur_freq[policy->cpu] = stock_freq;
#endif
policy->cur = stock_freq;
return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
}
......
/*
* $Id: powernow-k6.c,v 1.36 2002/10/31 21:17:40 db Exp $
* $Id: powernow-k6.c,v 1.48 2003/02/22 10:23:46 db Exp $
* This file was part of Powertweak Linux (http://powertweak.sf.net)
* and is shared with the Linux Kernel module.
*
* (C) 2000-2002 Dave Jones, Arjan van de Ven, Janne Pnkl, Dominik Brodowski.
* (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pnkl, Dominik Brodowski.
*
* Licensed under the terms of the GNU GPL License version 2.
*
......@@ -25,7 +25,6 @@
#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long
as it is unused */
static struct cpufreq_driver *powernow_driver;
static unsigned int busfreq; /* FSB, in 10 kHz */
static unsigned int max_multiplier;
......@@ -77,8 +76,8 @@ static void powernow_k6_set_state (unsigned int best_i)
unsigned long msrval;
struct cpufreq_freqs freqs;
if (!powernow_driver) {
printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n");
if (clock_ratio[best_i].index > max_multiplier) {
printk(KERN_ERR "cpufreq: invalid target frequency\n");
return;
}
......@@ -126,11 +125,13 @@ static int powernow_k6_verify(struct cpufreq_policy *policy)
*
* sets a new CPUFreq policy
*/
static int powernow_k6_setpolicy (struct cpufreq_policy *policy)
static int powernow_k6_target (struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate = 0;
if (cpufreq_frequency_table_setpolicy(policy, &clock_ratio[0], &newstate))
if (cpufreq_frequency_table_target(policy, &clock_ratio[0], target_freq, relation, &newstate))
return -EINVAL;
powernow_k6_set_state(newstate);
......@@ -139,43 +140,22 @@ static int powernow_k6_setpolicy (struct cpufreq_policy *policy)
}
/**
* powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
*
* Initializes the K6 PowerNow! support. Returns -ENODEV on unsupported
* devices, -EINVAL or -ENOMEM on problems during initiatization, and zero
* on success.
*/
static int __init powernow_k6_init(void)
static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *c = cpu_data;
struct cpufreq_driver *driver;
unsigned int result;
unsigned int i;
/* capability check */
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
((c->x86_model != 12) && (c->x86_model != 13)))
return -ENODEV;
if (policy->cpu != 0)
return -ENODEV;
/* get frequencies */
max_multiplier = powernow_k6_get_cpu_multiplier();
busfreq = cpu_khz / max_multiplier;
if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
printk("cpufreq: PowerNow IOPORT region already used.\n");
return -EIO;
}
/* initialization of main "cpufreq" code*/
driver = kmalloc(sizeof(struct cpufreq_driver) +
NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
if (!driver) {
release_region (POWERNOW_IOPORT, 16);
return -ENOMEM;
}
memset(driver, 0, sizeof(struct cpufreq_driver) +
NR_CPUS * sizeof(struct cpufreq_policy));
driver->policy = (struct cpufreq_policy *) (driver + 1);
/* table init */
for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
if (clock_ratio[i].index > max_multiplier)
......@@ -184,33 +164,61 @@ static int __init powernow_k6_init(void)
clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
}
driver->verify = &powernow_k6_verify;
driver->setpolicy = &powernow_k6_setpolicy;
strncpy(driver->name, "powernow-k6", CPUFREQ_NAME_LEN);
/* cpuinfo and default policy values */
driver->policy[0].cpu = 0;
driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
#ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_cur_freq[0] = busfreq * max_multiplier;
#endif
result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &clock_ratio[0]);
if (result) {
kfree(driver);
return result;
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = busfreq * max_multiplier;
return cpufreq_frequency_table_cpuinfo(policy, &clock_ratio[0]);
}
static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
{
unsigned int i;
for (i=0; i<8; i++) {
if (i==max_multiplier)
powernow_k6_set_state(i);
}
return 0;
}
static struct cpufreq_driver powernow_k6_driver = {
.verify = powernow_k6_verify,
.target = powernow_k6_target,
.init = powernow_k6_cpu_init,
.exit = powernow_k6_cpu_exit,
.name = "powernow-k6",
};
powernow_driver = driver;
result = cpufreq_register(driver);
if (result) {
/**
* powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
*
* Initializes the K6 PowerNow! support. Returns -ENODEV on unsupported
* devices, -EINVAL or -ENOMEM on problems during initiatization, and zero
* on success.
*/
static int __init powernow_k6_init(void)
{
struct cpuinfo_x86 *c = cpu_data;
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
((c->x86_model != 12) && (c->x86_model != 13)))
return -ENODEV;
if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
printk("cpufreq: PowerNow IOPORT region already used.\n");
return -EIO;
}
if (cpufreq_register_driver(&powernow_k6_driver)) {
release_region (POWERNOW_IOPORT, 16);
powernow_driver = NULL;
kfree(driver);
return -EINVAL;
}
return result;
return 0;
}
......@@ -221,20 +229,14 @@ static int __init powernow_k6_init(void)
*/
static void __exit powernow_k6_exit(void)
{
unsigned int i;
if (powernow_driver) {
for (i=0;i<8;i++)
if (clock_ratio[i].index == max_multiplier)
powernow_k6_set_state(i);
cpufreq_unregister();
kfree(powernow_driver);
}
cpufreq_unregister_driver(&powernow_k6_driver);
release_region (POWERNOW_IOPORT, 16);
}
MODULE_AUTHOR ("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@suse.de>, Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
MODULE_LICENSE ("GPL");
module_init(powernow_k6_init);
module_exit(powernow_k6_exit);
/*
* $Id: powernow-k7.c,v 1.31 2003/02/12 21:16:35 davej Exp $
* $Id: powernow-k7.c,v 1.34 2003/02/22 10:23:46 db Exp $
*
* (C) 2003 Dave Jones <davej@suse.de>
*
......@@ -72,8 +72,6 @@ static int fid_codes[32] = {
150, 225, 160, 165, 170, 180, -1, -1,
};
static struct cpufreq_driver powernow_driver;
static struct cpufreq_frequency_table *powernow_table;
static unsigned int can_scale_bus;
......@@ -369,13 +367,18 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = latency;
#ifdef CONFIG_CPU_FREQ_24_API
powernow_driver.cpu_cur_freq[policy->cpu] = maximum_speed;
#endif
policy->cur = maximum_speed;
return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
}
static struct cpufreq_driver powernow_driver = {
.verify = powernow_verify,
.target = powernow_target,
.init = powernow_cpu_init,
.name = "powernow-k7",
};
static int __init powernow_init (void)
{
if (check_powernow()==0)
......@@ -391,14 +394,6 @@ static void __exit powernow_exit (void)
kfree(powernow_table);
}
static struct cpufreq_driver powernow_driver = {
.verify = powernow_verify,
.target = powernow_target,
.init = powernow_cpu_init,
.name = "powernow-k7",
};
MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
MODULE_LICENSE ("GPL");
......
/*
* $Id: speedstep.c,v 1.68 2003/01/20 17:31:47 db Exp $
* $Id: speedstep.c,v 1.70 2003/02/22 10:23:46 db Exp $
*
* (C) 2001 Dave Jones, Arjan van de ven.
* (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
......@@ -30,8 +30,6 @@
#include <asm/msr.h>
static struct cpufreq_driver speedstep_driver;
/* 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
......@@ -629,9 +627,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
policy->policy = (speed == speedstep_low_freq) ?
CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
#ifdef CONFIG_CPU_FREQ_24_API
speedstep_driver.cpu_cur_freq[policy->cpu] = speed;
#endif
policy->cur = speed;
return cpufreq_frequency_table_cpuinfo(policy, &speedstep_freqs[0]);
}
......@@ -686,7 +682,7 @@ static int __init speedstep_init(void)
return -ENODEV;
}
dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.68 $\n");
dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.70 $\n");
/* activate speedstep support */
if (speedstep_activate())
......
......@@ -9,3 +9,30 @@ config CPU_FREQ_PROC_INTF
For details, take a look at linux/Documentation/cpufreq.
If in doubt, say N.
config CPU_FREQ_GOV_USERSPACE
tristate "'userspace' governor for userspace frequency scaling"
depends on CPU_FREQ
help
Enable this cpufreq governor when you either want to set the
CPU frequency manually or when an userspace programm shall
be able to set the CPU dynamically, like on LART
( http://www.lart.tudelft.nl/ )
For details, take a look at linux/Documentation/cpufreq.
If in doubt, say Y.
config CPU_FREQ_24_API
bool "/proc/sys/cpu/ interface (2.4. / OLD)"
depends on CPU_FREQ && SYSCTL && CPU_FREQ_GOV_USERSPACE
help
This enables the /proc/sys/cpu/ sysctl interface for controlling
the CPUFreq,"userspace" governor. This is the same interface
as known from the.4.-kernel patches for CPUFreq, and offers
the same functionality as long as "userspace" is the
selected governor for the specified CPU.
For details, take a look at linux/Documentation/cpufreq.
If in doubt, say N.
#CPUfreq governors and cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
obj-$(CONFIG_CPU_FREQ_PROC_INTF) += proc_intf.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += userspace.o
This diff is collapsed.
......@@ -108,11 +108,18 @@
- New reset code uses "force reset" cmd on Rhine-II
- Various clean ups
LK1.1.17 (Roger Luethi)
- Fix race in via_rhine_start_tx()
- On errors, wait for Tx engine to turn off before scavenging
- Handle Tx descriptor write-back race on Rhine-II
- Force flushing for PCI posted writes
- More reset code changes
*/
#define DRV_NAME "via-rhine"
#define DRV_VERSION "1.1.16"
#define DRV_RELDATE "February-15-2003"
#define DRV_VERSION "1.1.17"
#define DRV_RELDATE "March-1-2003"
/* A few user-configurable values.
......@@ -562,7 +569,7 @@ static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
/* VT86C100A may need long delay after reset (dlink) */
/* Seen on Rhine-II as well (rl) */
while ((readw(ioaddr + ChipCmd) & CmdReset) && --boguscnt);
while ((readw(ioaddr + ChipCmd) & CmdReset) && --boguscnt)
udelay(5);
}
......
......@@ -62,6 +62,8 @@ struct cpufreq_policy {
unsigned int cpu; /* cpu nr or CPUFREQ_ALL_CPUS */
unsigned int min; /* in kHz */
unsigned int max; /* in kHz */
unsigned int cur; /* in kHz, only needed if cpufreq
* governors are used */
unsigned int policy; /* see above */
struct cpufreq_governor *governor; /* see below */
struct cpufreq_cpuinfo cpuinfo; /* see above */
......@@ -164,10 +166,6 @@ struct cpufreq_driver {
/* optional, for the moment */
int (*init) (struct cpufreq_policy *policy);
int (*exit) (struct cpufreq_policy *policy);
/* 2.4. compatible API */
#ifdef CONFIG_CPU_FREQ_24_API
unsigned int cpu_cur_freq[NR_CPUS];
#endif
};
int cpufreq_register_driver(struct cpufreq_driver *driver_data);
......@@ -208,14 +206,19 @@ int cpufreq_restore(void);
/* the proc_intf.c needs this */
int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
#ifdef CONFIG_CPU_FREQ_24_API
#if defined(CONFIG_CPU_FREQ_GOV_USERSPACE) || defined(CONFIG_CPU_FREQ_GOV_USERSPACE_MODULE)
/*********************************************************************
* CPUFREQ 2.4. INTERFACE *
* CPUFREQ USERSPACE GOVERNOR *
*********************************************************************/
extern struct cpufreq_governor cpufreq_gov_userspace;
int cpufreq_gov_userspace_init(void);
int cpufreq_setmax(unsigned int cpu);
int cpufreq_set(unsigned int kHz, unsigned int cpu);
unsigned int cpufreq_get(unsigned int cpu);
#ifdef CONFIG_CPU_FREQ_24_API
/* /proc/sys/cpu */
enum {
CPU_NR = 1, /* compatibilty reasons */
......@@ -260,45 +263,10 @@ enum {
CPU_NR_FREQ = 3,
};
#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
.ctl_name = CPU_NR_FREQ_MAX, \
.data = &cpu_max_freq[cpunr], \
.procname = "speed-max", \
.maxlen = sizeof(cpu_max_freq[cpunr]),\
.mode = 0444, \
.proc_handler = proc_dointvec, }
#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
.ctl_name = CPU_NR_FREQ_MIN, \
.data = &cpu_min_freq[cpunr], \
.procname = "speed-min", \
.maxlen = sizeof(cpu_min_freq[cpunr]),\
.mode = 0444, \
.proc_handler = proc_dointvec, }
#define CTL_CPU_VARS_SPEED(cpunr) { \
.ctl_name = CPU_NR_FREQ, \
.procname = "speed", \
.mode = 0644, \
.proc_handler = cpufreq_procctl, \
.strategy = cpufreq_sysctl, \
.extra1 = (void*) (cpunr), }
#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
CTL_CPU_VARS_SPEED_MAX(cpunr), \
CTL_CPU_VARS_SPEED_MIN(cpunr), \
CTL_CPU_VARS_SPEED(cpunr), \
{ .ctl_name = 0, }, }
/* the ctl_table entry for each CPU */
#define CPU_ENUM(s) { \
.ctl_name = (CPU_NR + s), \
.procname = #s, \
.mode = 0555, \
.child = ctl_cpu_vars_##s }
#endif /* CONFIG_CPU_FREQ_24_API */
#endif /* CONFIG_CPU_FREQ_GOV_USERSPACE */
/*********************************************************************
* FREQUENCY TABLE HELPERS *
......
......@@ -150,13 +150,7 @@ void *__symbol_get(const char *symbol);
void *__symbol_get_gpl(const char *symbol);
#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
#ifdef __GENKSYMS__
/* genksyms doesn't handle GPL-only symbols yet */
#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
#else
#ifndef __GENKSYMS__
#ifdef CONFIG_MODVERSIONS
/* Mark the CRC weak since genksyms apparently decides not to
* generate a checksums for some symbols */
......@@ -188,7 +182,7 @@ void *__symbol_get_gpl(const char *symbol);
#endif
/* We don't mangle the actual symbol anymore, so no need for
* special casing EXPORT_SYMBOL_NOVERS */
* special casing EXPORT_SYMBOL_NOVERS. FIXME: Deprecated */
#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
struct module_ref
......
......@@ -3,6 +3,9 @@
#
obj-y := main.o version.o do_mounts.o initramfs.o
obj-$(CONFIG_DEVFS_FS) += do_mounts_devfs.o
obj-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o
obj-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o
# files to be removed upon make clean
clean-files := ../include/linux/compile.h
......@@ -17,5 +20,5 @@ $(obj)/version.o: include/linux/compile.h
# actual file if its content has changed.
include/linux/compile.h: FORCE
@echo -n ' Generating $@'
@echo -n ' GEN $@'
@sh $(srctree)/scripts/mkcompile_h $@ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
This diff is collapsed.
#define __KERNEL_SYSCALLS__
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/init.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/blk.h>
#include <linux/root_dev.h>
asmlinkage long sys_unlink(const char *name);
asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
asmlinkage long sys_mkdir(const char *name, int mode);
asmlinkage long sys_rmdir(const char *name);
asmlinkage long sys_chdir(const char *name);
asmlinkage long sys_fchdir(int fd);
asmlinkage long sys_chroot(const char *name);
asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
unsigned long flags, void *data);
asmlinkage long sys_umount(char *name, int flags);
dev_t name_to_dev_t(char *name);
void change_floppy(char *fmt, ...);
void mount_block_root(char *name, int flags);
void mount_root(void);
extern int root_mountflags;
#ifdef CONFIG_DEVFS_FS
void mount_devfs(void);
void umount_devfs(char *path);
int create_dev(char *name, dev_t dev, char *devfs_name);
#else
static inline void mount_devfs(void) {}
static inline void umount_devfs(const char *path) {}
static inline int create_dev(char *name, dev_t dev, char *devfs_name)
{
sys_unlink(name);
return sys_mknod(name, S_IFBLK|0600, dev);
}
#endif
#ifdef CONFIG_BLK_DEV_RAM
int __init rd_load_disk(int n);
int __init rd_load_image(char *from);
#else
static inline int rd_load_disk(int n) { return 0; }
static inline int rd_load_image(char *from) { return 0; }
#endif
#ifdef CONFIG_BLK_DEV_INITRD
int __init initrd_load(void);
#else
static inline int initrd_load(void) { return 0; }
#endif
#ifdef CONFIG_BLK_DEV_MD
void md_run_setup(void);
#else
static inline void md_run_setup(void) {}
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -5,7 +5,7 @@
# fix-dep: Used to generate dependency information during build process
# split-include: Divide all config symbols up in a number of files in
# include/config/...
# docproc: Preprocess .tmpl file in order to generate .sgml documentation
# docproc: Preprocess .tmpl file in order to generate .sgml docs
# conmakehash: Create arrays for initializing the kernel console tables
host-progs := fixdep split-include conmakehash docproc kallsyms modpost \
......@@ -14,20 +14,20 @@ build-targets := $(host-progs) empty.o
modpost-objs := modpost.o file2alias.o
clean-files := elfconfig.h
subdir-$(CONFIG_MODVERSIONS) += genksyms
# Let clean descend into subdirs
subdir- := lxdialog kconfig
subdir- += lxdialog kconfig
# fixdep is needed to compile other host programs
$(addprefix $(obj)/,$(filter-out fixdep,$(build-targets))): $(obj)/fixdep
$(addprefix $(obj)/,$(filter-out fixdep,$(build-targets)) $(subdir-y)): $(obj)/fixdep
# dependencies on generated files need to be listed explicitly
$(obj)/modpost.o $(obj)/file2alias.o: $(obj)/elfconfig.h
quiet_cmd_elfconfig = MKELF $@
cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@
cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
$(call if_changed,elfconfig)
......
......@@ -90,8 +90,7 @@ define rule_vcc_o_c
mv $(@D)/.tmp_$(@F) $@; \
else \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \
| $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) \
| sed -n 's/\#define __ver_\([^ ]*\)[ ]*\([^ ]*\)/__crc_\1 = 0x\2 ;/gp' \
| $(GENKSYMS) \
> $(@D)/.tmp_$(@F:.o=.ver); \
\
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
......
......@@ -35,7 +35,7 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
# ==========================================================================
__clean-files := $(wildcard $(EXTRA_TARGETS) $(host-progs) $(clean-files))
__clean-files := $(wildcard $(EXTRA_TARGETS) $(host-progs) $(clean-files) $(targets))
quiet_cmd_clean = CLEAN $(obj)
cmd_clean = rm -f $(__clean-files); $(clean-rule)
......
host-progs := genksyms
build-targets := $(host-progs)
genksyms-objs := genksyms.o parse.o lex.o
HOSTCFLAGS_parse.o := -Wno-uninitialized
# dependencies on generated files need to be listed explicitly
$(obj)/lex.o: $(obj)/parse.h $(obj)/keywords.c
ifdef GENERATE_PARSER
# gperf
quiet_cmd_keywords.c = GPERF $@
cmd_keywords.c = gperf -L ANSI-C -a -C -E -g -H is_reserved_hash \
-k 1,3,$$ -N is_reserved_word -p -t $< > $@
$(obj)/keywords.c: $(obj)/keywords.gperf FORCE
$(call if_changed,keywords.c)
# flex
quiet_cmd_lex.c = FLEX $@
cmd_lex.c = flex -o$@ -d $(filter-out FORCE,$^)
$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h FORCE
$(call if_changed,lex.c)
# bison
quiet_cmd_parse.c = BISON $@
cmd_parse.c = bison -o$@ -dtv $(filter-out FORCE,$^)
$(obj)/parse.c: $(obj)/parse.y FORCE
$(call if_changed,parse.c)
$(obj)/parse.h: $(obj)/parse.c ;
clean-files += parse.output
endif
targets += $(obj)/keywords.c $(obj)/lex.c $(obj)/parse.c $(obj)/parse.h
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3059,7 +3059,7 @@ static void ali_ac97_set(struct trident_card *card, int secondary, u8 reg, u16 v
ncount = 10;
while(1) {
wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
if(!wcontrol & 0x8000)
if(!(wcontrol & 0x8000))
break;
if(ncount <= 0)
break;
......
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