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
17d5007f
Commit
17d5007f
authored
Apr 21, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux-dj.bkbits.net/cpufreq
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
4918451f
ad4c196a
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
302 additions
and
57 deletions
+302
-57
arch/i386/kernel/cpu/cpufreq/acpi.c
arch/i386/kernel/cpu/cpufreq/acpi.c
+39
-6
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+232
-25
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+3
-3
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+1
-1
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+16
-15
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+8
-4
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/cpufreq_userspace.c
+3
-3
No files found.
arch/i386/kernel/cpu/cpufreq/acpi.c
View file @
17d5007f
...
@@ -238,6 +238,34 @@ acpi_cpufreq_verify (
...
@@ -238,6 +238,34 @@ acpi_cpufreq_verify (
}
}
static
unsigned
long
acpi_cpufreq_guess_freq
(
struct
cpufreq_acpi_io
*
data
,
unsigned
int
cpu
)
{
if
(
cpu_khz
)
{
/* search the closest match to cpu_khz */
unsigned
int
i
;
unsigned
long
freq
;
unsigned
long
freqn
=
data
->
acpi_data
.
states
[
0
].
core_frequency
*
1000
;
for
(
i
=
0
;
i
<
(
data
->
acpi_data
.
state_count
-
1
);
i
++
)
{
freq
=
freqn
;
freqn
=
data
->
acpi_data
.
states
[
i
+
1
].
core_frequency
*
1000
;
if
((
2
*
cpu_khz
)
>
(
freqn
+
freq
))
{
data
->
acpi_data
.
state
=
i
;
return
(
freq
);
}
}
data
->
acpi_data
.
state
=
data
->
acpi_data
.
state_count
-
1
;
return
(
freqn
);
}
else
/* assume CPU is at P0... */
data
->
acpi_data
.
state
=
0
;
return
data
->
acpi_data
.
states
[
0
].
core_frequency
*
1000
;
}
static
int
static
int
acpi_cpufreq_cpu_init
(
acpi_cpufreq_cpu_init
(
struct
cpufreq_policy
*
policy
)
struct
cpufreq_policy
*
policy
)
...
@@ -290,11 +318,8 @@ acpi_cpufreq_cpu_init (
...
@@ -290,11 +318,8 @@ acpi_cpufreq_cpu_init (
}
}
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
/*
/* The current speed is unknown and not detectable by ACPI... */
* The current speed is unknown and not detectable by ACPI... argh! Assume
policy
->
cur
=
acpi_cpufreq_guess_freq
(
data
,
policy
->
cpu
);
* it's P0, it will be set to this value later during initialization.
*/
policy
->
cur
=
data
->
acpi_data
.
states
[
0
].
core_frequency
*
1000
;
/* table init */
/* table init */
for
(
i
=
0
;
i
<=
data
->
acpi_data
.
state_count
;
i
++
)
for
(
i
=
0
;
i
<=
data
->
acpi_data
.
state_count
;
i
++
)
...
@@ -306,7 +331,7 @@ acpi_cpufreq_cpu_init (
...
@@ -306,7 +331,7 @@ acpi_cpufreq_cpu_init (
data
->
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
data
->
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
}
}
result
=
cpufreq_frequency_table_cpuinfo
(
policy
,
&
data
->
freq_table
[
0
]
);
result
=
cpufreq_frequency_table_cpuinfo
(
policy
,
data
->
freq_table
);
if
(
result
)
{
if
(
result
)
{
goto
err_freqfree
;
goto
err_freqfree
;
}
}
...
@@ -321,6 +346,7 @@ acpi_cpufreq_cpu_init (
...
@@ -321,6 +346,7 @@ acpi_cpufreq_cpu_init (
(
u32
)
data
->
acpi_data
.
states
[
i
].
power
,
(
u32
)
data
->
acpi_data
.
states
[
i
].
power
,
(
u32
)
data
->
acpi_data
.
states
[
i
].
transition_latency
);
(
u32
)
data
->
acpi_data
.
states
[
i
].
transition_latency
);
cpufreq_frequency_table_get_attr
(
data
->
freq_table
,
policy
->
cpu
);
return_VALUE
(
result
);
return_VALUE
(
result
);
err_freqfree:
err_freqfree:
...
@@ -345,6 +371,7 @@ acpi_cpufreq_cpu_exit (
...
@@ -345,6 +371,7 @@ acpi_cpufreq_cpu_exit (
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_cpu_exit"
);
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_cpu_exit"
);
if
(
data
)
{
if
(
data
)
{
cpufreq_frequency_table_put_attr
(
policy
->
cpu
);
acpi_io_data
[
policy
->
cpu
]
=
NULL
;
acpi_io_data
[
policy
->
cpu
]
=
NULL
;
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
policy
->
cpu
);
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
policy
->
cpu
);
kfree
(
data
);
kfree
(
data
);
...
@@ -354,6 +381,11 @@ acpi_cpufreq_cpu_exit (
...
@@ -354,6 +381,11 @@ acpi_cpufreq_cpu_exit (
}
}
static
struct
freq_attr
*
acpi_cpufreq_attr
[]
=
{
&
cpufreq_freq_attr_scaling_available_freqs
,
NULL
,
};
static
struct
cpufreq_driver
acpi_cpufreq_driver
=
{
static
struct
cpufreq_driver
acpi_cpufreq_driver
=
{
.
verify
=
acpi_cpufreq_verify
,
.
verify
=
acpi_cpufreq_verify
,
.
target
=
acpi_cpufreq_target
,
.
target
=
acpi_cpufreq_target
,
...
@@ -361,6 +393,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
...
@@ -361,6 +393,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
.
exit
=
acpi_cpufreq_cpu_exit
,
.
exit
=
acpi_cpufreq_cpu_exit
,
.
name
=
"acpi-cpufreq"
,
.
name
=
"acpi-cpufreq"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
attr
=
acpi_cpufreq_attr
,
};
};
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
View file @
17d5007f
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
#include <linux/config.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/slab.h>
...
@@ -27,6 +28,11 @@
...
@@ -27,6 +28,11 @@
#include <asm/io.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/system.h>
#ifdef CONFIG_ACPI_PROCESSOR
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif
#include "powernow-k7.h"
#include "powernow-k7.h"
#define DEBUG
#define DEBUG
...
@@ -57,6 +63,17 @@ struct pst_s {
...
@@ -57,6 +63,17 @@ struct pst_s {
u8
numpstates
;
u8
numpstates
;
};
};
#ifdef CONFIG_ACPI_PROCESSOR
union
powernow_acpi_control_t
{
struct
{
unsigned
long
fid
:
5
,
vid:
5
,
sgtc:
20
,
res1:
2
;
}
bits
;
unsigned
long
val
;
};
#endif
/* divide by 1000 to get VID. */
/* divide by 1000 to get VID. */
static
int
mobile_vid_table
[
32
]
=
{
static
int
mobile_vid_table
[
32
]
=
{
...
@@ -74,6 +91,12 @@ static int fid_codes[32] = {
...
@@ -74,6 +91,12 @@ static int fid_codes[32] = {
150
,
225
,
160
,
165
,
170
,
180
,
-
1
,
-
1
,
150
,
225
,
160
,
165
,
170
,
180
,
-
1
,
-
1
,
};
};
/* This parameter is used in order to force ACPI instead of legacy method for
* configuration purpose.
*/
static
int
powernow_acpi_force
;
static
struct
cpufreq_frequency_table
*
powernow_table
;
static
struct
cpufreq_frequency_table
*
powernow_table
;
static
unsigned
int
can_scale_bus
;
static
unsigned
int
can_scale_bus
;
...
@@ -85,6 +108,14 @@ static unsigned int fsb;
...
@@ -85,6 +108,14 @@ static unsigned int fsb;
static
unsigned
int
latency
;
static
unsigned
int
latency
;
static
char
have_a0
;
static
char
have_a0
;
static
int
check_fsb
(
unsigned
int
fsbspeed
)
{
int
delta
;
unsigned
int
f
=
fsb
/
1000
;
delta
=
(
fsbspeed
>
f
)
?
fsbspeed
-
f
:
f
-
fsbspeed
;
return
(
delta
<
5
);
}
static
int
check_powernow
(
void
)
static
int
check_powernow
(
void
)
{
{
...
@@ -140,7 +171,8 @@ static int check_powernow(void)
...
@@ -140,7 +171,8 @@ static int check_powernow(void)
static
int
get_ranges
(
unsigned
char
*
pst
)
static
int
get_ranges
(
unsigned
char
*
pst
)
{
{
unsigned
int
j
,
speed
;
unsigned
int
j
;
unsigned
int
speed
;
u8
fid
,
vid
;
u8
fid
,
vid
;
powernow_table
=
kmalloc
((
sizeof
(
struct
cpufreq_frequency_table
)
*
(
number_scales
+
1
)),
GFP_KERNEL
);
powernow_table
=
kmalloc
((
sizeof
(
struct
cpufreq_frequency_table
)
*
(
number_scales
+
1
)),
GFP_KERNEL
);
...
@@ -151,12 +183,12 @@ static int get_ranges (unsigned char *pst)
...
@@ -151,12 +183,12 @@ static int get_ranges (unsigned char *pst)
for
(
j
=
0
;
j
<
number_scales
;
j
++
)
{
for
(
j
=
0
;
j
<
number_scales
;
j
++
)
{
fid
=
*
pst
++
;
fid
=
*
pst
++
;
powernow_table
[
j
].
frequency
=
fsb
*
fid_codes
[
fid
]
*
10
0
;
powernow_table
[
j
].
frequency
=
(
fsb
*
fid_codes
[
fid
])
/
1
0
;
powernow_table
[
j
].
index
=
fid
;
/* lower 8 bits */
powernow_table
[
j
].
index
=
fid
;
/* lower 8 bits */
speed
=
fsb
*
(
fid_codes
[
fid
]
/
10
);
speed
=
powernow_table
[
j
].
frequency
;
if
((
fid_codes
[
fid
]
%
10
)
==
5
)
{
if
((
fid_codes
[
fid
]
%
10
)
==
5
)
{
speed
+=
fsb
/
2
;
#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
if
(
have_a0
==
1
)
if
(
have_a0
==
1
)
powernow_table
[
j
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
powernow_table
[
j
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
...
@@ -164,7 +196,7 @@ static int get_ranges (unsigned char *pst)
...
@@ -164,7 +196,7 @@ static int get_ranges (unsigned char *pst)
}
}
dprintk
(
KERN_INFO
PFX
" FID: 0x%x (%d.%dx [%dMHz])
\t
"
,
fid
,
dprintk
(
KERN_INFO
PFX
" FID: 0x%x (%d.%dx [%dMHz])
\t
"
,
fid
,
fid_codes
[
fid
]
/
10
,
fid_codes
[
fid
]
%
10
,
speed
);
fid_codes
[
fid
]
/
10
,
fid_codes
[
fid
]
%
10
,
speed
/
1000
);
if
(
speed
<
minimum_speed
)
if
(
speed
<
minimum_speed
)
minimum_speed
=
speed
;
minimum_speed
=
speed
;
...
@@ -176,8 +208,6 @@ static int get_ranges (unsigned char *pst)
...
@@ -176,8 +208,6 @@ static int get_ranges (unsigned char *pst)
dprintk
(
"VID: 0x%x (%d.%03dV)
\n
"
,
vid
,
mobile_vid_table
[
vid
]
/
1000
,
dprintk
(
"VID: 0x%x (%d.%03dV)
\n
"
,
vid
,
mobile_vid_table
[
vid
]
/
1000
,
mobile_vid_table
[
vid
]
%
1000
);
mobile_vid_table
[
vid
]
%
1000
);
}
}
dprintk
(
"
\n
"
);
powernow_table
[
number_scales
].
frequency
=
CPUFREQ_TABLE_END
;
powernow_table
[
number_scales
].
frequency
=
CPUFREQ_TABLE_END
;
powernow_table
[
number_scales
].
index
=
0
;
powernow_table
[
number_scales
].
index
=
0
;
...
@@ -234,7 +264,8 @@ static void change_speed (unsigned int index)
...
@@ -234,7 +264,8 @@ static void change_speed (unsigned int index)
rdmsrl
(
MSR_K7_FID_VID_STATUS
,
fidvidstatus
.
val
);
rdmsrl
(
MSR_K7_FID_VID_STATUS
,
fidvidstatus
.
val
);
cfid
=
fidvidstatus
.
bits
.
CFID
;
cfid
=
fidvidstatus
.
bits
.
CFID
;
freqs
.
old
=
fsb
*
fid_codes
[
cfid
]
*
100
;
freqs
.
old
=
fsb
*
fid_codes
[
cfid
]
/
10
;
freqs
.
new
=
powernow_table
[
index
].
frequency
;
freqs
.
new
=
powernow_table
[
index
].
frequency
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
...
@@ -262,19 +293,136 @@ static void change_speed (unsigned int index)
...
@@ -262,19 +293,136 @@ static void change_speed (unsigned int index)
}
}
#ifdef CONFIG_ACPI_PROCESSOR
struct
acpi_processor_performance
*
acpi_processor_perf
;
static
int
powernow_acpi_init
(
void
)
{
int
i
;
int
retval
=
0
;
union
powernow_acpi_control_t
pc
;
if
(
acpi_processor_perf
!=
NULL
&&
powernow_table
!=
NULL
)
{
retval
=
-
EINVAL
;
goto
err0
;
}
acpi_processor_perf
=
kmalloc
(
sizeof
(
struct
acpi_processor_performance
),
GFP_KERNEL
);
if
(
!
acpi_processor_perf
)
{
retval
=
-
ENOMEM
;
goto
err0
;
}
memset
(
acpi_processor_perf
,
0
,
sizeof
(
struct
acpi_processor_performance
));
if
(
acpi_processor_register_performance
(
acpi_processor_perf
,
0
))
{
retval
=
-
EIO
;
goto
err1
;
}
if
(
acpi_processor_perf
->
control_register
.
space_id
!=
ACPI_ADR_SPACE_FIXED_HARDWARE
)
{
retval
=
-
ENODEV
;
goto
err2
;
}
if
(
acpi_processor_perf
->
status_register
.
space_id
!=
ACPI_ADR_SPACE_FIXED_HARDWARE
)
{
retval
=
-
ENODEV
;
goto
err2
;
}
number_scales
=
acpi_processor_perf
->
state_count
;
if
(
number_scales
<
2
)
{
retval
=
-
ENODEV
;
goto
err2
;
}
powernow_table
=
kmalloc
((
number_scales
+
1
)
*
(
sizeof
(
struct
cpufreq_frequency_table
)),
GFP_KERNEL
);
if
(
!
powernow_table
)
{
retval
=
-
ENOMEM
;
goto
err2
;
}
memset
(
powernow_table
,
0
,
((
number_scales
+
1
)
*
sizeof
(
struct
cpufreq_frequency_table
)));
pc
.
val
=
(
unsigned
long
)
acpi_processor_perf
->
states
[
0
].
control
;
for
(
i
=
0
;
i
<
number_scales
;
i
++
)
{
u8
fid
,
vid
;
unsigned
int
speed
;
pc
.
val
=
(
unsigned
long
)
acpi_processor_perf
->
states
[
i
].
control
;
dprintk
(
KERN_INFO
PFX
"acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d
\n
"
,
i
,
(
u32
)
acpi_processor_perf
->
states
[
i
].
core_frequency
,
(
u32
)
acpi_processor_perf
->
states
[
i
].
power
,
(
u32
)
acpi_processor_perf
->
states
[
i
].
transition_latency
,
(
u32
)
acpi_processor_perf
->
states
[
i
].
control
,
pc
.
bits
.
sgtc
);
vid
=
pc
.
bits
.
vid
;
fid
=
pc
.
bits
.
fid
;
powernow_table
[
i
].
frequency
=
fsb
*
fid_codes
[
fid
]
/
10
;
powernow_table
[
i
].
index
=
fid
;
/* lower 8 bits */
powernow_table
[
i
].
index
|=
(
vid
<<
8
);
/* upper 8 bits */
speed
=
powernow_table
[
i
].
frequency
;
if
((
fid_codes
[
fid
]
%
10
)
==
5
)
{
if
(
have_a0
==
1
)
powernow_table
[
i
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
}
dprintk
(
KERN_INFO
PFX
" FID: 0x%x (%d.%dx [%dMHz])
\t
"
,
fid
,
fid_codes
[
fid
]
/
10
,
fid_codes
[
fid
]
%
10
,
speed
/
1000
);
dprintk
(
"VID: 0x%x (%d.%03dV)
\n
"
,
vid
,
mobile_vid_table
[
vid
]
/
1000
,
mobile_vid_table
[
vid
]
%
1000
);
if
(
latency
<
pc
.
bits
.
sgtc
)
latency
=
pc
.
bits
.
sgtc
;
if
(
speed
<
minimum_speed
)
minimum_speed
=
speed
;
if
(
speed
>
maximum_speed
)
maximum_speed
=
speed
;
}
powernow_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
powernow_table
[
i
].
index
=
0
;
return
0
;
err2:
acpi_processor_unregister_performance
(
acpi_processor_perf
,
0
);
err1:
kfree
(
acpi_processor_perf
);
err0:
printk
(
KERN_WARNING
PFX
"ACPI perflib can not be used in this platform
\n
"
);
acpi_processor_perf
=
NULL
;
return
retval
;
}
#else
static
int
powernow_acpi_init
(
void
)
{
printk
(
KERN_INFO
PFX
"no support for ACPI processor found."
" Please recompile your kernel with ACPI processor
\n
"
);
return
-
EINVAL
;
}
#endif
static
int
powernow_decode_bios
(
int
maxfid
,
int
startvid
)
static
int
powernow_decode_bios
(
int
maxfid
,
int
startvid
)
{
{
struct
psb_s
*
psb
;
struct
psb_s
*
psb
;
struct
pst_s
*
pst
;
struct
pst_s
*
pst
;
struct
cpuinfo_x86
*
c
=
cpu_data
;
unsigned
int
i
,
j
;
unsigned
int
i
,
j
;
unsigned
char
*
p
;
unsigned
char
*
p
;
unsigned
int
etuple
;
unsigned
int
etuple
;
unsigned
int
ret
;
unsigned
int
ret
;
etuple
=
cpuid_eax
(
0x80000001
);
etuple
=
cpuid_eax
(
0x80000001
);
etuple
&=
0xf00
;
etuple
|=
(
c
->
x86_model
<<
4
)
|
(
c
->
x86_mask
);
for
(
i
=
0xC0000
;
i
<
0xffff0
;
i
+=
16
)
{
for
(
i
=
0xC0000
;
i
<
0xffff0
;
i
+=
16
)
{
...
@@ -305,7 +453,6 @@ static int powernow_decode_bios (int maxfid, int startvid)
...
@@ -305,7 +453,6 @@ static int powernow_decode_bios (int maxfid, int startvid)
}
}
dprintk
(
KERN_INFO
PFX
"Settling Time: %d microseconds.
\n
"
,
psb
->
settlingtime
);
dprintk
(
KERN_INFO
PFX
"Settling Time: %d microseconds.
\n
"
,
psb
->
settlingtime
);
dprintk
(
KERN_INFO
PFX
"Has %d PST tables. (Only dumping ones relevant to this CPU).
\n
"
,
psb
->
numpst
);
dprintk
(
KERN_INFO
PFX
"Has %d PST tables. (Only dumping ones relevant to this CPU).
\n
"
,
psb
->
numpst
);
latency
*=
100
;
/* SGTC needs to be in units of 10ns */
p
+=
sizeof
(
struct
psb_s
);
p
+=
sizeof
(
struct
psb_s
);
...
@@ -315,7 +462,8 @@ static int powernow_decode_bios (int maxfid, int startvid)
...
@@ -315,7 +462,8 @@ static int powernow_decode_bios (int maxfid, int startvid)
pst
=
(
struct
pst_s
*
)
p
;
pst
=
(
struct
pst_s
*
)
p
;
number_scales
=
pst
->
numpstates
;
number_scales
=
pst
->
numpstates
;
if
((
etuple
==
pst
->
cpuid
)
&&
(
maxfid
==
pst
->
maxfid
)
&&
(
startvid
==
pst
->
startvid
))
if
((
etuple
==
pst
->
cpuid
)
&&
check_fsb
(
pst
->
fsbspeed
)
&&
(
maxfid
==
pst
->
maxfid
)
&&
(
startvid
==
pst
->
startvid
))
{
{
dprintk
(
KERN_INFO
PFX
"PST:%d (@%p)
\n
"
,
i
,
pst
);
dprintk
(
KERN_INFO
PFX
"PST:%d (@%p)
\n
"
,
i
,
pst
);
dprintk
(
KERN_INFO
PFX
" cpuid: 0x%x
\t
"
,
pst
->
cpuid
);
dprintk
(
KERN_INFO
PFX
" cpuid: 0x%x
\t
"
,
pst
->
cpuid
);
...
@@ -323,7 +471,6 @@ static int powernow_decode_bios (int maxfid, int startvid)
...
@@ -323,7 +471,6 @@ static int powernow_decode_bios (int maxfid, int startvid)
dprintk
(
"maxFID: 0x%x
\t
"
,
pst
->
maxfid
);
dprintk
(
"maxFID: 0x%x
\t
"
,
pst
->
maxfid
);
dprintk
(
"startvid: 0x%x
\n
"
,
pst
->
startvid
);
dprintk
(
"startvid: 0x%x
\n
"
,
pst
->
startvid
);
fsb
=
pst
->
fsbspeed
;
ret
=
get_ranges
((
char
*
)
pst
+
sizeof
(
struct
pst_s
));
ret
=
get_ranges
((
char
*
)
pst
+
sizeof
(
struct
pst_s
));
return
ret
;
return
ret
;
...
@@ -335,7 +482,7 @@ static int powernow_decode_bios (int maxfid, int startvid)
...
@@ -335,7 +482,7 @@ static int powernow_decode_bios (int maxfid, int startvid)
}
}
printk
(
KERN_INFO
PFX
"No PST tables match this cpuid (0x%x)
\n
"
,
etuple
);
printk
(
KERN_INFO
PFX
"No PST tables match this cpuid (0x%x)
\n
"
,
etuple
);
printk
(
KERN_INFO
PFX
"This is indicative of a broken BIOS.
\n
"
);
printk
(
KERN_INFO
PFX
"This is indicative of a broken BIOS.
\n
"
);
printk
(
KERN_INFO
PFX
"See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
p
++
;
p
++
;
...
@@ -365,6 +512,33 @@ static int powernow_verify (struct cpufreq_policy *policy)
...
@@ -365,6 +512,33 @@ static int powernow_verify (struct cpufreq_policy *policy)
return
cpufreq_frequency_table_verify
(
policy
,
powernow_table
);
return
cpufreq_frequency_table_verify
(
policy
,
powernow_table
);
}
}
/*
* We use the fact that the bus frequency is somehow
* a multiple of 100000/3 khz, then we compute sgtc according
* to this multiple.
* That way, we match more how AMD thinks all of that work.
* We will then get the same kind of behaviour already tested under
* the "well-known" other OS.
*/
static
int
__init
fixup_sgtc
(
void
)
{
unsigned
int
sgtc
;
unsigned
int
m
;
m
=
fsb
/
3333
;
if
((
m
%
10
)
>=
5
)
m
+=
5
;
m
/=
10
;
sgtc
=
100
*
m
*
latency
;
sgtc
=
sgtc
/
3
;
if
(
sgtc
>
0xfffff
)
{
printk
(
KERN_WARNING
PFX
"SGTC too large %d
\n
"
,
sgtc
);
sgtc
=
0xfffff
;
}
return
sgtc
;
}
static
int
__init
powernow_cpu_init
(
struct
cpufreq_policy
*
policy
)
static
int
__init
powernow_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
{
...
@@ -376,18 +550,45 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
...
@@ -376,18 +550,45 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
rdmsrl
(
MSR_K7_FID_VID_STATUS
,
fidvidstatus
.
val
);
rdmsrl
(
MSR_K7_FID_VID_STATUS
,
fidvidstatus
.
val
);
result
=
powernow_decode_bios
(
fidvidstatus
.
bits
.
MFID
,
fidvidstatus
.
bits
.
SVID
);
/* A K7 with powernow technology is set to max frequency by BIOS */
fsb
=
(
10
*
cpu_khz
)
/
fid_codes
[
fidvidstatus
.
bits
.
CFID
];
if
(
!
fsb
)
{
printk
(
KERN_WARNING
PFX
"can not determine bus frequency
\n
"
);
return
-
EINVAL
;
}
dprintk
(
KERN_INFO
PFX
"FSB: %3d.%03d MHz
\n
"
,
fsb
/
1000
,
fsb
%
1000
);
if
((
dmi_broken
&
BROKEN_CPUFREQ
)
||
powernow_acpi_force
)
{
printk
(
KERN_INFO
PFX
"PSB/PST known to be broken. Trying ACPI instead
\n
"
);
result
=
powernow_acpi_init
();
}
else
{
result
=
powernow_decode_bios
(
fidvidstatus
.
bits
.
MFID
,
fidvidstatus
.
bits
.
SVID
);
if
(
result
)
{
printk
(
KERN_INFO
PFX
"Trying ACPI perflib
\n
"
);
maximum_speed
=
0
;
minimum_speed
=
-
1
;
latency
=
0
;
result
=
powernow_acpi_init
();
if
(
result
)
{
printk
(
KERN_INFO
PFX
"ACPI and legacy methods failed
\n
"
);
printk
(
KERN_INFO
PFX
"See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml
\n
"
);
}
}
else
{
/* SGTC use the bus clock as timer */
latency
=
fixup_sgtc
();
printk
(
KERN_INFO
PFX
"SGTC: %d
\n
"
,
latency
);
}
}
if
(
result
)
if
(
result
)
return
result
;
return
result
;
printk
(
KERN_INFO
PFX
"Minimum speed %d MHz. Maximum speed %d MHz.
\n
"
,
printk
(
KERN_INFO
PFX
"Minimum speed %d MHz. Maximum speed %d MHz.
\n
"
,
minimum_speed
,
maximum_speed
);
minimum_speed
/
1000
,
maximum_speed
/
1000
);
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
/* latency is in 10 ns (look for SGTC above) for each VID
policy
->
cpuinfo
.
transition_latency
=
20
*
latency
/
fsb
;
* and FID transition, so multiply that value with 20 */
policy
->
cpuinfo
.
transition_latency
=
latency
*
20
;
policy
->
cur
=
maximum_speed
;
policy
->
cur
=
maximum_speed
;
...
@@ -418,10 +619,6 @@ static struct cpufreq_driver powernow_driver = {
...
@@ -418,10 +619,6 @@ static struct cpufreq_driver powernow_driver = {
static
int
__init
powernow_init
(
void
)
static
int
__init
powernow_init
(
void
)
{
{
if
(
dmi_broken
&
BROKEN_CPUFREQ
)
{
printk
(
KERN_INFO
PFX
"Disabled at boot time by DMI,
\n
"
);
return
-
ENODEV
;
}
if
(
check_powernow
()
==
0
)
if
(
check_powernow
()
==
0
)
return
-
ENODEV
;
return
-
ENODEV
;
return
cpufreq_register_driver
(
&
powernow_driver
);
return
cpufreq_register_driver
(
&
powernow_driver
);
...
@@ -430,15 +627,25 @@ static int __init powernow_init (void)
...
@@ -430,15 +627,25 @@ static int __init powernow_init (void)
static
void
__exit
powernow_exit
(
void
)
static
void
__exit
powernow_exit
(
void
)
{
{
#ifdef CONFIG_ACPI_PROCESSOR
if
(
acpi_processor_perf
)
{
acpi_processor_unregister_performance
(
acpi_processor_perf
,
0
);
kfree
(
acpi_processor_perf
);
}
#endif
cpufreq_unregister_driver
(
&
powernow_driver
);
cpufreq_unregister_driver
(
&
powernow_driver
);
if
(
powernow_table
)
if
(
powernow_table
)
kfree
(
powernow_table
);
kfree
(
powernow_table
);
}
}
module_param
(
powernow_acpi_force
,
int
,
0444
);
MODULE_PARM_DESC
(
acpi_force
,
"Force ACPI to be used"
);
MODULE_AUTHOR
(
"Dave Jones <davej@codemonkey.org.uk>"
);
MODULE_AUTHOR
(
"Dave Jones <davej@codemonkey.org.uk>"
);
MODULE_DESCRIPTION
(
"Powernow driver for AMD K7 processors."
);
MODULE_DESCRIPTION
(
"Powernow driver for AMD K7 processors."
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
module_init
(
powernow_init
);
late_initcall
(
powernow_init
);
module_exit
(
powernow_exit
);
module_exit
(
powernow_exit
);
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
View file @
17d5007f
...
@@ -32,7 +32,7 @@
...
@@ -32,7 +32,7 @@
#include <asm/io.h>
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/delay.h>
#ifdef CONFIG_
X86_POWERNOW_K8_ACPI
#ifdef CONFIG_
ACPI_PROCESSOR
#include <linux/acpi.h>
#include <linux/acpi.h>
#include <acpi/processor.h>
#include <acpi/processor.h>
#endif
#endif
...
@@ -269,7 +269,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
...
@@ -269,7 +269,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
dprintk
(
KERN_DEBUG
PFX
dprintk
(
KERN_DEBUG
PFX
"ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x
\n
"
,
"ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x
\n
"
,
smp_processor_id
()
;
smp_processor_id
()
,
data
->
currfid
,
data
->
currvid
,
reqvid
,
data
->
rvo
);
data
->
currfid
,
data
->
currvid
,
reqvid
,
data
->
rvo
);
while
(
data
->
currvid
>
reqvid
)
{
while
(
data
->
currvid
>
reqvid
)
{
...
@@ -666,7 +666,7 @@ static int find_psb_table(struct powernow_k8_data *data)
...
@@ -666,7 +666,7 @@ static int find_psb_table(struct powernow_k8_data *data)
return
-
ENODEV
;
return
-
ENODEV
;
}
}
#ifdef CONFIG_
X86_POWERNOW_K8_ACPI
#ifdef CONFIG_
ACPI_PROCESSOR
static
void
powernow_k8_acpi_pst_values
(
struct
powernow_k8_data
*
data
,
unsigned
int
index
)
static
void
powernow_k8_acpi_pst_values
(
struct
powernow_k8_data
*
data
,
unsigned
int
index
)
{
{
if
(
!
data
->
acpi_data
.
state_count
)
if
(
!
data
->
acpi_data
.
state_count
)
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
View file @
17d5007f
...
@@ -29,7 +29,7 @@ struct powernow_k8_data {
...
@@ -29,7 +29,7 @@ struct powernow_k8_data {
* frequency is in kHz */
* frequency is in kHz */
struct
cpufreq_frequency_table
*
powernow_table
;
struct
cpufreq_frequency_table
*
powernow_table
;
#ifdef CONFIG_
X86_POWERNOW_K8_ACPI
#ifdef CONFIG_
ACPI_PROCESSOR
/* the acpi table needs to be kept. it's only available if ACPI was
/* the acpi table needs to be kept. it's only available if ACPI was
* used to determine valid frequency/vid/fid states */
* used to determine valid frequency/vid/fid states */
struct
acpi_processor_performance
acpi_data
;
struct
acpi_processor_performance
acpi_data
;
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
View file @
17d5007f
...
@@ -195,21 +195,6 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
...
@@ -195,21 +195,6 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
struct
cpuinfo_x86
*
cpu
=
&
cpu_data
[
policy
->
cpu
];
struct
cpuinfo_x86
*
cpu
=
&
cpu_data
[
policy
->
cpu
];
struct
cpu_model
*
model
;
struct
cpu_model
*
model
;
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
)
{
printk
(
KERN_INFO
PFX
"found unsupported CPU with Enhanced SpeedStep: "
"send /proc/cpuinfo to "
MAINTAINER
"
\n
"
);
return
-
ENODEV
;
}
for
(
model
=
models
;
model
->
model_name
!=
NULL
;
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
)
break
;
break
;
...
@@ -361,6 +346,7 @@ static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return
...
@@ -361,6 +346,7 @@ static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return
static
int
centrino_cpu_init
(
struct
cpufreq_policy
*
policy
)
static
int
centrino_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
{
struct
cpuinfo_x86
*
cpu
=
&
cpu_data
[
policy
->
cpu
];
unsigned
freq
;
unsigned
freq
;
unsigned
l
,
h
;
unsigned
l
,
h
;
int
ret
;
int
ret
;
...
@@ -368,6 +354,21 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
...
@@ -368,6 +354,21 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
if
(
policy
->
cpu
!=
0
)
if
(
policy
->
cpu
!=
0
)
return
-
ENODEV
;
return
-
ENODEV
;
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
)
{
printk
(
KERN_INFO
PFX
"found unsupported CPU with Enhanced SpeedStep: "
"send /proc/cpuinfo to "
MAINTAINER
"
\n
"
);
return
-
ENODEV
;
}
if
(
centrino_cpu_init_acpi
(
policy
))
{
if
(
centrino_cpu_init_acpi
(
policy
))
{
if
(
centrino_cpu_init_table
(
policy
))
{
if
(
centrino_cpu_init_table
(
policy
))
{
return
-
ENODEV
;
return
-
ENODEV
;
...
...
drivers/cpufreq/cpufreq.c
View file @
17d5007f
...
@@ -360,8 +360,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
...
@@ -360,8 +360,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
return
-
EINVAL
;
return
-
EINVAL
;
policy
=
kmalloc
(
sizeof
(
struct
cpufreq_policy
),
GFP_KERNEL
);
policy
=
kmalloc
(
sizeof
(
struct
cpufreq_policy
),
GFP_KERNEL
);
if
(
!
policy
)
if
(
!
policy
)
{
return
-
ENOMEM
;
ret
=
-
ENOMEM
;
goto
nomem_out
;
}
memset
(
policy
,
0
,
sizeof
(
struct
cpufreq_policy
));
memset
(
policy
,
0
,
sizeof
(
struct
cpufreq_policy
));
policy
->
cpu
=
cpu
;
policy
->
cpu
=
cpu
;
...
@@ -410,7 +412,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
...
@@ -410,7 +412,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
return
0
;
return
0
;
err_out_unregister:
err_out_unregister:
spin_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
spin_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
cpufreq_cpu_data
[
cpu
]
=
NULL
;
cpufreq_cpu_data
[
cpu
]
=
NULL
;
spin_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
spin_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
...
@@ -418,8 +420,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
...
@@ -418,8 +420,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
kobject_unregister
(
&
policy
->
kobj
);
kobject_unregister
(
&
policy
->
kobj
);
wait_for_completion
(
&
policy
->
kobj_unregister
);
wait_for_completion
(
&
policy
->
kobj_unregister
);
err_out:
err_out:
kfree
(
policy
);
kfree
(
policy
);
nomem_out:
module_put
(
cpufreq_driver
->
owner
);
module_put
(
cpufreq_driver
->
owner
);
return
ret
;
return
ret
;
}
}
...
...
drivers/cpufreq/cpufreq_userspace.c
View file @
17d5007f
...
@@ -167,8 +167,8 @@ cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
...
@@ -167,8 +167,8 @@ cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
void
__user
*
buffer
,
size_t
*
lenp
)
void
__user
*
buffer
,
size_t
*
lenp
)
{
{
char
buf
[
16
],
*
p
;
char
buf
[
16
],
*
p
;
int
cpu
=
(
int
)
ctl
->
extra1
;
int
cpu
=
(
long
)
ctl
->
extra1
;
int
len
,
left
=
*
lenp
;
unsigned
int
len
,
left
=
*
lenp
;
if
(
!
left
||
(
filp
->
f_pos
&&
!
write
)
||
!
cpu_online
(
cpu
))
{
if
(
!
left
||
(
filp
->
f_pos
&&
!
write
)
||
!
cpu_online
(
cpu
))
{
*
lenp
=
0
;
*
lenp
=
0
;
...
@@ -205,7 +205,7 @@ cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
...
@@ -205,7 +205,7 @@ cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
void
__user
*
oldval
,
size_t
__user
*
oldlenp
,
void
__user
*
oldval
,
size_t
__user
*
oldlenp
,
void
__user
*
newval
,
size_t
newlen
,
void
**
context
)
void
__user
*
newval
,
size_t
newlen
,
void
**
context
)
{
{
int
cpu
=
(
int
)
table
->
extra1
;
int
cpu
=
(
long
)
table
->
extra1
;
if
(
!
cpu_online
(
cpu
))
if
(
!
cpu_online
(
cpu
))
return
-
EINVAL
;
return
-
EINVAL
;
...
...
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