Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
e79b352d
Commit
e79b352d
authored
May 18, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
10cba765
6deb6e5b
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
834 additions
and
265 deletions
+834
-265
Documentation/cpu-freq/core.txt
Documentation/cpu-freq/core.txt
+4
-0
arch/arm/mach-integrator/cpu.c
arch/arm/mach-integrator/cpu.c
+14
-6
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mach-sa1100/cpu-sa1100.c
+5
-3
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-sa1100/cpu-sa1110.c
+5
-4
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/generic.c
+4
-2
arch/arm/mach-sa1100/generic.h
arch/arm/mach-sa1100/generic.h
+1
-1
arch/i386/kernel/cpu/cpufreq/Makefile
arch/i386/kernel/cpu/cpufreq/Makefile
+2
-2
arch/i386/kernel/cpu/cpufreq/elanfreq.c
arch/i386/kernel/cpu/cpufreq/elanfreq.c
+5
-4
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
+5
-4
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
+80
-7
arch/i386/kernel/cpu/cpufreq/longhaul.h
arch/i386/kernel/cpu/cpufreq/longhaul.h
+154
-13
arch/i386/kernel/cpu/cpufreq/longrun.c
arch/i386/kernel/cpu/cpufreq/longrun.c
+32
-9
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+97
-54
arch/i386/kernel/cpu/cpufreq/powernow-k6.c
arch/i386/kernel/cpu/cpufreq/powernow-k6.c
+6
-0
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+16
-1
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+48
-16
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+10
-8
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+81
-43
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+6
-1
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+17
-3
arch/i386/kernel/timers/timer_tsc.c
arch/i386/kernel/timers/timer_tsc.c
+46
-12
arch/sparc64/kernel/time.c
arch/sparc64/kernel/time.c
+2
-1
arch/x86_64/kernel/time.c
arch/x86_64/kernel/time.c
+2
-1
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+162
-25
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/cpufreq_userspace.c
+3
-39
drivers/serial/sh-sci.c
drivers/serial/sh-sci.c
+2
-1
include/linux/cpufreq.h
include/linux/cpufreq.h
+25
-5
No files found.
Documentation/cpu-freq/core.txt
View file @
e79b352d
...
...
@@ -92,3 +92,7 @@ values:
cpu - number of the affected CPU
old - old frequency
new - new frequency
If the cpufreq core detects the frequency has changed while the system
was suspended, these notifiers are called with CPUFREQ_RESUMECHANGE as
second argument.
arch/arm/mach-integrator/cpu.c
View file @
e79b352d
...
...
@@ -152,10 +152,10 @@ static int integrator_set_target(struct cpufreq_policy *policy,
return
0
;
}
static
int
integrator_cpufreq_init
(
struct
cpufreq_policy
*
policy
)
static
unsigned
int
integrator_get
(
unsigned
int
cpu
)
{
unsigned
long
cpus_allowed
;
unsigned
int
c
pu
=
policy
->
cpu
;
unsigned
int
c
urrent_freq
;
u_int
cm_osc
;
struct
icst525_vco
vco
;
...
...
@@ -175,15 +175,22 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
vco
.
v
=
cm_osc
&
255
;
vco
.
r
=
22
;
current_freq
=
icst525_khz
(
&
cclk_params
,
vco
);
/* current freq */
set_cpus_allowed
(
current
,
cpus_allowed
);
return
current_freq
;
}
static
int
integrator_cpufreq_init
(
struct
cpufreq_policy
*
policy
)
{
/* set default policy and cpuinfo */
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
max_freq
=
160000
;
policy
->
cpuinfo
.
min_freq
=
12000
;
policy
->
cpuinfo
.
transition_latency
=
1000000
;
/* 1 ms, assumed */
policy
->
cur
=
policy
->
min
=
policy
->
max
=
icst525_khz
(
&
cclk_params
,
vco
);
/* current freq */
set_cpus_allowed
(
current
,
cpus_allowed
);
policy
->
cur
=
policy
->
min
=
policy
->
max
=
integrator_get
(
policy
->
cpu
);
return
0
;
}
...
...
@@ -191,6 +198,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
static
struct
cpufreq_driver
integrator_driver
=
{
.
verify
=
integrator_verify_policy
,
.
target
=
integrator_set_target
,
.
get
=
integrator_get
,
.
init
=
integrator_cpufreq_init
,
.
name
=
"integrator"
,
};
...
...
arch/arm/mach-sa1100/cpu-sa1100.c
View file @
e79b352d
...
...
@@ -180,7 +180,7 @@ static int sa1100_target(struct cpufreq_policy *policy,
unsigned
int
target_freq
,
unsigned
int
relation
)
{
unsigned
int
cur
=
sa11x0_getspeed
();
unsigned
int
cur
=
sa11x0_getspeed
(
0
);
unsigned
int
new_ppcr
;
struct
cpufreq_freqs
freqs
;
...
...
@@ -221,7 +221,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
{
if
(
policy
->
cpu
!=
0
)
return
-
EINVAL
;
policy
->
cur
=
policy
->
min
=
policy
->
max
=
sa11x0_getspeed
();
policy
->
cur
=
policy
->
min
=
policy
->
max
=
sa11x0_getspeed
(
0
);
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
min_freq
=
59000
;
policy
->
cpuinfo
.
max_freq
=
287000
;
...
...
@@ -230,15 +230,17 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
}
static
struct
cpufreq_driver
sa1100_driver
=
{
.
flags
=
(
CPUFREQ_PANIC_OUTOFSYNC
|
CPUFREQ_PANIC_RESUME_OUTOFSYNC
),
.
verify
=
sa11x0_verify_speed
,
.
target
=
sa1100_target
,
.
get
=
sa11x0_getspeed
,
.
init
=
sa1100_cpu_init
,
.
name
=
"sa1100"
,
};
static
int
__init
sa1100_dram_init
(
void
)
{
cpufreq_gov_userspace_init
();
if
((
processor_id
&
CPU_SA1100_MASK
)
==
CPU_SA1100_ID
)
return
cpufreq_register_driver
(
&
sa1100_driver
);
else
...
...
arch/arm/mach-sa1100/cpu-sa1110.c
View file @
e79b352d
...
...
@@ -238,7 +238,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
return
-
EINVAL
;
}
freqs
.
old
=
sa11x0_getspeed
();
freqs
.
old
=
sa11x0_getspeed
(
0
);
freqs
.
new
=
sa11x0_ppcr_to_freq
(
ppcr
);
freqs
.
cpu
=
0
;
...
...
@@ -320,7 +320,7 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
{
if
(
policy
->
cpu
!=
0
)
return
-
EINVAL
;
policy
->
cur
=
policy
->
min
=
policy
->
max
=
sa11x0_getspeed
();
policy
->
cur
=
policy
->
min
=
policy
->
max
=
sa11x0_getspeed
(
0
);
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
min_freq
=
59000
;
policy
->
cpuinfo
.
max_freq
=
287000
;
...
...
@@ -329,8 +329,11 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
}
static
struct
cpufreq_driver
sa1110_driver
=
{
.
flags
=
(
CPUFREQ_PANIC_OUTOFSYNC
|
CPUFREQ_PANIC_RESUME_OUTOFSYNC
),
.
verify
=
sa11x0_verify_speed
,
.
target
=
sa1110_target
,
.
get
=
sa11x0_getspeed
,
.
init
=
sa1110_cpu_init
,
.
name
=
"sa1110"
,
};
...
...
@@ -354,8 +357,6 @@ static int __init sa1110_clk_init(void)
sdram
->
tck
,
sdram
->
trcd
,
sdram
->
trp
,
sdram
->
twr
,
sdram
->
refresh
,
sdram
->
cas_latency
);
cpufreq_gov_userspace_init
();
memcpy
(
&
sdram_params
,
sdram
,
sizeof
(
sdram_params
));
return
cpufreq_register_driver
(
&
sa1110_driver
);
...
...
arch/arm/mach-sa1100/generic.c
View file @
e79b352d
...
...
@@ -96,11 +96,13 @@ int sa11x0_verify_speed(struct cpufreq_policy *policy)
return
0
;
}
unsigned
int
sa11x0_getspeed
(
void
)
unsigned
int
sa11x0_getspeed
(
unsigned
int
cpu
)
{
if
(
cpu
)
return
0
;
return
cclk_frequency_100khz
[
PPCR
&
0xf
]
*
100
;
}
EXPORT_SYMBOL
(
sa11x0_getspeed
);
#else
/*
* We still need to provide this so building without cpufreq works.
...
...
arch/arm/mach-sa1100/generic.h
View file @
e79b352d
...
...
@@ -22,5 +22,5 @@ struct cpufreq_policy;
extern
unsigned
int
sa11x0_freq_to_ppcr
(
unsigned
int
khz
);
extern
int
sa11x0_verify_speed
(
struct
cpufreq_policy
*
policy
);
extern
unsigned
int
sa11x0_getspeed
(
void
);
extern
unsigned
int
sa11x0_getspeed
(
unsigned
int
cpu
);
extern
unsigned
int
sa11x0_ppcr_to_freq
(
unsigned
int
idx
);
arch/i386/kernel/cpu/cpufreq/Makefile
View file @
e79b352d
...
...
@@ -2,15 +2,15 @@ obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7)
+=
powernow-k7.o
obj-$(CONFIG_X86_POWERNOW_K8)
+=
powernow-k8.o
obj-$(CONFIG_X86_LONGHAUL)
+=
longhaul.o
obj-$(CONFIG_X86_P4_CLOCKMOD)
+=
p4-clockmod.o
obj-$(CONFIG_ELAN_CPUFREQ)
+=
elanfreq.o
obj-$(CONFIG_X86_LONGRUN)
+=
longrun.o
obj-$(CONFIG_X86_GX_SUSPMOD)
+=
gx-suspmod.o
obj-$(CONFIG_X86_ACPI_CPUFREQ)
+=
acpi.o
obj-$(CONFIG_X86_SPEEDSTEP_ICH)
+=
speedstep-ich.o
obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)
+=
speedstep-centrino.o
obj-$(CONFIG_X86_SPEEDSTEP_LIB)
+=
speedstep-lib.o
obj-$(CONFIG_X86_SPEEDSTEP_SMI)
+=
speedstep-smi.o
obj-$(CONFIG_X86_ACPI_CPUFREQ)
+=
acpi.o
obj-$(CONFIG_X86_P4_CLOCKMOD)
+=
p4-clockmod.o
ifdef
CONFIG_X86_ACPI_CPUFREQ
ifdef
CONFIG_ACPI_DEBUG
...
...
arch/i386/kernel/cpu/cpufreq/elanfreq.c
View file @
e79b352d
...
...
@@ -77,7 +77,7 @@ static struct cpufreq_frequency_table elanfreq_table[] = {
* and have the rest of the chip running with 33 MHz.
*/
static
unsigned
int
elanfreq_get_cpu_frequency
(
void
)
static
unsigned
int
elanfreq_get_cpu_frequency
(
unsigned
int
cpu
)
{
u8
clockspeed_reg
;
/* Clock Speed Register */
...
...
@@ -121,7 +121,7 @@ static void elanfreq_set_cpu_state (unsigned int state) {
struct
cpufreq_freqs
freqs
;
freqs
.
old
=
elanfreq_get_cpu_frequency
();
freqs
.
old
=
elanfreq_get_cpu_frequency
(
0
);
freqs
.
new
=
elan_multiplier
[
state
].
clock
;
freqs
.
cpu
=
0
;
/* elanfreq.c is UP only driver */
...
...
@@ -209,7 +209,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
/* max freq */
if
(
!
max_freq
)
max_freq
=
elanfreq_get_cpu_frequency
();
max_freq
=
elanfreq_get_cpu_frequency
(
0
);
/* table init */
for
(
i
=
0
;
(
elanfreq_table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
);
i
++
)
{
...
...
@@ -220,7 +220,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
/* cpuinfo and default policy values */
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
transition_latency
=
CPUFREQ_ETERNAL
;
policy
->
cur
=
elanfreq_get_cpu_frequency
();
policy
->
cur
=
elanfreq_get_cpu_frequency
(
0
);
result
=
cpufreq_frequency_table_cpuinfo
(
policy
,
elanfreq_table
);
if
(
result
)
...
...
@@ -267,6 +267,7 @@ static struct freq_attr* elanfreq_attr[] = {
static
struct
cpufreq_driver
elanfreq_driver
=
{
.
get
=
elanfreq_get_cpu_frequency
,
.
verify
=
elanfreq_verify
,
.
target
=
elanfreq_target
,
.
init
=
elanfreq_cpu_init
,
...
...
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
View file @
e79b352d
...
...
@@ -215,7 +215,7 @@ static __init struct pci_dev *gx_detect_chipset(void)
*
* Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs.
*/
static
int
gx_get_cpuspeed
(
void
)
static
unsigned
int
gx_get_cpuspeed
(
unsigned
int
cpu
)
{
if
((
gx_params
->
pci_suscfg
&
SUSMOD
)
==
0
)
return
stock_freq
;
...
...
@@ -271,7 +271,7 @@ static void gx_set_cpuspeed(unsigned int khz)
freqs
.
cpu
=
0
;
freqs
.
old
=
gx_get_cpuspeed
();
freqs
.
old
=
gx_get_cpuspeed
(
0
);
new_khz
=
gx_validate_speed
(
khz
,
&
gx_params
->
on_duration
,
&
gx_params
->
off_duration
);
...
...
@@ -405,7 +405,7 @@ static int cpufreq_gx_target(struct cpufreq_policy *policy,
static
int
cpufreq_gx_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
int
maxfreq
,
curfreq
;
unsigned
int
maxfreq
,
curfreq
;
if
(
!
policy
||
policy
->
cpu
!=
0
)
return
-
ENODEV
;
...
...
@@ -419,7 +419,7 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
maxfreq
=
30000
*
gx_freq_mult
[
getCx86
(
CX86_DIR1
)
&
0x0f
];
}
stock_freq
=
maxfreq
;
curfreq
=
gx_get_cpuspeed
();
curfreq
=
gx_get_cpuspeed
(
0
);
dprintk
(
"cpu max frequency is %d.
\n
"
,
maxfreq
);
dprintk
(
"cpu current frequency is %dkHz.
\n
"
,
curfreq
);
...
...
@@ -446,6 +446,7 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
* MediaGX/Geode GX initialize cpufreq driver
*/
static
struct
cpufreq_driver
gx_suspmod_driver
=
{
.
get
=
gx_get_cpuspeed
,
.
verify
=
cpufreq_gx_verify
,
.
target
=
cpufreq_gx_target
,
.
init
=
cpufreq_gx_cpu_init
,
...
...
arch/i386/kernel/cpu/cpufreq/longhaul.c
View file @
e79b352d
...
...
@@ -82,6 +82,10 @@ static int longhaul_get_cpu_mult (void)
if
(
lo
&
(
1
<<
27
))
invalue
+=
16
;
}
if
(
longhaul_version
==
4
)
{
if
(
lo
&
(
1
<<
27
))
invalue
+=
16
;
}
return
eblcr_table
[
invalue
];
}
...
...
@@ -158,6 +162,22 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
longhaul
.
bits
.
RevisionKey
=
3
;
wrmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
break
;
case
4
:
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
longhaul
.
bits
.
SoftBusRatio
=
clock_ratio_index
&
0xf
;
longhaul
.
bits
.
SoftBusRatio4
=
(
clock_ratio_index
&
0x10
)
>>
4
;
longhaul
.
bits
.
EnableSoftBusRatio
=
1
;
longhaul
.
bits
.
RevisionKey
=
0x0
;
wrmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
__hlt
();
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
longhaul
.
bits
.
EnableSoftBusRatio
=
0
;
longhaul
.
bits
.
RevisionKey
=
0xf
;
wrmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
break
;
}
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
...
...
@@ -207,7 +227,7 @@ static int guess_fsb(int maxmult)
static
int
__init
longhaul_get_ranges
(
void
)
{
struct
cpuinfo_x86
*
c
=
cpu_data
;
unsigned
long
invalue
;
unsigned
long
invalue
,
invalue2
;
unsigned
int
minmult
=
0
,
maxmult
=
0
;
unsigned
int
multipliers
[
32
]
=
{
50
,
30
,
40
,
100
,
55
,
35
,
45
,
95
,
90
,
70
,
80
,
60
,
120
,
75
,
85
,
65
,
...
...
@@ -234,8 +254,6 @@ static int __init longhaul_get_ranges (void)
case
2
:
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
//TODO: Nehemiah may have borken MaxMHzBR.
// need to extrapolate from FSB.
invalue
=
longhaul
.
bits
.
MaxMHzBR
;
if
(
longhaul
.
bits
.
MaxMHzBR4
)
invalue
+=
16
;
...
...
@@ -258,6 +276,38 @@ static int __init longhaul_get_ranges (void)
break
;
}
break
;
case
4
:
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
//TODO: Nehemiah may have borken MaxMHzBR.
// need to extrapolate from FSB.
invalue2
=
longhaul
.
bits
.
MinMHzBR
;
invalue
=
longhaul
.
bits
.
MaxMHzBR
;
if
(
longhaul
.
bits
.
MaxMHzBR4
)
invalue
+=
16
;
maxmult
=
multipliers
[
invalue
];
maxmult
=
longhaul_get_cpu_mult
();
printk
(
KERN_INFO
PFX
" invalue: %ld maxmult: %d
\n
"
,
invalue
,
maxmult
);
printk
(
KERN_INFO
PFX
" invalue2: %ld
\n
"
,
invalue2
);
minmult
=
50
;
switch
(
longhaul
.
bits
.
MaxMHzFSB
)
{
case
0x0
:
fsb
=
133
;
break
;
case
0x1
:
fsb
=
100
;
break
;
case
0x2
:
printk
(
KERN_INFO
PFX
"Invalid (reserved) FSB!
\n
"
);
return
-
EINVAL
;
case
0x3
:
fsb
=
66
;
break
;
}
break
;
}
dprintk
(
KERN_INFO
PFX
"MinMult=%d.%dx MaxMult=%d.%dx
\n
"
,
...
...
@@ -380,6 +430,13 @@ static int longhaul_target (struct cpufreq_policy *policy,
return
0
;
}
static
unsigned
int
longhaul_get
(
unsigned
int
cpu
)
{
if
(
cpu
)
return
0
;
return
(
calc_speed
(
longhaul_get_cpu_mult
(),
fsb
));
}
static
int
__init
longhaul_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
struct
cpuinfo_x86
*
c
=
cpu_data
;
...
...
@@ -423,12 +480,27 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy)
break
;
case
9
:
cpuname
=
"C3 'Nehemiah' [C5N]"
;
longhaul_version
=
2
;
longhaul_version
=
4
;
numscales
=
32
;
memcpy
(
clock_ratio
,
nehemiah_clock_ratio
,
sizeof
(
nehemiah_clock_ratio
));
memcpy
(
eblcr_table
,
nehemiah_eblcr
,
sizeof
(
nehemiah_eblcr
));
switch
(
c
->
x86_mask
)
{
case
0
...
1
:
cpuname
=
"C3 'Nehemiah A' [C5N]"
;
memcpy
(
clock_ratio
,
nehemiah_a_clock_ratio
,
sizeof
(
nehemiah_a_clock_ratio
));
memcpy
(
eblcr_table
,
nehemiah_a_eblcr
,
sizeof
(
nehemiah_a_eblcr
));
break
;
case
2
...
4
:
cpuname
=
"C3 'Nehemiah B' [C5N]"
;
memcpy
(
clock_ratio
,
nehemiah_b_clock_ratio
,
sizeof
(
nehemiah_b_clock_ratio
));
memcpy
(
eblcr_table
,
nehemiah_b_eblcr
,
sizeof
(
nehemiah_b_eblcr
));
break
;
case
5
...
15
:
cpuname
=
"C3 'Nehemiah C' [C5N]"
;
memcpy
(
clock_ratio
,
nehemiah_c_clock_ratio
,
sizeof
(
nehemiah_c_clock_ratio
));
memcpy
(
eblcr_table
,
nehemiah_c_eblcr
,
sizeof
(
nehemiah_c_eblcr
));
break
;
}
break
;
default:
cpuname
=
"Unknown"
;
...
...
@@ -472,6 +544,7 @@ static struct freq_attr* longhaul_attr[] = {
static
struct
cpufreq_driver
longhaul_driver
=
{
.
verify
=
longhaul_verify
,
.
target
=
longhaul_target
,
.
get
=
longhaul_get
,
.
init
=
longhaul_cpu_init
,
.
exit
=
longhaul_cpu_exit
,
.
name
=
"longhaul"
,
...
...
arch/i386/kernel/cpu/cpufreq/longhaul.h
View file @
e79b352d
...
...
@@ -234,14 +234,15 @@ static int __initdata ezrat_eblcr[32] = {
/*
* VIA C3 Nehemiah */
static
int
__initdata
nehemiah_clock_ratio
[
32
]
=
{
static
int
__initdata
nehemiah_a_clock_ratio
[
32
]
=
{
100
,
/* 0000 -> 10.0x */
160
,
/* 0001 -> 16.0x */
-
1
,
/* 0010 -> RESERVED */
-
1
,
/* 0010 ->
RESERVED */
90
,
/* 0011 -> 9.0x */
95
,
/* 0100 -> 9.5x */
-
1
,
/* 0101 -> RESERVED */
-
1
,
/* 0110 -> RESERVED */
-
1
,
/* 0101 ->
RESERVED */
-
1
,
/* 0110 ->
RESERVED */
55
,
/* 0111 -> 5.5x */
60
,
/* 1000 -> 6.0x */
70
,
/* 1001 -> 7.0x */
...
...
@@ -250,8 +251,42 @@ static int __initdata nehemiah_clock_ratio[32] = {
65
,
/* 1100 -> 6.5x */
75
,
/* 1101 -> 7.5x */
85
,
/* 1110 -> 8.5x */
120
,
/* 1111 -> 12.0x */
120
,
/* 1111 -> 12.0x */
100
,
/* 0000 -> 10.0x */
-
1
,
/* 0001 -> RESERVED */
120
,
/* 0010 -> 12.0x */
90
,
/* 0011 -> 9.0x */
105
,
/* 0100 -> 10.5x */
115
,
/* 0101 -> 11.5x */
125
,
/* 0110 -> 12.5x */
135
,
/* 0111 -> 13.5x */
140
,
/* 1000 -> 14.0x */
150
,
/* 1001 -> 15.0x */
160
,
/* 1010 -> 16.0x */
130
,
/* 1011 -> 13.0x */
145
,
/* 1100 -> 14.5x */
155
,
/* 1101 -> 15.5x */
-
1
,
/* 1110 -> RESERVED (13.0x) */
120
,
/* 1111 -> 12.0x */
};
static
int
__initdata
nehemiah_b_clock_ratio
[
32
]
=
{
100
,
/* 0000 -> 10.0x */
160
,
/* 0001 -> 16.0x */
-
1
,
/* 0010 -> RESERVED */
90
,
/* 0011 -> 9.0x */
95
,
/* 0100 -> 9.5x */
-
1
,
/* 0101 -> RESERVED */
-
1
,
/* 0110 -> RESERVED */
55
,
/* 0111 -> 5.5x */
60
,
/* 1000 -> 6.0x */
70
,
/* 1001 -> 7.0x */
80
,
/* 1010 -> 8.0x */
50
,
/* 1011 -> 5.0x */
65
,
/* 1100 -> 6.5x */
75
,
/* 1101 -> 7.5x */
85
,
/* 1110 -> 8.5x */
120
,
/* 1111 -> 12.0x */
100
,
/* 0000 -> 10.0x */
110
,
/* 0001 -> 11.0x */
120
,
/* 0010 -> 12.0x */
...
...
@@ -266,18 +301,88 @@ static int __initdata nehemiah_clock_ratio[32] = {
130
,
/* 1011 -> 13.0x */
145
,
/* 1100 -> 14.5x */
155
,
/* 1101 -> 15.5x */
-
1
,
/* 1110 -> RESERVED */
-
1
,
/* 1110 -> RESERVED
(13.0x)
*/
120
,
/* 1111 -> 12.0x */
};
static
int
__initdata
nehemiah_eblcr
[
32
]
=
{
static
int
__initdata
nehemiah_c_clock_ratio
[
32
]
=
{
100
,
/* 0000 -> 10.0x */
160
,
/* 0001 -> 16.0x */
40
,
/* 0010 -> RESERVED */
90
,
/* 0011 -> 9.0x */
95
,
/* 0100 -> 9.5x */
-
1
,
/* 0101 -> RESERVED */
45
,
/* 0110 -> RESERVED */
55
,
/* 0111 -> 5.5x */
60
,
/* 1000 -> 6.0x */
70
,
/* 1001 -> 7.0x */
80
,
/* 1010 -> 8.0x */
50
,
/* 1011 -> 5.0x */
65
,
/* 1100 -> 6.5x */
75
,
/* 1101 -> 7.5x */
85
,
/* 1110 -> 8.5x */
120
,
/* 1111 -> 12.0x */
100
,
/* 0000 -> 10.0x */
110
,
/* 0001 -> 11.0x */
120
,
/* 0010 -> 12.0x */
90
,
/* 0011 -> 9.0x */
105
,
/* 0100 -> 10.5x */
115
,
/* 0101 -> 11.5x */
125
,
/* 0110 -> 12.5x */
135
,
/* 0111 -> 13.5x */
140
,
/* 1000 -> 14.0x */
150
,
/* 1001 -> 15.0x */
160
,
/* 1010 -> 16.0x */
130
,
/* 1011 -> 13.0x */
145
,
/* 1100 -> 14.5x */
155
,
/* 1101 -> 15.5x */
-
1
,
/* 1110 -> RESERVED (13.0x) */
120
,
/* 1111 -> 12.0x */
};
static
int
__initdata
nehemiah_a_eblcr
[
32
]
=
{
50
,
/* 0000 -> 5.0x */
160
,
/* 0001 -> 16.0x */
-
1
,
/* 0010 -> RESERVED */
-
1
,
/* 0010 ->
RESERVED */
100
,
/* 0011 -> 10.0x */
55
,
/* 0100 -> 5.5x */
-
1
,
/* 0101 -> RESERVED */
-
1
,
/* 0110 -> RESERVED */
-
1
,
/* 0101 -> RESERVED */
-
1
,
/* 0110 -> RESERVED */
95
,
/* 0111 -> 9.5x */
90
,
/* 1000 -> 9.0x */
70
,
/* 1001 -> 7.0x */
80
,
/* 1010 -> 8.0x */
60
,
/* 1011 -> 6.0x */
120
,
/* 1100 -> 12.0x */
75
,
/* 1101 -> 7.5x */
85
,
/* 1110 -> 8.5x */
65
,
/* 1111 -> 6.5x */
90
,
/* 0000 -> 9.0x */
-
1
,
/* 0001 -> RESERVED */
120
,
/* 0010 -> 12.0x */
100
,
/* 0011 -> 10.0x */
135
,
/* 0100 -> 13.5x */
115
,
/* 0101 -> 11.5x */
125
,
/* 0110 -> 12.5x */
105
,
/* 0111 -> 10.5x */
130
,
/* 1000 -> 13.0x */
150
,
/* 1001 -> 15.0x */
160
,
/* 1010 -> 16.0x */
140
,
/* 1011 -> 14.0x */
120
,
/* 1100 -> 12.0x */
155
,
/* 1101 -> 15.5x */
-
1
,
/* 1110 -> RESERVED (13.0x) */
145
/* 1111 -> 14.5x */
/* end of table */
};
static
int
__initdata
nehemiah_b_eblcr
[
32
]
=
{
50
,
/* 0000 -> 5.0x */
160
,
/* 0001 -> 16.0x */
-
1
,
/* 0010 -> RESERVED */
100
,
/* 0011 -> 10.0x */
55
,
/* 0100 -> 5.5x */
-
1
,
/* 0101 -> RESERVED */
-
1
,
/* 0110 -> RESERVED */
95
,
/* 0111 -> 9.5x */
90
,
/* 1000 -> 9.0x */
70
,
/* 1001 -> 7.0x */
...
...
@@ -287,7 +392,6 @@ static int __initdata nehemiah_eblcr[32] = {
75
,
/* 1101 -> 7.5x */
85
,
/* 1110 -> 8.5x */
65
,
/* 1111 -> 6.5x */
90
,
/* 0000 -> 9.0x */
110
,
/* 0001 -> 11.0x */
120
,
/* 0010 -> 12.0x */
...
...
@@ -302,9 +406,46 @@ static int __initdata nehemiah_eblcr[32] = {
140
,
/* 1011 -> 14.0x */
120
,
/* 1100 -> 12.0x */
155
,
/* 1101 -> 15.5x */
-
1
,
/* 1110 -> RESERVED */
-
1
,
/* 1111 -> RESERVED */
-
1
,
/* 1110 -> RESERVED (13.0x) */
145
/* 1111 -> 14.5x */
/* end of table */
};
static
int
__initdata
nehemiah_c_eblcr
[
32
]
=
{
50
,
/* 0000 -> 5.0x */
160
,
/* 0001 -> 16.0x */
40
,
/* 0010 -> RESERVED */
100
,
/* 0011 -> 10.0x */
55
,
/* 0100 -> 5.5x */
-
1
,
/* 0101 -> RESERVED */
45
,
/* 0110 -> RESERVED */
95
,
/* 0111 -> 9.5x */
90
,
/* 1000 -> 9.0x */
70
,
/* 1001 -> 7.0x */
80
,
/* 1010 -> 8.0x */
60
,
/* 1011 -> 6.0x */
120
,
/* 1100 -> 12.0x */
75
,
/* 1101 -> 7.5x */
85
,
/* 1110 -> 8.5x */
65
,
/* 1111 -> 6.5x */
90
,
/* 0000 -> 9.0x */
110
,
/* 0001 -> 11.0x */
120
,
/* 0010 -> 12.0x */
100
,
/* 0011 -> 10.0x */
135
,
/* 0100 -> 13.5x */
115
,
/* 0101 -> 11.5x */
125
,
/* 0110 -> 12.5x */
105
,
/* 0111 -> 10.5x */
130
,
/* 1000 -> 13.0x */
150
,
/* 1001 -> 15.0x */
160
,
/* 1010 -> 16.0x */
140
,
/* 1011 -> 14.0x */
120
,
/* 1100 -> 12.0x */
155
,
/* 1101 -> 15.5x */
-
1
,
/* 1110 -> RESERVED (13.0x) */
145
/* 1111 -> 14.5x */
/* end of table */
};
/*
* Voltage scales. Div/Mod by 1000 to get actual voltage.
* Which scale to use depends on the VRM type in use.
...
...
arch/i386/kernel/cpu/cpufreq/longrun.c
View file @
e79b352d
...
...
@@ -46,11 +46,16 @@ static void __init longrun_get_policy(struct cpufreq_policy *policy)
rdmsr
(
MSR_TMTA_LONGRUN_CTRL
,
msr_lo
,
msr_hi
);
msr_lo
&=
0x0000007F
;
msr_hi
&=
0x0000007F
;
policy
->
min
=
longrun_low_freq
+
msr_lo
*
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
policy
->
max
=
longrun_low_freq
+
msr_hi
*
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
if
(
longrun_high_freq
<=
longrun_low_freq
)
{
/* Assume degenerate Longrun table */
policy
->
min
=
policy
->
max
=
longrun_high_freq
;
}
else
{
policy
->
min
=
longrun_low_freq
+
msr_lo
*
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
policy
->
max
=
longrun_low_freq
+
msr_hi
*
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
}
policy
->
cpu
=
0
;
}
...
...
@@ -70,10 +75,15 @@ static int longrun_set_policy(struct cpufreq_policy *policy)
if
(
!
policy
)
return
-
EINVAL
;
pctg_lo
=
(
policy
->
min
-
longrun_low_freq
)
/
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
pctg_hi
=
(
policy
->
max
-
longrun_low_freq
)
/
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
if
(
longrun_high_freq
<=
longrun_low_freq
)
{
/* Assume degenerate Longrun table */
pctg_lo
=
pctg_hi
=
100
;
}
else
{
pctg_lo
=
(
policy
->
min
-
longrun_low_freq
)
/
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
pctg_hi
=
(
policy
->
max
-
longrun_low_freq
)
/
((
longrun_high_freq
-
longrun_low_freq
)
/
100
);
}
if
(
pctg_hi
>
100
)
pctg_hi
=
100
;
...
...
@@ -128,6 +138,17 @@ static int longrun_verify_policy(struct cpufreq_policy *policy)
return
0
;
}
static
unsigned
int
longrun_get
(
unsigned
int
cpu
)
{
u32
eax
,
ebx
,
ecx
,
edx
;
if
(
cpu
)
return
0
;
cpuid
(
0x80860007
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
return
(
eax
*
1000
);
}
/**
* longrun_determine_freqs - determines the lowest and highest possible core frequency
...
...
@@ -250,8 +271,10 @@ static int __init longrun_cpu_init(struct cpufreq_policy *policy)
static
struct
cpufreq_driver
longrun_driver
=
{
.
flags
=
CPUFREQ_CONST_LOOPS
,
.
verify
=
longrun_verify_policy
,
.
setpolicy
=
longrun_set_policy
,
.
get
=
longrun_get
,
.
init
=
longrun_cpu_init
,
.
name
=
"longrun"
,
.
owner
=
THIS_MODULE
,
...
...
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
View file @
e79b352d
...
...
@@ -51,55 +51,16 @@ enum {
static
int
has_N44_O17_errata
[
NR_CPUS
];
static
unsigned
int
stock_freq
;
static
struct
cpufreq_driver
p4clockmod_driver
;
static
unsigned
int
cpufreq_p4_get
(
unsigned
int
cpu
);
static
int
cpufreq_p4_setdc
(
unsigned
int
cpu
,
unsigned
int
newstate
)
{
u32
l
,
h
;
cpumask_t
cpus_allowed
,
affected_cpu_map
;
struct
cpufreq_freqs
freqs
;
int
j
;
if
(
!
cpu_online
(
cpu
)
||
(
newstate
>
DC_DISABLE
)
||
(
newstate
==
DC_RESV
))
if
(
!
cpu_online
(
cpu
)
||
(
newstate
>
DC_DISABLE
)
||
(
newstate
==
DC_RESV
))
return
-
EINVAL
;
/* switch to physical CPU where state is to be changed*/
cpus_allowed
=
current
->
cpus_allowed
;
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
affected_cpu_map
=
cpu_sibling_map
[
cpu
];
#else
affected_cpu_map
=
cpumask_of_cpu
(
cpu
);
#endif
set_cpus_allowed
(
current
,
affected_cpu_map
);
BUG_ON
(
!
cpu_isset
(
smp_processor_id
(),
affected_cpu_map
));
/* get current state */
rdmsr
(
MSR_IA32_THERM_CONTROL
,
l
,
h
);
if
(
l
&
0x10
)
{
l
=
l
>>
1
;
l
&=
0x7
;
}
else
l
=
DC_DISABLE
;
if
(
l
==
newstate
)
{
set_cpus_allowed
(
current
,
cpus_allowed
);
return
0
;
}
else
if
(
l
==
DC_RESV
)
{
printk
(
KERN_ERR
PFX
"BIG FAT WARNING: currently in invalid setting
\n
"
);
}
/* notifiers */
freqs
.
old
=
stock_freq
*
l
/
8
;
freqs
.
new
=
stock_freq
*
newstate
/
8
;
for_each_cpu
(
j
)
{
if
(
cpu_isset
(
j
,
affected_cpu_map
))
{
freqs
.
cpu
=
j
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
}
}
rdmsr
(
MSR_IA32_THERM_STATUS
,
l
,
h
);
#if 0
if (l & 0x01)
...
...
@@ -125,16 +86,6 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
wrmsr
(
MSR_IA32_THERM_CONTROL
,
l
,
h
);
}
set_cpus_allowed
(
current
,
cpus_allowed
);
/* notifiers */
for_each_cpu
(
j
)
{
if
(
cpu_isset
(
j
,
affected_cpu_map
))
{
freqs
.
cpu
=
j
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
}
}
return
0
;
}
...
...
@@ -158,11 +109,59 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
unsigned
int
relation
)
{
unsigned
int
newstate
=
DC_RESV
;
struct
cpufreq_freqs
freqs
;
cpumask_t
cpus_allowed
,
affected_cpu_map
;
int
i
;
if
(
cpufreq_frequency_table_target
(
policy
,
&
p4clockmod_table
[
0
],
target_freq
,
relation
,
&
newstate
))
return
-
EINVAL
;
cpufreq_p4_setdc
(
policy
->
cpu
,
p4clockmod_table
[
newstate
].
index
);
freqs
.
old
=
cpufreq_p4_get
(
policy
->
cpu
);
freqs
.
new
=
stock_freq
*
p4clockmod_table
[
newstate
].
index
/
8
;
if
(
freqs
.
new
==
freqs
.
old
)
return
0
;
/* switch to physical CPU where state is to be changed*/
cpus_allowed
=
current
->
cpus_allowed
;
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
affected_cpu_map
=
cpu_sibling_map
[
policy
->
cpu
];
#else
affected_cpu_map
=
cpumask_of_cpu
(
policy
->
cpu
);
#endif
/* notifiers */
for_each_cpu
(
i
)
{
if
(
cpu_isset
(
i
,
affected_cpu_map
))
{
freqs
.
cpu
=
i
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
}
}
/* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software
* Developer's Manual, Volume 3
*/
for_each_cpu
(
i
)
{
if
(
cpu_isset
(
i
,
affected_cpu_map
))
{
cpumask_t
this_cpu
=
cpumask_of_cpu
(
i
);
set_cpus_allowed
(
current
,
this_cpu
);
BUG_ON
(
smp_processor_id
()
!=
i
);
cpufreq_p4_setdc
(
i
,
p4clockmod_table
[
newstate
].
index
);
}
}
set_cpus_allowed
(
current
,
cpus_allowed
);
/* notifiers */
for_each_cpu
(
i
)
{
if
(
cpu_isset
(
i
,
affected_cpu_map
))
{
freqs
.
cpu
=
i
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
}
}
return
0
;
}
...
...
@@ -177,11 +176,23 @@ static int cpufreq_p4_verify(struct cpufreq_policy *policy)
static
unsigned
int
cpufreq_p4_get_frequency
(
struct
cpuinfo_x86
*
c
)
{
if
((
c
->
x86
==
0x06
)
&&
(
c
->
x86_model
==
0x09
))
{
/* Pentium M */
/* Pentium M (Banias) */
printk
(
KERN_WARNING
PFX
"Warning: Pentium M detected. "
"The speedstep_centrino module offers voltage scaling"
" in addition of frequency scaling. You should use "
"that instead of p4-clockmod, if possible.
\n
"
);
return
speedstep_get_processor_frequency
(
SPEEDSTEP_PROCESSOR_PM
);
}
if
((
c
->
x86
==
0x06
)
&&
(
c
->
x86_model
==
0x13
))
{
/* Pentium M (Dothan) */
printk
(
KERN_WARNING
PFX
"Warning: Pentium M detected. "
"The speedstep_centrino module offers voltage scaling"
" in addition of frequency scaling. You should use "
"that instead of p4-clockmod, if possible.
\n
"
);
/* on P-4s, the TSC runs with constant frequency independent wether
* throttling is active or not. */
p4clockmod_driver
.
flags
|=
CPUFREQ_CONST_LOOPS
;
return
speedstep_get_processor_frequency
(
SPEEDSTEP_PROCESSOR_PM
);
}
...
...
@@ -190,6 +201,10 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
return
0
;
}
/* on P-4s, the TSC runs with constant frequency independent wether
* throttling is active or not. */
p4clockmod_driver
.
flags
|=
CPUFREQ_CONST_LOOPS
;
if
(
speedstep_detect_processor
()
==
SPEEDSTEP_PROCESSOR_P4M
)
{
printk
(
KERN_WARNING
PFX
"Warning: Pentium 4-M detected. "
"The speedstep-ich or acpi cpufreq modules offer "
...
...
@@ -249,6 +264,33 @@ static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy)
return
0
;
}
static
unsigned
int
cpufreq_p4_get
(
unsigned
int
cpu
)
{
cpumask_t
cpus_allowed
,
affected_cpu_map
;
u32
l
,
h
;
cpus_allowed
=
current
->
cpus_allowed
;
affected_cpu_map
=
cpumask_of_cpu
(
cpu
);
set_cpus_allowed
(
current
,
affected_cpu_map
);
BUG_ON
(
!
cpu_isset
(
smp_processor_id
(),
affected_cpu_map
));
rdmsr
(
MSR_IA32_THERM_CONTROL
,
l
,
h
);
set_cpus_allowed
(
current
,
cpus_allowed
);
if
(
l
&
0x10
)
{
l
=
l
>>
1
;
l
&=
0x7
;
}
else
l
=
DC_DISABLE
;
if
(
l
!=
DC_DISABLE
)
return
(
stock_freq
*
l
/
8
);
return
stock_freq
;
}
static
struct
freq_attr
*
p4clockmod_attr
[]
=
{
&
cpufreq_freq_attr_scaling_available_freqs
,
NULL
,
...
...
@@ -259,6 +301,7 @@ static struct cpufreq_driver p4clockmod_driver = {
.
target
=
cpufreq_p4_target
,
.
init
=
cpufreq_p4_cpu_init
,
.
exit
=
cpufreq_p4_cpu_exit
,
.
get
=
cpufreq_p4_get
,
.
name
=
"p4-clockmod"
,
.
owner
=
THIS_MODULE
,
.
attr
=
p4clockmod_attr
,
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k6.c
View file @
e79b352d
...
...
@@ -185,6 +185,11 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
return
0
;
}
static
unsigned
int
powernow_k6_get
(
unsigned
int
cpu
)
{
return
busfreq
*
powernow_k6_get_cpu_multiplier
();
}
static
struct
freq_attr
*
powernow_k6_attr
[]
=
{
&
cpufreq_freq_attr_scaling_available_freqs
,
NULL
,
...
...
@@ -195,6 +200,7 @@ static struct cpufreq_driver powernow_k6_driver = {
.
target
=
powernow_k6_target
,
.
init
=
powernow_k6_cpu_init
,
.
exit
=
powernow_k6_cpu_exit
,
.
get
=
powernow_k6_get
,
.
name
=
"powernow-k6"
,
.
owner
=
THIS_MODULE
,
.
attr
=
powernow_k6_attr
,
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
View file @
e79b352d
...
...
@@ -540,6 +540,20 @@ static int __init fixup_sgtc(void)
return
sgtc
;
}
static
unsigned
int
powernow_get
(
unsigned
int
cpu
)
{
union
msr_fidvidstatus
fidvidstatus
;
unsigned
int
cfid
;
if
(
cpu
)
return
0
;
rdmsrl
(
MSR_K7_FID_VID_STATUS
,
fidvidstatus
.
val
);
cfid
=
fidvidstatus
.
bits
.
CFID
;
return
(
fsb
*
fid_codes
[
cfid
]
/
10
);
}
static
int
__init
powernow_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
union
msr_fidvidstatus
fidvidstatus
;
...
...
@@ -590,7 +604,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
policy
->
cpuinfo
.
transition_latency
=
20
*
latency
/
fsb
;
policy
->
cur
=
maximum_speed
;
policy
->
cur
=
powernow_get
(
0
)
;
cpufreq_frequency_table_get_attr
(
powernow_table
,
policy
->
cpu
);
...
...
@@ -610,6 +624,7 @@ 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"
,
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
View file @
e79b352d
...
...
@@ -32,14 +32,14 @@
#include <asm/io.h>
#include <asm/delay.h>
#if
def CONFIG_ACPI_PROCESSOR
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif
#define PFX "powernow-k8: "
#define BFX PFX "BIOS error: "
#define VERSION "version 1.00.0
8
b"
#define VERSION "version 1.00.0
9
b"
#include "powernow-k8.h"
/* serialize freq changes */
...
...
@@ -450,13 +450,10 @@ static int check_supported_cpu(unsigned int cpu)
goto
out
;
eax
=
cpuid_eax
(
CPUID_PROCESSOR_SIGNATURE
);
if
((
eax
&
CPUID_XFAM_MOD
)
==
ATHLON64_XFAM_MOD
)
{
dprintk
(
KERN_DEBUG
PFX
"AMD Althon 64 Processor found
\n
"
);
}
else
if
((
eax
&
CPUID_XFAM_MOD
)
==
OPTERON_XFAM_MOD
)
{
dprintk
(
KERN_DEBUG
PFX
"AMD Opteron Processor found
\n
"
);
}
else
{
printk
(
KERN_INFO
PFX
"AMD Athlon 64 or AMD Opteron processor required
\n
"
);
if
(((
eax
&
CPUID_USE_XFAM_XMOD
)
!=
CPUID_USE_XFAM_XMOD
)
||
((
eax
&
CPUID_XFAM
)
!=
CPUID_XFAM_K8
)
||
((
eax
&
CPUID_XMOD
)
>
CPUID_XMOD_REV_E
))
{
printk
(
KERN_INFO
PFX
"Processor cpuid %x not supported
\n
"
,
eax
);
goto
out
;
}
...
...
@@ -524,11 +521,12 @@ static void print_basics(struct powernow_k8_data *data)
{
int
j
;
for
(
j
=
0
;
j
<
data
->
numps
;
j
++
)
{
printk
(
KERN_INFO
PFX
" %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)
\n
"
,
j
,
data
->
powernow_table
[
j
].
index
&
0xff
,
data
->
powernow_table
[
j
].
frequency
/
1000
,
data
->
powernow_table
[
j
].
index
>>
8
,
find_millivolts_from_vid
(
data
,
data
->
powernow_table
[
j
].
index
>>
8
));
if
(
data
->
powernow_table
[
j
].
frequency
!=
CPUFREQ_ENTRY_INVALID
)
printk
(
KERN_INFO
PFX
" %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)
\n
"
,
j
,
data
->
powernow_table
[
j
].
index
&
0xff
,
data
->
powernow_table
[
j
].
frequency
/
1000
,
data
->
powernow_table
[
j
].
index
>>
8
,
find_millivolts_from_vid
(
data
,
data
->
powernow_table
[
j
].
index
>>
8
));
}
if
(
data
->
batps
)
printk
(
KERN_INFO
PFX
"Only %d pstates on battery
\n
"
,
data
->
batps
);
...
...
@@ -666,7 +664,7 @@ static int find_psb_table(struct powernow_k8_data *data)
return
-
ENODEV
;
}
#if
def CONFIG_ACPI_PROCESSOR
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
static
void
powernow_k8_acpi_pst_values
(
struct
powernow_k8_data
*
data
,
unsigned
int
index
)
{
if
(
!
data
->
acpi_data
.
state_count
)
...
...
@@ -723,7 +721,14 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
/* verify frequency is OK */
if
((
powernow_table
[
i
].
frequency
>
(
MAX_FREQ
*
1000
))
||
(
powernow_table
[
i
].
frequency
<
(
MIN_FREQ
*
1000
)))
{
dprintk
(
KERN_INFO
PFX
"invalid freq %u kHz
\n
"
,
powernow_table
[
i
].
frequency
);
dprintk
(
KERN_INFO
PFX
"invalid freq %u kHz, ignoring
\n
"
,
powernow_table
[
i
].
frequency
);
powernow_table
[
i
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
continue
;
}
/* verify voltage is OK - BIOSs are using "off" to indicate invalid */
if
(
vid
==
0x1f
)
{
dprintk
(
KERN_INFO
PFX
"invalid vid %u, ignoring
\n
"
,
vid
);
powernow_table
[
i
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
continue
;
}
...
...
@@ -1025,6 +1030,32 @@ static int __exit powernowk8_cpu_exit (struct cpufreq_policy *pol)
return
0
;
}
static
unsigned
int
powernowk8_get
(
unsigned
int
cpu
)
{
struct
powernow_k8_data
*
data
=
powernow_data
[
cpu
];
cpumask_t
oldmask
=
current
->
cpus_allowed
;
unsigned
int
khz
=
0
;
set_cpus_allowed
(
current
,
cpumask_of_cpu
(
cpu
));
if
(
smp_processor_id
()
!=
cpu
)
{
printk
(
KERN_ERR
PFX
"limiting to CPU %d failed in powernowk8_get
\n
"
,
cpu
);
set_cpus_allowed
(
current
,
oldmask
);
return
0
;
}
preempt_disable
();
if
(
query_current_values_with_pending_wait
(
data
))
goto
out
;
khz
=
find_khz_freq_from_fid
(
data
->
currfid
);
out:
preempt_enable_no_resched
();
set_cpus_allowed
(
current
,
oldmask
);
return
khz
;
}
static
struct
freq_attr
*
powernow_k8_attr
[]
=
{
&
cpufreq_freq_attr_scaling_available_freqs
,
NULL
,
...
...
@@ -1035,6 +1066,7 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
.
target
=
powernowk8_target
,
.
init
=
powernowk8_cpu_init
,
.
exit
=
powernowk8_cpu_exit
,
.
get
=
powernowk8_get
,
.
name
=
"powernow-k8"
,
.
owner
=
THIS_MODULE
,
.
attr
=
powernow_k8_attr
,
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
View file @
e79b352d
...
...
@@ -29,7 +29,7 @@ struct powernow_k8_data {
* frequency is in kHz */
struct
cpufreq_frequency_table
*
powernow_table
;
#if
def CONFIG_ACPI_PROCESSOR
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
/* the acpi table needs to be kept. it's only available if ACPI was
* used to determine valid frequency/vid/fid states */
struct
acpi_processor_performance
acpi_data
;
...
...
@@ -38,13 +38,15 @@ struct powernow_k8_data {
/* processor's cpuid instruction support */
#define CPUID_PROCESSOR_SIGNATURE 1
/* function 1 */
#define CPUID_XFAM_MOD 0x0ff00ff0
/* extended fam, fam + model */
#define ATHLON64_XFAM_MOD 0x00000f40
/* extended fam, fam + model */
#define OPTERON_XFAM_MOD 0x00000f50
/* extended fam, fam + model */
#define CPUID_GET_MAX_CAPABILITIES 0x80000000
#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
#define P_STATE_TRANSITION_CAPABLE 6
#define CPUID_PROCESSOR_SIGNATURE 1
/* function 1 */
#define CPUID_XFAM 0x0ff00000
/* extended family */
#define CPUID_XFAM_K8 0
#define CPUID_XMOD 0x000f0000
/* extended model */
#define CPUID_XMOD_REV_E 0x00020000
#define CPUID_USE_XFAM_XMOD 0x00000f00
#define CPUID_GET_MAX_CAPABILITIES 0x80000000
#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
#define P_STATE_TRANSITION_CAPABLE 6
/* Model Specific Registers for p-state transitions. MSRs are 64-bit. For */
/* writes (wrmsr - opcode 0f 30), the register number is placed in ecx, and */
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
View file @
e79b352d
...
...
@@ -38,13 +38,37 @@
#define dprintk(msg...) do { } while(0)
#endif
struct
cpu_id
{
__u8
x86
;
/* CPU family */
__u8
x86_vendor
;
/* CPU vendor */
__u8
x86_model
;
/* model */
__u8
x86_mask
;
/* stepping */
};
static
const
struct
cpu_id
cpu_id_banias
=
{
.
x86_vendor
=
X86_VENDOR_INTEL
,
.
x86
=
6
,
.
x86_model
=
9
,
.
x86_mask
=
5
,
};
static
const
struct
cpu_id
cpu_id_dothan_a1
=
{
.
x86_vendor
=
X86_VENDOR_INTEL
,
.
x86
=
6
,
.
x86_model
=
13
,
.
x86_mask
=
1
,
};
struct
cpu_model
{
const
struct
cpu_id
*
cpu_id
;
const
char
*
model_name
;
unsigned
max_freq
;
/* max clock in kHz */
struct
cpufreq_frequency_table
*
op_points
;
/* clock/voltage pairs */
};
static
int
centrino_verify_cpu_id
(
struct
cpuinfo_x86
*
c
,
const
struct
cpu_id
*
x
);
/* Operating points for current CPU */
static
struct
cpu_model
*
centrino_model
;
...
...
@@ -67,8 +91,8 @@ static struct cpu_model *centrino_model;
* M.
*/
/* Ultra Low Voltage Intel Pentium M processor 900MHz */
static
struct
cpufreq_frequency_table
op
_900
[]
=
/* Ultra Low Voltage Intel Pentium M processor 900MHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_900
[]
=
{
OP
(
600
,
844
),
OP
(
800
,
988
),
...
...
@@ -76,8 +100,8 @@ static struct cpufreq_frequency_table op_900[] =
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
/* Ultra Low Voltage Intel Pentium M processor 1000MHz */
static
struct
cpufreq_frequency_table
op
_1000
[]
=
/* Ultra Low Voltage Intel Pentium M processor 1000MHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1000
[]
=
{
OP
(
600
,
844
),
OP
(
800
,
972
),
...
...
@@ -86,8 +110,8 @@ static struct cpufreq_frequency_table op_1000[] =
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
/* Low Voltage Intel Pentium M processor 1.10GHz */
static
struct
cpufreq_frequency_table
op
_1100
[]
=
/* Low Voltage Intel Pentium M processor 1.10GHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1100
[]
=
{
OP
(
600
,
956
),
OP
(
800
,
1020
),
...
...
@@ -98,8 +122,8 @@ static struct cpufreq_frequency_table op_1100[] =
};
/* Low Voltage Intel Pentium M processor 1.20GHz */
static
struct
cpufreq_frequency_table
op
_1200
[]
=
/* Low Voltage Intel Pentium M processor 1.20GHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1200
[]
=
{
OP
(
600
,
956
),
OP
(
800
,
1004
),
...
...
@@ -110,8 +134,8 @@ static struct cpufreq_frequency_table op_1200[] =
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
/* Intel Pentium M processor 1.30GHz */
static
struct
cpufreq_frequency_table
op
_1300
[]
=
/* Intel Pentium M processor 1.30GHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1300
[]
=
{
OP
(
600
,
956
),
OP
(
800
,
1260
),
...
...
@@ -121,8 +145,8 @@ static struct cpufreq_frequency_table op_1300[] =
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
/* Intel Pentium M processor 1.40GHz */
static
struct
cpufreq_frequency_table
op
_1400
[]
=
/* Intel Pentium M processor 1.40GHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1400
[]
=
{
OP
(
600
,
956
),
OP
(
800
,
1180
),
...
...
@@ -132,8 +156,8 @@ static struct cpufreq_frequency_table op_1400[] =
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
/* Intel Pentium M processor 1.50GHz */
static
struct
cpufreq_frequency_table
op
_1500
[]
=
/* Intel Pentium M processor 1.50GHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1500
[]
=
{
OP
(
600
,
956
),
OP
(
800
,
1116
),
...
...
@@ -144,8 +168,8 @@ static struct cpufreq_frequency_table op_1500[] =
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
/* Intel Pentium M processor 1.60GHz */
static
struct
cpufreq_frequency_table
op
_1600
[]
=
/* Intel Pentium M processor 1.60GHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1600
[]
=
{
OP
(
600
,
956
),
OP
(
800
,
1036
),
...
...
@@ -156,8 +180,8 @@ static struct cpufreq_frequency_table op_1600[] =
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
/* Intel Pentium M processor 1.70GHz */
static
struct
cpufreq_frequency_table
op
_1700
[]
=
/* Intel Pentium M processor 1.70GHz
(Banias)
*/
static
struct
cpufreq_frequency_table
banias
_1700
[]
=
{
OP
(
600
,
956
),
OP
(
800
,
1004
),
...
...
@@ -169,26 +193,31 @@ static struct cpufreq_frequency_table op_1700[] =
};
#undef OP
#define _CPU(max, name) \
{ "Intel(R) Pentium(R) M processor " name "MHz", (max)*1000, op_##max }
#define CPU(max) _CPU(max, #max)
#define _BANIAS(cpuid, max, name) \
{ .cpu_id = cpuid, \
.model_name = "Intel(R) Pentium(R) M processor " name "MHz", \
.max_freq = (max)*1000, \
.op_points = banias_##max, \
}
#define BANIAS(max) _BANIAS(&cpu_id_banias, max, #max)
/* CPU models, their operating frequency range, and freq/voltage
operating points */
static
struct
cpu_model
models
[]
=
{
_CPU
(
900
,
" 900"
),
CPU
(
1000
),
CPU
(
1100
),
CPU
(
1200
),
CPU
(
1300
),
CPU
(
1400
),
CPU
(
1500
),
CPU
(
1600
),
CPU
(
1700
),
_BANIAS
(
&
cpu_id_banias
,
900
,
" 900"
),
BANIAS
(
1000
),
BANIAS
(
1100
),
BANIAS
(
1200
),
BANIAS
(
1300
),
BANIAS
(
1400
),
BANIAS
(
1500
),
BANIAS
(
1600
),
BANIAS
(
1700
),
{
0
,
}
};
#undef CPU
#undef _BANIAS
#undef BANIAS
static
int
centrino_cpu_init_table
(
struct
cpufreq_policy
*
policy
)
{
...
...
@@ -196,7 +225,8 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
struct
cpu_model
*
model
;
for
(
model
=
models
;
model
->
model_name
!=
NULL
;
model
++
)
if
(
strcmp
(
cpu
->
x86_model_id
,
model
->
model_name
)
==
0
)
if
((
strcmp
(
cpu
->
x86_model_id
,
model
->
model_name
)
==
0
)
&&
(
!
centrino_verify_cpu_id
(
cpu
,
model
->
cpu_id
)))
break
;
if
(
model
->
model_name
==
NULL
)
{
printk
(
KERN_INFO
PFX
"no support for CPU model
\"
%s
\"
: "
...
...
@@ -217,6 +247,16 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
static
inline
int
centrino_cpu_init_table
(
struct
cpufreq_policy
*
policy
)
{
return
-
ENODEV
;
}
#endif
/* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */
static
int
centrino_verify_cpu_id
(
struct
cpuinfo_x86
*
c
,
const
struct
cpu_id
*
x
)
{
if
((
c
->
x86
==
x
->
x86
)
&&
(
c
->
x86_vendor
==
x
->
x86_vendor
)
&&
(
c
->
x86_model
==
x
->
x86_model
)
&&
(
c
->
x86_mask
==
x
->
x86_mask
))
return
0
;
return
-
ENODEV
;
}
/* Extract clock in kHz from PERF_CTL value */
static
unsigned
extract_clock
(
unsigned
msr
)
{
...
...
@@ -225,9 +265,11 @@ static unsigned extract_clock(unsigned msr)
}
/* Return the current CPU frequency in kHz */
static
unsigned
get_cur_freq
(
void
)
static
unsigned
int
get_cur_freq
(
unsigned
int
cpu
)
{
unsigned
l
,
h
;
if
(
cpu
)
return
0
;
rdmsr
(
MSR_IA32_PERF_STATUS
,
l
,
h
);
return
extract_clock
(
l
);
...
...
@@ -322,7 +364,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
goto
err_kfree
;
}
cur_freq
=
get_cur_freq
();
cur_freq
=
get_cur_freq
(
0
);
for
(
i
=
0
;
i
<
p
.
state_count
;
i
++
)
{
centrino_model
->
op_points
[
i
].
index
=
p
.
states
[
i
].
control
;
...
...
@@ -357,13 +399,8 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
if
(
!
cpu_has
(
cpu
,
X86_FEATURE_EST
))
return
-
ENODEV
;
/* Only Intel Pentium M stepping 5 for now - add new CPUs as
they appear after making sure they use PERF_CTL in the same
way. */
if
(
cpu
->
x86_vendor
!=
X86_VENDOR_INTEL
||
cpu
->
x86
!=
6
||
cpu
->
x86_model
!=
9
||
cpu
->
x86_mask
!=
5
)
{
if
((
centrino_verify_cpu_id
(
cpu
,
&
cpu_id_banias
))
&&
(
centrino_verify_cpu_id
(
cpu
,
&
cpu_id_dothan_a1
)))
{
printk
(
KERN_INFO
PFX
"found unsupported CPU with Enhanced SpeedStep: "
"send /proc/cpuinfo to "
MAINTAINER
"
\n
"
);
return
-
ENODEV
;
...
...
@@ -391,10 +428,10 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
}
}
freq
=
get_cur_freq
();
freq
=
get_cur_freq
(
0
);
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
transition_latency
=
10
;
/* 10uS transition latency */
policy
->
cpuinfo
.
transition_latency
=
10
000
;
/* 10uS transition latency */
policy
->
cur
=
freq
;
dprintk
(
KERN_INFO
PFX
"centrino_cpu_init: policy=%d cur=%dkHz
\n
"
,
...
...
@@ -516,6 +553,7 @@ static struct cpufreq_driver centrino_driver = {
.
exit
=
centrino_cpu_exit
,
.
verify
=
centrino_verify
,
.
target
=
centrino_target
,
.
get
=
get_cur_freq
,
.
attr
=
centrino_attr
,
.
owner
=
THIS_MODULE
,
};
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
View file @
e79b352d
...
...
@@ -179,7 +179,7 @@ static int speedstep_activate (void)
/**
* speedstep_detect_chipset - detect the Southbridge which contains SpeedStep logic
*
* Detects
PIIX4, ICH2-M and ICH3
-M so far. The pci_dev points to
* Detects
ICH2-M, ICH3-M and ICH4
-M so far. The pci_dev points to
* the LPC bridge / PM module which contains all power-management
* functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected
* chipset, or zero on failure.
...
...
@@ -322,6 +322,10 @@ static int speedstep_cpu_exit(struct cpufreq_policy *policy)
return
0
;
}
static
unsigned
int
speedstep_get
(
unsigned
int
cpu
)
{
return
speedstep_get_processor_frequency
(
speedstep_processor
);
}
static
struct
freq_attr
*
speedstep_attr
[]
=
{
&
cpufreq_freq_attr_scaling_available_freqs
,
...
...
@@ -335,6 +339,7 @@ static struct cpufreq_driver speedstep_driver = {
.
target
=
speedstep_target
,
.
init
=
speedstep_cpu_init
,
.
exit
=
speedstep_cpu_exit
,
.
get
=
speedstep_get
,
.
owner
=
THIS_MODULE
,
.
attr
=
speedstep_attr
,
};
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
View file @
e79b352d
...
...
@@ -36,6 +36,8 @@ static int smi_port = 0;
static
int
smi_cmd
=
0
;
static
unsigned
int
smi_sig
=
0
;
/* info about the processor */
static
unsigned
int
speedstep_processor
=
0
;
/*
* There are only two frequency states for each processor. Values
...
...
@@ -258,9 +260,10 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
&
speedstep_freqs
[
SPEEDSTEP_HIGH
].
frequency
);
if
(
result
)
{
/* fall back to speedstep_lib.c dection mechanism: try both states out */
unsigned
int
speedstep_processor
=
speedstep_detect_processor
();
dprintk
(
KERN_INFO
PFX
"could not detect low and high frequencies by SMI call.
\n
"
);
if
(
!
speedstep_processor
)
speedstep_processor
=
speedstep_detect_processor
();
if
(
!
speedstep_processor
)
return
-
ENODEV
;
...
...
@@ -298,13 +301,23 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
return
0
;
}
static
int
speedstep_cpu_exit
(
struct
cpufreq_policy
*
policy
)
{
cpufreq_frequency_table_put_attr
(
policy
->
cpu
);
return
0
;
}
static
unsigned
int
speedstep_get
(
unsigned
int
cpu
)
{
if
(
cpu
)
return
-
ENODEV
;
if
(
!
speedstep_processor
)
speedstep_processor
=
speedstep_detect_processor
();
if
(
!
speedstep_processor
)
return
0
;
return
speedstep_get_processor_frequency
(
speedstep_processor
);
}
static
int
speedstep_resume
(
struct
cpufreq_policy
*
policy
)
{
...
...
@@ -327,6 +340,7 @@ static struct cpufreq_driver speedstep_driver = {
.
target
=
speedstep_target
,
.
init
=
speedstep_cpu_init
,
.
exit
=
speedstep_cpu_exit
,
.
get
=
speedstep_get
,
.
resume
=
speedstep_resume
,
.
owner
=
THIS_MODULE
,
.
attr
=
speedstep_attr
,
...
...
arch/i386/kernel/timers/timer_tsc.c
View file @
e79b352d
...
...
@@ -27,6 +27,8 @@ static unsigned long hpet_last;
struct
timer_opts
timer_tsc
;
#endif
static
inline
void
cpufreq_delayed_get
(
void
);
int
tsc_disable
__initdata
=
0
;
extern
spinlock_t
i8253_lock
;
...
...
@@ -241,6 +243,9 @@ static void mark_offset_tsc(void)
clock_fallback
();
}
/* ... but give the TSC a fair chance */
if
(
lost_count
>
25
)
cpufreq_delayed_get
();
}
else
lost_count
=
0
;
/* update the monotonic base value */
...
...
@@ -324,15 +329,40 @@ static void mark_offset_tsc_hpet(void)
#ifdef CONFIG_CPU_FREQ
#include <linux/workqueue.h>
static
unsigned
int
cpufreq_delayed_issched
=
0
;
static
unsigned
int
cpufreq_init
=
0
;
static
struct
work_struct
cpufreq_delayed_get_work
;
static
void
handle_cpufreq_delayed_get
(
void
*
v
)
{
unsigned
int
cpu
;
for_each_online_cpu
(
cpu
)
{
cpufreq_get
(
cpu
);
}
cpufreq_delayed_issched
=
0
;
}
/* if we notice lost ticks, schedule a call to cpufreq_get() as it tries
* to verify the CPU frequency the timing core thinks the CPU is running
* at is still correct.
*/
static
inline
void
cpufreq_delayed_get
(
void
)
{
if
(
cpufreq_init
&&
!
cpufreq_delayed_issched
)
{
cpufreq_delayed_issched
=
1
;
printk
(
KERN_DEBUG
"Losing some ticks... checking if CPU frequency changed.
\n
"
);
schedule_work
(
&
cpufreq_delayed_get_work
);
}
}
/* If the CPU frequency is scaled, TSC-based delays will need a different
* loops_per_jiffy value to function properly. An exception to this
* are modern Intel Pentium 4 processors, where the TSC runs at a constant
* speed independent of frequency scaling.
* loops_per_jiffy value to function properly.
*/
static
unsigned
int
ref_freq
=
0
;
static
unsigned
long
loops_per_jiffy_ref
=
0
;
static
unsigned
int
variable_tsc
=
1
;
#ifndef CONFIG_SMP
static
unsigned
long
fast_gettimeoffset_ref
=
0
;
...
...
@@ -356,14 +386,15 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
}
if
((
val
==
CPUFREQ_PRECHANGE
&&
freq
->
old
<
freq
->
new
)
||
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
))
{
if
(
variable_tsc
)
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
)
||
(
val
==
CPUFREQ_RESUMECHANGE
))
{
if
(
!
(
freq
->
flags
&
CPUFREQ_CONST_LOOPS
))
cpu_data
[
freq
->
cpu
].
loops_per_jiffy
=
cpufreq_scale
(
loops_per_jiffy_ref
,
ref_freq
,
freq
->
new
);
#ifndef CONFIG_SMP
if
(
cpu_khz
)
cpu_khz
=
cpufreq_scale
(
cpu_khz_ref
,
ref_freq
,
freq
->
new
);
if
(
use_tsc
)
{
if
(
variable_tsc
)
{
if
(
!
(
freq
->
flags
&
CPUFREQ_CONST_LOOPS
)
)
{
fast_gettimeoffset_quotient
=
cpufreq_scale
(
fast_gettimeoffset_ref
,
freq
->
new
,
ref_freq
);
set_cyc2ns_scale
(
cpu_khz
/
1000
);
}
...
...
@@ -382,14 +413,17 @@ static struct notifier_block time_cpufreq_notifier_block = {
static
int
__init
cpufreq_tsc
(
void
)
{
/* P4 and above CPU TSC freq doesn't change when CPU frequency changes*/
if
((
boot_cpu_data
.
x86
>=
15
)
&&
(
boot_cpu_data
.
x86_vendor
==
X86_VENDOR_INTEL
))
variable_tsc
=
0
;
return
cpufreq_register_notifier
(
&
time_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
int
ret
;
INIT_WORK
(
&
cpufreq_delayed_get_work
,
handle_cpufreq_delayed_get
,
NULL
);
ret
=
cpufreq_register_notifier
(
&
time_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
if
(
!
ret
)
cpufreq_init
=
1
;
return
ret
;
}
core_initcall
(
cpufreq_tsc
);
#else
/* CONFIG_CPU_FREQ */
static
inline
void
cpufreq_delayed_get
(
void
)
{
return
;
}
#endif
...
...
arch/sparc64/kernel/time.c
View file @
e79b352d
...
...
@@ -1035,7 +1035,8 @@ static int sparc64_cpufreq_notifier(struct notifier_block *nb, unsigned long val
ft
->
clock_tick_ref
=
cpu_data
(
cpu
).
clock_tick
;
}
if
((
val
==
CPUFREQ_PRECHANGE
&&
freq
->
old
<
freq
->
new
)
||
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
))
{
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
)
||
(
val
==
CPUFREQ_RESUMECHANGE
))
{
cpu_data
(
cpu
).
udelay_val
=
cpufreq_scale
(
ft
->
udelay_val_ref
,
ft
->
ref_freq
,
...
...
arch/x86_64/kernel/time.c
View file @
e79b352d
...
...
@@ -532,7 +532,8 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
cpu_khz_ref
=
cpu_khz
;
}
if
((
val
==
CPUFREQ_PRECHANGE
&&
freq
->
old
<
freq
->
new
)
||
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
))
{
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
)
||
(
val
==
CPUFREQ_RESUMECHANGE
))
{
*
lpj
=
cpufreq_scale
(
loops_per_jiffy_ref
,
ref_freq
,
freq
->
new
);
...
...
drivers/cpufreq/cpufreq.c
View file @
e79b352d
...
...
@@ -33,9 +33,10 @@ static struct cpufreq_driver *cpufreq_driver;
static
struct
cpufreq_policy
*
cpufreq_cpu_data
[
NR_CPUS
];
static
spinlock_t
cpufreq_driver_lock
=
SPIN_LOCK_UNLOCKED
;
/* internal prototype */
/* internal prototype
s
*/
static
int
__cpufreq_governor
(
struct
cpufreq_policy
*
policy
,
unsigned
int
event
);
static
void
handle_update
(
void
*
data
);
static
inline
void
adjust_jiffies
(
unsigned
long
val
,
struct
cpufreq_freqs
*
ci
);
/**
* Two notifier lists: the "policy" list is involved in the
...
...
@@ -161,6 +162,7 @@ show_one(cpuinfo_min_freq, cpuinfo.min_freq);
show_one
(
cpuinfo_max_freq
,
cpuinfo
.
max_freq
);
show_one
(
scaling_min_freq
,
min
);
show_one
(
scaling_max_freq
,
max
);
show_one
(
scaling_cur_freq
,
cur
);
/**
* cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
...
...
@@ -188,6 +190,18 @@ static ssize_t store_##file_name \
store_one
(
scaling_min_freq
,
min
);
store_one
(
scaling_max_freq
,
max
);
/**
* show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
*/
static
ssize_t
show_cpuinfo_cur_freq
(
struct
cpufreq_policy
*
policy
,
char
*
buf
)
{
unsigned
int
cur_freq
=
cpufreq_get
(
policy
->
cpu
);
if
(
!
cur_freq
)
return
sprintf
(
buf
,
"<unknown>"
);
return
sprintf
(
buf
,
"%u
\n
"
,
cur_freq
);
}
/**
* show_scaling_governor - show the current policy for the specified CPU
*/
...
...
@@ -268,6 +282,12 @@ struct freq_attr _name = { \
.show = show_##_name, \
}
#define define_one_ro0400(_name) \
struct freq_attr _name = { \
.attr = { .name = __stringify(_name), .mode = 0400 }, \
.show = show_##_name, \
}
#define define_one_rw(_name) \
struct freq_attr _name = { \
.attr = { .name = __stringify(_name), .mode = 0644 }, \
...
...
@@ -275,10 +295,12 @@ struct freq_attr _name = { \
.store = store_##_name, \
}
define_one_ro0400
(
cpuinfo_cur_freq
);
define_one_ro
(
cpuinfo_min_freq
);
define_one_ro
(
cpuinfo_max_freq
);
define_one_ro
(
scaling_available_governors
);
define_one_ro
(
scaling_driver
);
define_one_ro
(
scaling_cur_freq
);
define_one_rw
(
scaling_min_freq
);
define_one_rw
(
scaling_max_freq
);
define_one_rw
(
scaling_governor
);
...
...
@@ -369,6 +391,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
policy
->
cpu
=
cpu
;
init_MUTEX_LOCKED
(
&
policy
->
lock
);
init_completion
(
&
policy
->
kobj_unregister
);
INIT_WORK
(
&
policy
->
update
,
handle_update
,
(
void
*
)(
long
)
cpu
);
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
...
...
@@ -394,6 +417,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
sysfs_create_file
(
&
policy
->
kobj
,
&
((
*
drv_attr
)
->
attr
));
drv_attr
++
;
}
if
(
cpufreq_driver
->
get
)
sysfs_create_file
(
&
policy
->
kobj
,
&
cpuinfo_cur_freq
.
attr
);
if
(
cpufreq_driver
->
target
)
sysfs_create_file
(
&
policy
->
kobj
,
&
scaling_cur_freq
.
attr
);
spin_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
cpufreq_cpu_data
[
cpu
]
=
policy
;
...
...
@@ -474,11 +501,86 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
return
0
;
}
static
void
handle_update
(
void
*
data
)
{
unsigned
int
cpu
=
(
unsigned
int
)(
long
)
data
;
cpufreq_update_policy
(
cpu
);
}
/**
* cpufreq_resume - restore the CPU clock frequency after resume
* cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
* @cpu: cpu number
* @old_freq: CPU frequency the kernel thinks the CPU runs at
* @new_freq: CPU frequency the CPU actually runs at
*
* Restore the CPU clock frequency so that our idea of the current
* frequency reflects the actual hardware.
* We adjust to current frequency first, and need to clean up later. So either call
* to cpufreq_update_policy() or schedule handle_update()).
*/
static
void
cpufreq_out_of_sync
(
unsigned
int
cpu
,
unsigned
int
old_freq
,
unsigned
int
new_freq
)
{
struct
cpufreq_freqs
freqs
;
if
(
cpufreq_driver
->
flags
&
CPUFREQ_PANIC_OUTOFSYNC
)
panic
(
"CPU Frequency is out of sync."
);
printk
(
KERN_WARNING
"Warning: CPU frequency out of sync: cpufreq and timing "
"core thinks of %u, is %u kHz.
\n
"
,
old_freq
,
new_freq
);
freqs
.
cpu
=
cpu
;
freqs
.
old
=
old_freq
;
freqs
.
new
=
new_freq
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
}
/**
* cpufreq_get - get the current CPU frequency (in kHz)
* @cpu: CPU number
*
* Get the CPU current (static) CPU frequency
*/
unsigned
int
cpufreq_get
(
unsigned
int
cpu
)
{
struct
cpufreq_policy
*
policy
=
cpufreq_cpu_get
(
cpu
);
unsigned
int
ret
=
0
;
if
(
!
policy
)
return
0
;
if
(
!
cpufreq_driver
->
get
)
goto
out
;
down
(
&
policy
->
lock
);
ret
=
cpufreq_driver
->
get
(
cpu
);
if
(
ret
&&
policy
->
cur
&&
!
(
cpufreq_driver
->
flags
&
CPUFREQ_CONST_LOOPS
))
{
/* verify no discrepancy between actual and saved value exists */
if
(
unlikely
(
ret
!=
policy
->
cur
))
{
cpufreq_out_of_sync
(
cpu
,
policy
->
cur
,
ret
);
schedule_work
(
&
policy
->
update
);
}
}
up
(
&
policy
->
lock
);
out:
cpufreq_cpu_put
(
policy
);
return
(
ret
);
}
EXPORT_SYMBOL
(
cpufreq_get
);
/**
* cpufreq_resume - restore proper CPU frequency handling after resume
*
* 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
* 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync
* 3.) schedule call cpufreq_update_policy() ASAP as interrupts are restored.
*/
static
int
cpufreq_resume
(
struct
sys_device
*
sysdev
)
{
...
...
@@ -498,25 +600,37 @@ static int cpufreq_resume(struct sys_device * sysdev)
if
(
!
cpu_policy
)
return
-
EINVAL
;
if
(
cpufreq_driver
->
resume
)
ret
=
cpufreq_driver
->
resume
(
cpu_policy
);
if
(
ret
)
{
printk
(
KERN_ERR
"cpufreq: resume failed in ->resume step on CPU %u
\n
"
,
cpu_policy
->
cpu
);
goto
out
;
}
if
(
!
(
cpufreq_driver
->
flags
&
CPUFREQ_CONST_LOOPS
))
{
unsigned
int
cur_freq
=
0
;
if
(
cpufreq_driver
->
setpolicy
)
ret
=
cpufreq_driver
->
setpolicy
(
cpu_policy
);
else
/* CPUFREQ_RELATION_H or CPUFREQ_RELATION_L have the same effect here, as cpu_policy->cur is known
* to be a valid and exact target frequency
*/
ret
=
cpufreq_driver
->
target
(
cpu_policy
,
cpu_policy
->
cur
,
CPUFREQ_RELATION_H
);
if
(
cpufreq_driver
->
get
)
cur_freq
=
cpufreq_driver
->
get
(
cpu_policy
->
cpu
);
if
(
ret
)
printk
(
KERN_ERR
"cpufreq: resume failed in ->setpolicy/target step on CPU %u
\n
"
,
cpu_policy
->
cpu
);
if
(
!
cur_freq
||
!
cpu_policy
->
cur
)
{
printk
(
KERN_ERR
"cpufreq: resume failed to assert current frequency is what timing core thinks it is.
\n
"
);
goto
out
;
}
if
(
unlikely
(
cur_freq
!=
cpu_policy
->
cur
))
{
struct
cpufreq_freqs
freqs
;
if
(
cpufreq_driver
->
flags
&
CPUFREQ_PANIC_RESUME_OUTOFSYNC
)
panic
(
"CPU Frequency is out of sync."
);
printk
(
KERN_WARNING
"Warning: CPU frequency out of sync: cpufreq and timing"
"core thinks of %u, is %u kHz.
\n
"
,
cpu_policy
->
cur
,
cur_freq
);
freqs
.
cpu
=
cpu
;
freqs
.
old
=
cpu_policy
->
cur
;
freqs
.
new
=
cur_freq
;
notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_RESUMECHANGE
,
&
freqs
);
adjust_jiffies
(
CPUFREQ_RESUMECHANGE
,
&
freqs
);
}
}
out:
schedule_work
(
&
cpu_policy
->
update
);
cpufreq_cpu_put
(
cpu_policy
);
return
ret
;
}
...
...
@@ -904,16 +1018,20 @@ static unsigned int l_p_j_ref_freq;
static
inline
void
adjust_jiffies
(
unsigned
long
val
,
struct
cpufreq_freqs
*
ci
)
{
if
(
ci
->
flags
&
CPUFREQ_CONST_LOOPS
)
return
;
if
(
!
l_p_j_ref_freq
)
{
l_p_j_ref
=
loops_per_jiffy
;
l_p_j_ref_freq
=
ci
->
old
;
}
if
((
val
==
CPUFREQ_PRECHANGE
&&
ci
->
old
<
ci
->
new
)
||
(
val
==
CPUFREQ_POSTCHANGE
&&
ci
->
old
>
ci
->
new
))
(
val
==
CPUFREQ_POSTCHANGE
&&
ci
->
old
>
ci
->
new
)
||
(
val
==
CPUFREQ_RESUMECHANGE
))
loops_per_jiffy
=
cpufreq_scale
(
l_p_j_ref
,
l_p_j_ref_freq
,
ci
->
new
);
}
#else
#define adjust_jiffies(x...) do {} while (0)
static
inline
void
adjust_jiffies
(
unsigned
long
val
,
struct
cpufreq_freqs
*
ci
)
{
return
;
}
#endif
...
...
@@ -925,13 +1043,29 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
*/
void
cpufreq_notify_transition
(
struct
cpufreq_freqs
*
freqs
,
unsigned
int
state
)
{
if
(
irqs_disabled
())
return
;
/* Only valid if we're in the resume process where
* everyone knows what CPU frequency we are at */
BUG_ON
(
irqs_disabled
());
freqs
->
flags
=
cpufreq_driver
->
flags
;
down_read
(
&
cpufreq_notifier_rwsem
);
switch
(
state
)
{
case
CPUFREQ_PRECHANGE
:
/* detect if the driver reported a value as "old frequency" which
* is not equal to what the cpufreq core thinks is "old frequency".
*/
if
(
!
(
cpufreq_driver
->
flags
&
CPUFREQ_CONST_LOOPS
))
{
if
((
likely
(
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
))
&&
(
unlikely
(
freqs
->
old
!=
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
)))
{
if
(
cpufreq_driver
->
flags
&
CPUFREQ_PANIC_OUTOFSYNC
)
panic
(
"CPU Frequency is out of sync."
);
printk
(
KERN_WARNING
"Warning: CPU frequency out of sync: "
"cpufreq and timing core thinks of %u, is %u kHz.
\n
"
,
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
,
freqs
->
old
);
freqs
->
old
=
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
;
}
}
notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_PRECHANGE
,
freqs
);
adjust_jiffies
(
CPUFREQ_PRECHANGE
,
freqs
);
break
;
...
...
@@ -970,6 +1104,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
((
!
driver_data
->
setpolicy
)
&&
(
!
driver_data
->
target
)))
return
-
EINVAL
;
if
(
driver_data
->
setpolicy
)
driver_data
->
flags
|=
CPUFREQ_CONST_LOOPS
;
spin_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
if
(
cpufreq_driver
)
{
spin_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
...
...
drivers/cpufreq/cpufreq_userspace.c
View file @
e79b352d
...
...
@@ -145,19 +145,6 @@ int cpufreq_setmax(unsigned int cpu)
EXPORT_SYMBOL_GPL
(
cpufreq_setmax
);
/**
* cpufreq_get - get the current CPU frequency (in kHz)
* @cpu: CPU number
*
* Get the CPU current (static) CPU frequency
*/
unsigned
int
cpufreq_get
(
unsigned
int
cpu
)
{
return
cpu_cur_freq
[
cpu
];
}
EXPORT_SYMBOL
(
cpufreq_get
);
#ifdef CONFIG_CPU_FREQ_24_API
...
...
@@ -542,20 +529,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
return
0
;
}
/* on ARM SA1100 we need to rely on the values of cpufreq_get() - because
* of this, cpu_cur_freq[] needs to be set early.
*/
#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_SA1100)
extern
unsigned
int
sa11x0_getspeed
(
void
);
static
void
cpufreq_sa11x0_compat
(
void
)
{
cpu_cur_freq
[
0
]
=
sa11x0_getspeed
();
}
#else
#define cpufreq_sa11x0_compat() do {} while(0)
#endif
struct
cpufreq_governor
cpufreq_gov_userspace
=
{
.
name
=
"userspace"
,
...
...
@@ -564,21 +537,12 @@ struct cpufreq_governor cpufreq_gov_userspace = {
};
EXPORT_SYMBOL
(
cpufreq_gov_userspace
);
static
int
already_init
=
0
;
int
cpufreq_gov_userspace_init
(
void
)
static
int
__init
cpufreq_gov_userspace_init
(
void
)
{
if
(
!
already_init
)
{
down
(
&
userspace_sem
);
cpufreq_sa11x0_compat
();
cpufreq_sysctl_init
();
cpufreq_register_notifier
(
&
userspace_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
already_init
=
1
;
up
(
&
userspace_sem
);
}
cpufreq_sysctl_init
();
cpufreq_register_notifier
(
&
userspace_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
return
cpufreq_register_governor
(
&
cpufreq_gov_userspace
);
}
EXPORT_SYMBOL
(
cpufreq_gov_userspace_init
);
static
void
__exit
cpufreq_gov_userspace_exit
(
void
)
...
...
drivers/serial/sh-sci.c
View file @
e79b352d
...
...
@@ -758,7 +758,8 @@ static int sci_notifier(struct notifier_block *self, unsigned long phase, void *
struct
cpufreq_freqs
*
freqs
=
p
;
int
i
;
if
(
phase
==
CPUFREQ_POSTCHANGE
)
{
if
((
phase
==
CPUFREQ_POSTCHANGE
)
||
(
phase
==
CPUFREQ_RESUMECHANGE
)){
for
(
i
=
0
;
i
<
SCI_NPORTS
;
i
++
)
{
struct
uart_port
*
port
=
&
sci_ports
[
i
];
...
...
include/linux/cpufreq.h
View file @
e79b352d
...
...
@@ -21,6 +21,7 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#define CPUFREQ_NAME_LEN 16
...
...
@@ -81,6 +82,9 @@ struct cpufreq_policy {
struct
semaphore
lock
;
/* CPU ->setpolicy or ->target may
only be called once a time */
struct
work_struct
update
;
/* if update_policy() needs to be
* called, but you're in IRQ context */
struct
cpufreq_real_policy
user_policy
;
struct
kobject
kobj
;
...
...
@@ -96,11 +100,13 @@ struct cpufreq_policy {
#define CPUFREQ_PRECHANGE (0)
#define CPUFREQ_POSTCHANGE (1)
#define CPUFREQ_RESUMECHANGE (8)
struct
cpufreq_freqs
{
unsigned
int
cpu
;
/* cpu nr */
unsigned
int
old
;
unsigned
int
new
;
u8
flags
;
/* flags of cpufreq_driver, see below. */
};
...
...
@@ -187,6 +193,9 @@ struct cpufreq_driver {
unsigned
int
target_freq
,
unsigned
int
relation
);
/* should be defined, if possible */
unsigned
int
(
*
get
)
(
unsigned
int
cpu
);
/* optional */
int
(
*
exit
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
resume
)
(
struct
cpufreq_policy
*
policy
);
...
...
@@ -195,8 +204,19 @@ struct cpufreq_driver {
/* flags */
#define CPUFREQ_STICKY 0x01
/* the driver isn't removed even if
all ->init() calls failed */
#define CPUFREQ_STICKY 0x01
/* the driver isn't removed even if
* all ->init() calls failed */
#define CPUFREQ_CONST_LOOPS 0x02
/* loops_per_jiffy or other kernel
* "constants" aren't affected by
* frequency transitions */
#define CPUFREQ_PANIC_OUTOFSYNC 0x04
/* panic if cpufreq's opinion of
* current frequency differs from
* actual frequency */
#define CPUFREQ_PANIC_RESUME_OUTOFSYNC 0x08
/* panic if cpufreq's opinion of
* current frequency differs from
* actual frequency on resume
* from sleep. */
int
cpufreq_register_driver
(
struct
cpufreq_driver
*
driver_data
);
int
cpufreq_unregister_driver
(
struct
cpufreq_driver
*
driver_data
);
...
...
@@ -234,6 +254,9 @@ int cpufreq_set_policy(struct cpufreq_policy *policy);
int
cpufreq_get_policy
(
struct
cpufreq_policy
*
policy
,
unsigned
int
cpu
);
int
cpufreq_update_policy
(
unsigned
int
cpu
);
/* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
unsigned
int
cpufreq_get
(
unsigned
int
cpu
);
/* the proc_intf.c needs this */
int
cpufreq_parse_governor
(
char
*
str_governor
,
unsigned
int
*
policy
,
struct
cpufreq_governor
**
governor
);
...
...
@@ -241,13 +264,10 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpu
/*********************************************************************
* CPUFREQ USERSPACE GOVERNOR *
*********************************************************************/
int
cpufreq_gov_userspace_init
(
void
);
#ifdef CONFIG_CPU_FREQ_24_API
int
cpufreq_setmax
(
unsigned
int
cpu
);
int
cpufreq_set
(
unsigned
int
kHz
,
unsigned
int
cpu
);
unsigned
int
cpufreq_get
(
unsigned
int
cpu
);
/* /proc/sys/cpu */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment