1 |
3 |
xianfeng |
CPU frequency and voltage scaling code in the Linux(TM) kernel
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
L i n u x C P U F r e q
|
5 |
|
|
|
6 |
|
|
C P U F r e q C o r e
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
Dominik Brodowski
|
10 |
|
|
David Kimdon
|
11 |
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
Clock scaling allows you to change the clock speed of the CPUs on the
|
15 |
|
|
fly. This is a nice method to save battery power, because the lower
|
16 |
|
|
the clock speed, the less power the CPU consumes.
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
Contents:
|
20 |
|
|
---------
|
21 |
|
|
1. CPUFreq core and interfaces
|
22 |
|
|
2. CPUFreq notifiers
|
23 |
|
|
|
24 |
|
|
1. General Information
|
25 |
|
|
=======================
|
26 |
|
|
|
27 |
|
|
The CPUFreq core code is located in drivers/cpufreq/cpufreq.c. This
|
28 |
|
|
cpufreq code offers a standardized interface for the CPUFreq
|
29 |
|
|
architecture drivers (those pieces of code that do actual
|
30 |
|
|
frequency transitions), as well as to "notifiers". These are device
|
31 |
|
|
drivers or other part of the kernel that need to be informed of
|
32 |
|
|
policy changes (ex. thermal modules like ACPI) or of all
|
33 |
|
|
frequency changes (ex. timing code) or even need to force certain
|
34 |
|
|
speed limits (like LCD drivers on ARM architecture). Additionally, the
|
35 |
|
|
kernel "constant" loops_per_jiffy is updated on frequency changes
|
36 |
|
|
here.
|
37 |
|
|
|
38 |
|
|
Reference counting is done by cpufreq_get_cpu and cpufreq_put_cpu,
|
39 |
|
|
which make sure that the cpufreq processor driver is correctly
|
40 |
|
|
registered with the core, and will not be unloaded until
|
41 |
|
|
cpufreq_put_cpu is called.
|
42 |
|
|
|
43 |
|
|
2. CPUFreq notifiers
|
44 |
|
|
====================
|
45 |
|
|
|
46 |
|
|
CPUFreq notifiers conform to the standard kernel notifier interface.
|
47 |
|
|
See linux/include/linux/notifier.h for details on notifiers.
|
48 |
|
|
|
49 |
|
|
There are two different CPUFreq notifiers - policy notifiers and
|
50 |
|
|
transition notifiers.
|
51 |
|
|
|
52 |
|
|
|
53 |
|
|
2.1 CPUFreq policy notifiers
|
54 |
|
|
----------------------------
|
55 |
|
|
|
56 |
|
|
These are notified when a new policy is intended to be set. Each
|
57 |
|
|
CPUFreq policy notifier is called three times for a policy transition:
|
58 |
|
|
|
59 |
|
|
1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
|
60 |
|
|
they see a need for this - may it be thermal considerations or
|
61 |
|
|
hardware limitations.
|
62 |
|
|
|
63 |
|
|
2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
|
64 |
|
|
hardware failure.
|
65 |
|
|
|
66 |
|
|
3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
|
67 |
|
|
- if two hardware drivers failed to agree on a new policy before this
|
68 |
|
|
stage, the incompatible hardware shall be shut down, and the user
|
69 |
|
|
informed of this.
|
70 |
|
|
|
71 |
|
|
The phase is specified in the second argument to the notifier.
|
72 |
|
|
|
73 |
|
|
The third argument, a void *pointer, points to a struct cpufreq_policy
|
74 |
|
|
consisting of five values: cpu, min, max, policy and max_cpu_freq. min
|
75 |
|
|
and max are the lower and upper frequencies (in kHz) of the new
|
76 |
|
|
policy, policy the new policy, cpu the number of the affected CPU; and
|
77 |
|
|
max_cpu_freq the maximum supported CPU frequency. This value is given
|
78 |
|
|
for informational purposes only.
|
79 |
|
|
|
80 |
|
|
|
81 |
|
|
2.2 CPUFreq transition notifiers
|
82 |
|
|
--------------------------------
|
83 |
|
|
|
84 |
|
|
These are notified twice when the CPUfreq driver switches the CPU core
|
85 |
|
|
frequency and this change has any external implications.
|
86 |
|
|
|
87 |
|
|
The second argument specifies the phase - CPUFREQ_PRECHANGE or
|
88 |
|
|
CPUFREQ_POSTCHANGE.
|
89 |
|
|
|
90 |
|
|
The third argument is a struct cpufreq_freqs with the following
|
91 |
|
|
values:
|
92 |
|
|
cpu - number of the affected CPU
|
93 |
|
|
old - old frequency
|
94 |
|
|
new - new frequency
|
95 |
|
|
|
96 |
|
|
If the cpufreq core detects the frequency has changed while the system
|
97 |
|
|
was suspended, these notifiers are called with CPUFREQ_RESUMECHANGE as
|
98 |
|
|
second argument.
|