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
nexedi
linux
Commits
eb2b0751
Commit
eb2b0751
authored
Aug 23, 2004
by
Dave Jones
Browse files
Options
Browse Files
Download
Plain Diff
Merge delerium.codemonkey.org.uk:/mnt/data/src/bk/bk-linus
into delerium.codemonkey.org.uk:/mnt/data/src/bk/cpufreq
parents
4d802161
a0dea52b
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
522 additions
and
326 deletions
+522
-326
arch/i386/kernel/cpu/cpufreq/Kconfig
arch/i386/kernel/cpu/cpufreq/Kconfig
+10
-0
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
+1
-0
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
+63
-40
arch/i386/kernel/cpu/cpufreq/longrun.c
arch/i386/kernel/cpu/cpufreq/longrun.c
+21
-21
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+2
-2
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+40
-32
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+4
-4
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
+166
-84
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+62
-55
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+6
-1
arch/i386/kernel/smpboot.c
arch/i386/kernel/smpboot.c
+1
-1
arch/i386/kernel/timers/timer_tsc.c
arch/i386/kernel/timers/timer_tsc.c
+5
-2
arch/x86_64/kernel/cpufreq/Kconfig
arch/x86_64/kernel/cpufreq/Kconfig
+5
-0
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+86
-83
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/cpufreq_userspace.c
+27
-0
drivers/cpufreq/proc_intf.c
drivers/cpufreq/proc_intf.c
+17
-0
include/asm-i386/acpi.h
include/asm-i386/acpi.h
+5
-0
No files found.
arch/i386/kernel/cpu/cpufreq/Kconfig
View file @
eb2b0751
...
...
@@ -88,6 +88,11 @@ config X86_POWERNOW_K7
If in doubt, say N.
config X86_POWERNOW_K7_ACPI
bool
depends on ((X86_POWERNOW_K7 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K7 = "y" && ACPI_PROCESSOR = "y"))
default y
config X86_POWERNOW_K8
tristate "AMD Opteron/Athlon64 PowerNow!"
depends on CPU_FREQ && EXPERIMENTAL
...
...
@@ -98,6 +103,11 @@ config X86_POWERNOW_K8
If in doubt, say N.
config X86_POWERNOW_K8_ACPI
bool
depends on ((X86_POWERNOW_K8 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K8 = "y" && ACPI_PROCESSOR = "y"))
default y
config X86_GX_SUSPMOD
tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
depends on CPU_FREQ
...
...
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
View file @
eb2b0751
...
...
@@ -297,6 +297,7 @@ static void gx_set_cpuspeed(unsigned int khz)
case
PCI_DEVICE_ID_CYRIX_5520
:
case
PCI_DEVICE_ID_CYRIX_5510
:
suscfg
=
gx_params
->
pci_suscfg
|
SUSMOD
;
break
;
default:
local_irq_restore
(
flags
);
dprintk
(
"fatal: try to set unknown chipset.
\n
"
);
...
...
arch/i386/kernel/cpu/cpufreq/longhaul.c
View file @
eb2b0751
...
...
@@ -5,14 +5,19 @@
* Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by VIA.
*
* VIA have currently
2
different versions of Longhaul.
* VIA have currently
3
different versions of Longhaul.
* Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
* It is present only in Samuel 1, Samuel 2 and Ezra.
* Version 2 (Powersaver) uses the POWERSAVER MSR at 0x110a.
* It is present in Ezra-T, Nehemiah and above.
* In addition to scaling multiplier, it can also scale voltage.
* There is provision for scaling FSB too, but this doesn't work
* too well in practice.
* It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0.
* Version 2 of longhaul is the same as v1, but adds voltage scaling.
* Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C)
* voltage scaling support has currently been disabled in this driver
* until we have code that gets it right.
* Version 3 of longhaul got renamed to Powersaver and redesigned
* to use the POWERSAVER MSR at 0x110a.
* It is present in Ezra-T (C5M), Nehemiah (C5X) and above.
* It's pretty much the same feature wise to longhaul v2, though
* there is provision for scaling FSB too, but this doesn't work
* too well in practice so we don't even try to use this.
*
* BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
*/
...
...
@@ -95,6 +100,27 @@ static int longhaul_get_cpu_mult(void)
}
static
void
do_powersaver
(
union
msr_longhaul
*
longhaul
,
unsigned
int
clock_ratio_index
,
int
version
)
{
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
=
0
;
local_irq_disable
();
wrmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
->
val
);
local_irq_enable
();
__hlt
();
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
->
val
);
longhaul
->
bits
.
EnableSoftBusRatio
=
0
;
longhaul
->
bits
.
RevisionKey
=
version
;
local_irq_disable
();
wrmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
->
val
);
local_irq_enable
();
}
/**
* longhaul_set_cpu_frequency()
* @clock_ratio_index : bitpattern of the new multiplier.
...
...
@@ -126,61 +152,54 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
dprintk
(
KERN_INFO
PFX
"FSB:%d Mult:%d.%dx
\n
"
,
fsb
,
mult
/
10
,
mult
%
10
);
switch
(
longhaul_version
)
{
/*
* Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B])
* Software controlled multipliers only.
*
* *NB* Until we get voltage scaling working v1 & v2 are the same code.
* Longhaul v2 appears in Samuel2 Steppings 1->7 [C5b] and Ezra [C5C]
*/
case
1
:
rdmsrl
(
MSR_VIA_BCR2
,
bcr2
.
val
);
/* Enable software clock multiplier */
bcr2
.
bits
.
ESOFTBF
=
1
;
bcr2
.
bits
.
CLOCKMUL
=
clock_ratio_index
;
local_irq_disable
();
wrmsrl
(
MSR_VIA_BCR2
,
bcr2
.
val
);
local_irq_enable
();
__hlt
();
/* Disable software clock multiplier */
rdmsrl
(
MSR_VIA_BCR2
,
bcr2
.
val
);
bcr2
.
bits
.
ESOFTBF
=
0
;
local_irq_disable
();
wrmsrl
(
MSR_VIA_BCR2
,
bcr2
.
val
);
local_irq_enable
();
break
;
/*
*
Powersaver. (Ezra-T [C5M], Nehemiah [C5N
])
*
Longhaul v3 (aka Powersaver). (Ezra-T [C5M
])
* We can scale voltage with this too, but that's currently
* disabled until we come up with a decent 'match freq to voltage'
* algorithm.
* W
e also need to do the voltage/freq setting in order depending
*
on the direction of scaling (like we do in powernow-k7.c)
*
Ezra-T was alleged to do FSB scaling too, but it never worked in practice.
* W
hen we add voltage scaling, we will also need to do the
*
voltage/freq setting in order depending on the direction
*
of scaling (like we do in powernow-k7.c)
*/
case
2
:
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
;
/* We must program the revision key only with values we
* know about, not blindly copy it from 0:3 */
longhaul
.
bits
.
RevisionKey
=
3
;
/* SoftVID & SoftBSEL */
wrmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
__hlt
();
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
longhaul
.
bits
.
EnableSoftBusRatio
=
0
;
longhaul
.
bits
.
RevisionKey
=
3
;
wrmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
do_powersaver
(
&
longhaul
,
clock_ratio_index
,
3
);
break
;
case
3
:
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
);
/*
* Powersaver. (Nehemiah [C5N])
* As for Ezra-T, we don't do voltage yet.
* This can do FSB scaling too, but it has never been proven
* to work in practice.
*/
case
3
:
do_powersaver
(
&
longhaul
,
clock_ratio_index
,
0xf
);
break
;
}
...
...
@@ -289,6 +308,10 @@ static int __init longhaul_get_ranges(void)
minmult
=
50
;
maxmult
=
longhaul_get_cpu_mult
();
/* Starting with the 1.2GHz parts, theres a 200MHz bus. */
if
((
cpu_khz
/
1000
)
>
1200
)
fsb
=
200
;
else
fsb
=
eblcr_fsb_table_v2
[
longhaul
.
bits
.
MaxMHzFSB
];
break
;
}
...
...
arch/i386/kernel/cpu/cpufreq/longrun.c
View file @
eb2b0751
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
View file @
eb2b0751
...
...
@@ -184,7 +184,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
"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
/* on P-4s, the TSC runs with constant frequency independent w
h
ether
* throttling is active or not. */
p4clockmod_driver
.
flags
|=
CPUFREQ_CONST_LOOPS
;
return
speedstep_get_processor_frequency
(
SPEEDSTEP_PROCESSOR_PM
);
...
...
@@ -195,7 +195,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
return
0
;
}
/* on P-4s, the TSC runs with constant frequency independent wether
/* on P-4s, the TSC runs with constant frequency independent w
h
ether
* throttling is active or not. */
p4clockmod_driver
.
flags
|=
CPUFREQ_CONST_LOOPS
;
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
View file @
eb2b0751
...
...
@@ -6,8 +6,6 @@
* Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by AMD.
*
* BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
*
* Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
* - We cli/sti on stepping A0 CPUs around the FID/VID transition.
* Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
...
...
@@ -29,21 +27,13 @@
#include <asm/io.h>
#include <asm/system.h>
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K7_ACPI
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif
#include "powernow-k7.h"
#define DEBUG
#ifdef DEBUG
#define dprintk(msg...) printk(msg)
#else
#define dprintk(msg...) do { } while(0)
#endif
#define PFX "powernow: "
...
...
@@ -64,7 +54,7 @@ struct pst_s {
u8
numpstates
;
};
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K7_ACPI
union
powernow_acpi_control_t
{
struct
{
unsigned
long
fid
:
5
,
...
...
@@ -97,6 +87,7 @@ static int fid_codes[32] = {
*/
static
int
acpi_force
;
static
int
debug
;
static
struct
cpufreq_frequency_table
*
powernow_table
;
...
...
@@ -109,6 +100,21 @@ static unsigned int fsb;
static
unsigned
int
latency
;
static
char
have_a0
;
static
void
dprintk
(
const
char
*
fmt
,
...)
{
char
s
[
256
];
va_list
args
;
if
(
debug
==
0
)
return
;
va_start
(
args
,
fmt
);
vsprintf
(
s
,
fmt
,
args
);
printk
(
s
);
va_end
(
args
);
}
static
int
check_fsb
(
unsigned
int
fsbspeed
)
{
int
delta
;
...
...
@@ -190,13 +196,13 @@ static int get_ranges (unsigned char *pst)
speed
=
powernow_table
[
j
].
frequency
;
if
((
fid_codes
[
fid
]
%
10
)
==
5
)
{
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K7_ACPI
if
(
have_a0
==
1
)
powernow_table
[
j
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
#endif
}
dprintk
(
KERN_INFO
PFX
" FID: 0x%x (%d.%dx [%dMHz])
\t
"
,
fid
,
dprintk
(
KERN_INFO
PFX
" FID: 0x%x (%d.%dx [%dMHz])
"
,
fid
,
fid_codes
[
fid
]
/
10
,
fid_codes
[
fid
]
%
10
,
speed
/
1000
);
if
(
speed
<
minimum_speed
)
...
...
@@ -294,7 +300,7 @@ static void change_speed (unsigned int index)
}
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K7_ACPI
struct
acpi_processor_performance
*
acpi_processor_perf
;
...
...
@@ -377,7 +383,7 @@ static int powernow_acpi_init(void)
powernow_table
[
i
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
}
dprintk
(
KERN_INFO
PFX
" FID: 0x%x (%d.%dx [%dMHz])
\t
"
,
fid
,
dprintk
(
KERN_INFO
PFX
" FID: 0x%x (%d.%dx [%dMHz])
"
,
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
);
...
...
@@ -467,9 +473,9 @@ static int powernow_decode_bios (int maxfid, int startvid)
(
maxfid
==
pst
->
maxfid
)
&&
(
startvid
==
pst
->
startvid
))
{
dprintk
(
KERN_INFO
PFX
"PST:%d (@%p)
\n
"
,
i
,
pst
);
dprintk
(
KERN_INFO
PFX
" cpuid: 0x%x
\t
"
,
pst
->
cpuid
);
dprintk
(
"fsb: %d
\t
"
,
pst
->
fsbspeed
);
dprintk
(
"maxFID: 0x%x
\t
"
,
pst
->
maxfid
);
dprintk
(
KERN_INFO
PFX
" cpuid: 0x%x
"
,
pst
->
cpuid
);
dprintk
(
"fsb: %d
"
,
pst
->
fsbspeed
);
dprintk
(
"maxFID: 0x%x
"
,
pst
->
maxfid
);
dprintk
(
"startvid: 0x%x
\n
"
,
pst
->
startvid
);
ret
=
get_ranges
((
char
*
)
pst
+
sizeof
(
struct
pst_s
));
...
...
@@ -591,7 +597,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
rdmsrl
(
MSR_K7_FID_VID_STATUS
,
fidvidstatus
.
val
);
/* A K7 with powernow technology is set to max frequency by BIOS */
fsb
=
(
10
*
cpu_khz
)
/
fid_codes
[
fidvidstatus
.
bits
.
C
FID
];
fsb
=
(
10
*
cpu_khz
)
/
fid_codes
[
fidvidstatus
.
bits
.
M
FID
];
if
(
!
fsb
)
{
printk
(
KERN_WARNING
PFX
"can not determine bus frequency
\n
"
);
return
-
EINVAL
;
...
...
@@ -668,7 +674,7 @@ static int __init powernow_init (void)
static
void
__exit
powernow_exit
(
void
)
{
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K7_ACPI
if
(
acpi_processor_perf
)
{
acpi_processor_unregister_performance
(
acpi_processor_perf
,
0
);
kfree
(
acpi_processor_perf
);
...
...
@@ -679,8 +685,10 @@ static void __exit powernow_exit (void)
kfree
(
powernow_table
);
}
module_param
(
debug
,
int
,
0444
);
MODULE_PARM_DESC
(
debug
,
"enable debug output."
);
module_param
(
acpi_force
,
int
,
0444
);
MODULE_PARM_DESC
(
acpi_force
,
"Force ACPI to be used"
);
MODULE_PARM_DESC
(
acpi_force
,
"Force ACPI to be used
.
"
);
MODULE_AUTHOR
(
"Dave Jones <davej@codemonkey.org.uk>"
);
MODULE_DESCRIPTION
(
"Powernow driver for AMD K7 processors."
);
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
View file @
eb2b0751
...
...
@@ -32,7 +32,7 @@
#include <asm/io.h>
#include <asm/delay.h>
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K8_ACPI
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif
...
...
@@ -664,7 +664,7 @@ static int find_psb_table(struct powernow_k8_data *data)
return
-
ENODEV
;
}
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K8_ACPI
static
void
powernow_k8_acpi_pst_values
(
struct
powernow_k8_data
*
data
,
unsigned
int
index
)
{
if
(
!
data
->
acpi_data
.
state_count
)
...
...
@@ -1024,7 +1024,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
return
-
ENODEV
;
}
static
int
__exit
powernowk8_cpu_exit
(
struct
cpufreq_policy
*
pol
)
static
int
__
dev
exit
powernowk8_cpu_exit
(
struct
cpufreq_policy
*
pol
)
{
struct
powernow_k8_data
*
data
=
powernow_data
[
pol
->
cpu
];
...
...
@@ -1076,7 +1076,7 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
.
verify
=
powernowk8_verify
,
.
target
=
powernowk8_target
,
.
init
=
powernowk8_cpu_init
,
.
exit
=
powernowk8_cpu_exit
,
.
exit
=
__devexit_p
(
powernowk8_cpu_exit
)
,
.
get
=
powernowk8_get
,
.
name
=
"powernow-k8"
,
.
owner
=
THIS_MODULE
,
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
View file @
eb2b0751
...
...
@@ -29,7 +29,7 @@ struct powernow_k8_data {
* frequency is in kHz */
struct
cpufreq_frequency_table
*
powernow_table
;
#if
defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#if
def CONFIG_X86_POWERNOW_K8_ACPI
/* 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
;
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
View file @
eb2b0751
...
...
@@ -23,6 +23,11 @@
#include <linux/cpufreq.h>
#include <linux/config.h>
#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif
#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>
...
...
@@ -41,24 +46,24 @@
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
,
enum
{
CPU_BANIAS
,
CPU_DOTHAN_A1
,
CPU_DOTHAN_A2
,
CPU_DOTHAN_B0
,
};
static
const
struct
cpu_id
cpu_id
_dothan_a1
=
{
.
x86_vendor
=
X86_VENDOR_INTEL
,
.
x86
=
6
,
.
x86_model
=
13
,
.
x86_mask
=
1
,
static
const
struct
cpu_id
cpu_id
s
[]
=
{
[
CPU_BANIAS
]
=
{
6
,
9
,
5
}
,
[
CPU_DOTHAN_A1
]
=
{
6
,
13
,
1
}
,
[
CPU_DOTHAN_A2
]
=
{
6
,
13
,
2
}
,
[
CPU_DOTHAN_B0
]
=
{
6
,
13
,
6
}
,
};
#define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0]))
struct
cpu_model
{
...
...
@@ -68,10 +73,11 @@ struct cpu_model
struct
cpufreq_frequency_table
*
op_points
;
/* clock/voltage pairs */
};
static
int
centrino_verify_cpu_id
(
struct
cpuinfo_x86
*
c
,
const
struct
cpu_id
*
x
);
static
int
centrino_verify_cpu_id
(
const
struct
cpuinfo_x86
*
c
,
const
struct
cpu_id
*
x
);
/* Operating points for current CPU */
static
struct
cpu_model
*
centrino_model
;
static
int
centrino_cpu
;
#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
...
...
@@ -199,13 +205,13 @@ static struct cpufreq_frequency_table banias_1700[] =
.max_freq = (max)*1000, \
.op_points = banias_##max, \
}
#define BANIAS(max) _BANIAS(&cpu_id
_banias
, max, #max)
#define BANIAS(max) _BANIAS(&cpu_id
s[CPU_BANIAS]
, max, #max)
/* CPU models, their operating frequency range, and freq/voltage
operating points */
static
struct
cpu_model
models
[]
=
{
_BANIAS
(
&
cpu_id
_banias
,
900
,
" 900"
),
_BANIAS
(
&
cpu_id
s
[
CPU_BANIAS
]
,
900
,
" 900"
),
BANIAS
(
1000
),
BANIAS
(
1100
),
BANIAS
(
1200
),
...
...
@@ -214,6 +220,12 @@ static struct cpu_model models[] =
BANIAS
(
1500
),
BANIAS
(
1600
),
BANIAS
(
1700
),
/* NULL model_name is a wildcard */
{
&
cpu_ids
[
CPU_DOTHAN_A1
],
NULL
,
0
,
NULL
},
{
&
cpu_ids
[
CPU_DOTHAN_A2
],
NULL
,
0
,
NULL
},
{
&
cpu_ids
[
CPU_DOTHAN_B0
],
NULL
,
0
,
NULL
},
{
NULL
,
}
};
#undef _BANIAS
...
...
@@ -224,17 +236,28 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
struct
cpuinfo_x86
*
cpu
=
&
cpu_data
[
policy
->
cpu
];
struct
cpu_model
*
model
;
for
(
model
=
models
;
model
->
model_name
!=
NULL
;
model
++
)
if
((
strcmp
(
cpu
->
x86_model_id
,
model
->
model_name
)
==
0
)
&&
(
!
centrino_verify_cpu_id
(
cpu
,
model
->
cpu_id
)))
for
(
model
=
models
;
model
->
cpu_id
!=
NULL
;
model
++
)
if
(
centrino_verify_cpu_id
(
cpu
,
model
->
cpu_id
)
&&
(
model
->
model_name
==
NULL
||
strcmp
(
cpu
->
x86_model_id
,
model
->
model_name
)
==
0
))
break
;
if
(
model
->
model_name
==
NULL
)
{
if
(
model
->
cpu_id
==
NULL
)
{
/* No match at all */
printk
(
KERN_INFO
PFX
"no support for CPU model
\"
%s
\"
: "
"send /proc/cpuinfo to "
MAINTAINER
"
\n
"
,
cpu
->
x86_model_id
);
return
-
ENOENT
;
}
if
(
model
->
op_points
==
NULL
)
{
/* Matched a non-match */
printk
(
KERN_INFO
PFX
"no table support for CPU model
\"
%s
\"
:
\n
"
,
cpu
->
x86_model_id
);
printk
(
KERN_INFO
PFX
"try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled
\n
"
);
return
-
ENOENT
;
}
centrino_model
=
model
;
printk
(
KERN_INFO
PFX
"found
\"
%s
\"
: max frequency: %dkHz
\n
"
,
...
...
@@ -247,31 +270,54 @@ 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
)
static
int
centrino_verify_cpu_id
(
const
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
1
;
return
0
;
return
-
ENODEV
;
}
/*
Extract clock in kHz from PERF_CTL value
*/
/*
To be called only after centrino_model is initialized
*/
static
unsigned
extract_clock
(
unsigned
msr
)
{
int
i
;
/*
* Extract clock in kHz from PERF_CTL value
* for centrino, as some DSDTs are buggy.
* Ideally, this can be done using the acpi_data structure.
*/
if
(
centrino_cpu
)
{
msr
=
(
msr
>>
8
)
&
0xff
;
return
msr
*
100000
;
}
if
((
!
centrino_model
)
||
(
!
centrino_model
->
op_points
))
return
0
;
msr
&=
0xffff
;
for
(
i
=
0
;
centrino_model
->
op_points
[
i
].
frequency
!=
CPUFREQ_TABLE_END
;
i
++
)
{
if
(
msr
==
centrino_model
->
op_points
[
i
].
index
)
return
centrino_model
->
op_points
[
i
].
frequency
;
}
return
0
;
}
/* Return the current CPU frequency in kHz */
static
unsigned
int
get_cur_freq
(
unsigned
int
cpu
)
{
unsigned
l
,
h
;
if
(
cpu
)
cpumask_t
saved_mask
;
saved_mask
=
current
->
cpus_allowed
;
set_cpus_allowed
(
current
,
cpumask_of_cpu
(
cpu
));
if
(
smp_processor_id
()
!=
cpu
)
return
0
;
rdmsr
(
MSR_IA32_PERF_STATUS
,
l
,
h
);
set_cpus_allowed
(
current
,
saved_mask
);
return
extract_clock
(
l
);
}
...
...
@@ -280,11 +326,6 @@ static unsigned int get_cur_freq(unsigned int cpu)
static
struct
acpi_processor_performance
p
;
#include <linux/acpi.h>
#include <acpi/processor.h>
#define ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP 0x1
/*
* centrino_cpu_init_acpi - register with ACPI P-States library
*
...
...
@@ -305,12 +346,12 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
arg0
.
buffer
.
pointer
=
(
u8
*
)
arg0_buf
;
arg0_buf
[
0
]
=
ACPI_PDC_REVISION_ID
;
arg0_buf
[
1
]
=
1
;
arg0_buf
[
2
]
=
ACPI_PDC_
CAPABILITY_ENHANCED_SPEEDSTEP
;
arg0_buf
[
2
]
=
ACPI_PDC_
EST_CAPABILITY_SMP
|
ACPI_PDC_EST_CAPABILITY_MSR
;
p
.
pdc
=
&
arg_list
;
/* register with ACPI core */
if
(
acpi_processor_register_performance
(
&
p
,
0
))
if
(
acpi_processor_register_performance
(
&
p
,
policy
->
cpu
))
return
-
EIO
;
/* verify the acpi_data */
...
...
@@ -340,11 +381,10 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
goto
err_unreg
;
}
if
(
extract_clock
(
p
.
states
[
i
].
control
)
!=
(
p
.
states
[
i
].
core_frequency
*
1000
))
{
printk
(
KERN_DEBUG
"Invalid encoded frequency
\n
"
);
result
=
-
EINVAL
;
goto
err_unreg
;
if
(
p
.
states
[
i
].
core_frequency
>
p
.
states
[
0
].
core_frequency
)
{
printk
(
KERN_DEBUG
"P%u has larger frequency than P0, skipping
\n
"
,
i
);
p
.
states
[
i
].
core_frequency
=
0
;
continue
;
}
}
...
...
@@ -364,22 +404,36 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
goto
err_kfree
;
}
cur_freq
=
get_cur_freq
(
0
);
for
(
i
=
0
;
i
<
p
.
state_count
;
i
++
)
{
centrino_model
->
op_points
[
i
].
index
=
p
.
states
[
i
].
control
;
centrino_model
->
op_points
[
i
].
frequency
=
p
.
states
[
i
].
core_frequency
*
1000
;
}
centrino_model
->
op_points
[
p
.
state_count
].
frequency
=
CPUFREQ_TABLE_END
;
cur_freq
=
get_cur_freq
(
policy
->
cpu
);
for
(
i
=
0
;
i
<
p
.
state_count
;
i
++
)
{
if
(
extract_clock
(
centrino_model
->
op_points
[
i
].
index
)
!=
(
centrino_model
->
op_points
[
i
].
frequency
))
{
printk
(
KERN_DEBUG
"Invalid encoded frequency
\n
"
);
result
=
-
EINVAL
;
goto
err_kfree_all
;
}
if
(
cur_freq
==
centrino_model
->
op_points
[
i
].
frequency
)
p
.
state
=
i
;
if
(
!
p
.
states
[
i
].
core_frequency
)
centrino_model
->
op_points
[
i
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
}
centrino_model
->
op_points
[
p
.
state_count
].
frequency
=
CPUFREQ_TABLE_END
;
return
0
;
err_kfree_all:
kfree
(
centrino_model
->
op_points
);
err_kfree:
kfree
(
centrino_model
);
err_unreg:
acpi_processor_unregister_performance
(
&
p
,
0
);
acpi_processor_unregister_performance
(
&
p
,
policy
->
cpu
);
return
(
result
);
}
#else
...
...
@@ -392,21 +446,30 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
unsigned
freq
;
unsigned
l
,
h
;
int
ret
;
int
i
;
if
(
policy
->
cpu
!=
0
)
/* Only Intel makes Enhanced Speedstep-capable CPUs */
if
(
cpu
->
x86_vendor
!=
X86_VENDOR_INTEL
||
!
cpu_has
(
cpu
,
X86_FEATURE_EST
))
return
-
ENODEV
;
if
(
!
cpu_has
(
cpu
,
X86_FEATURE_EST
))
for
(
i
=
0
;
i
<
N_IDS
;
i
++
)
if
(
centrino_verify_cpu_id
(
cpu
,
&
cpu_ids
[
i
]))
break
;
if
(
i
!=
N_IDS
)
centrino_cpu
=
1
;
if
(
centrino_cpu_init_acpi
(
policy
))
{
if
(
policy
->
cpu
!=
0
)
return
-
ENODEV
;
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
"
);
if
(
!
centrino_cpu
)
{
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_table
(
policy
))
{
return
-
ENODEV
;
}
...
...
@@ -428,7 +491,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
}
}
freq
=
get_cur_freq
(
0
);
freq
=
get_cur_freq
(
policy
->
cpu
);
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
transition_latency
=
10000
;
/* 10uS transition latency */
...
...
@@ -455,7 +518,7 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy)
#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
if
(
!
centrino_model
->
model_name
)
{
acpi_processor_unregister_performance
(
&
p
,
0
);
acpi_processor_unregister_performance
(
&
p
,
policy
->
cpu
);
kfree
(
centrino_model
->
op_points
);
kfree
(
centrino_model
);
}
...
...
@@ -493,19 +556,35 @@ static int centrino_target (struct cpufreq_policy *policy,
unsigned
int
newstate
=
0
;
unsigned
int
msr
,
oldmsr
,
h
;
struct
cpufreq_freqs
freqs
;
cpumask_t
saved_mask
;
int
retval
;
if
(
centrino_model
==
NULL
)
return
-
ENODEV
;
/*
* Support for SMP systems.
* Make sure we are running on the CPU that wants to change frequency
*/
saved_mask
=
current
->
cpus_allowed
;
set_cpus_allowed
(
current
,
cpumask_of_cpu
(
policy
->
cpu
));
if
(
smp_processor_id
()
!=
policy
->
cpu
)
{
return
(
-
EAGAIN
);
}
if
(
cpufreq_frequency_table_target
(
policy
,
centrino_model
->
op_points
,
target_freq
,
relation
,
&
newstate
))
return
-
EINVAL
;
relation
,
&
newstate
))
{
retval
=
-
EINVAL
;
goto
migrate_end
;
}
msr
=
centrino_model
->
op_points
[
newstate
].
index
;
rdmsr
(
MSR_IA32_PERF_CTL
,
oldmsr
,
h
);
if
(
msr
==
(
oldmsr
&
0xffff
))
return
0
;
if
(
msr
==
(
oldmsr
&
0xffff
))
{
retval
=
0
;
goto
migrate_end
;
}
/* Hm, old frequency can either be the last value we put in
PERF_CTL, or whatever it is now. The trouble is that TM2
...
...
@@ -519,7 +598,7 @@ static int centrino_target (struct cpufreq_policy *policy,
TODO: work out how the TCC interrupts work, and try to
catch the CPU changing things under us.
*/
freqs
.
cpu
=
0
;
freqs
.
cpu
=
policy
->
cpu
;
freqs
.
old
=
extract_clock
(
oldmsr
);
freqs
.
new
=
extract_clock
(
msr
);
...
...
@@ -538,7 +617,10 @@ static int centrino_target (struct cpufreq_policy *policy,
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
return
0
;
retval
=
0
;
migrate_end:
set_cpus_allowed
(
current
,
saved_mask
);
return
(
retval
);
}
static
struct
freq_attr
*
centrino_attr
[]
=
{
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
View file @
eb2b0751
...
...
@@ -82,8 +82,7 @@ static void speedstep_set_state (unsigned int state)
/* get PMBASE */
pci_read_config_dword
(
speedstep_chipset_dev
,
0x40
,
&
pmbase
);
if
(
!
(
pmbase
&
0x01
))
{
if
(
!
(
pmbase
&
0x01
))
{
printk
(
KERN_ERR
"cpufreq: could not find speedstep register
\n
"
);
return
;
}
...
...
@@ -151,13 +150,11 @@ static int speedstep_activate (void)
if
(
!
speedstep_chipset_dev
)
return
-
EINVAL
;
pci_read_config_word
(
speedstep_chipset_dev
,
0x00A0
,
&
value
);
pci_read_config_word
(
speedstep_chipset_dev
,
0x00A0
,
&
value
);
if
(
!
(
value
&
0x08
))
{
value
|=
0x08
;
dprintk
(
KERN_DEBUG
"cpufreq: activating SpeedStep (TM) registers
\n
"
);
pci_write_config_word
(
speedstep_chipset_dev
,
0x00A0
,
value
);
pci_write_config_word
(
speedstep_chipset_dev
,
0x00A0
,
value
);
}
return
0
;
...
...
@@ -226,6 +223,23 @@ static unsigned int speedstep_detect_chipset (void)
return
0
;
}
static
unsigned
int
speedstep_get
(
unsigned
int
cpu
)
{
unsigned
int
speed
;
cpumask_t
cpus_allowed
,
affected_cpu_map
;
/* only run on CPU to be set, or on its sibling */
cpus_allowed
=
current
->
cpus_allowed
;
#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
);
speed
=
speedstep_get_processor_frequency
(
speedstep_processor
);
set_cpus_allowed
(
current
,
cpus_allowed
);
return
speed
;
}
/**
* speedstep_target - set a new CPUFreq policy
...
...
@@ -247,14 +261,14 @@ static int speedstep_target (struct cpufreq_policy *policy,
if
(
cpufreq_frequency_table_target
(
policy
,
&
speedstep_freqs
[
0
],
target_freq
,
relation
,
&
newstate
))
return
-
EINVAL
;
freqs
.
old
=
speedstep_get
(
policy
->
cpu
);
freqs
.
new
=
speedstep_freqs
[
newstate
].
frequency
;
freqs
.
cpu
=
policy
->
cpu
;
/* no transition necessary */
if
(
freqs
.
old
==
freqs
.
new
)
return
0
;
freqs
.
old
=
speedstep_get_processor_frequency
(
speedstep_processor
);
freqs
.
new
=
speedstep_freqs
[
newstate
].
frequency
;
freqs
.
cpu
=
policy
->
cpu
;
cpus_allowed
=
current
->
cpus_allowed
;
/* only run on CPU to be set, or on its sibling */
...
...
@@ -324,14 +338,12 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
&
speedstep_freqs
[
SPEEDSTEP_LOW
].
frequency
,
&
speedstep_freqs
[
SPEEDSTEP_HIGH
].
frequency
,
&
speedstep_set_state
);
if
(
result
)
{
set_cpus_allowed
(
current
,
cpus_allowed
);
if
(
result
)
return
result
;
}
/* get current speed setting */
speed
=
speedstep_get_processor_frequency
(
speedstep_processor
);
set_cpus_allowed
(
current
,
cpus_allowed
);
speed
=
speedstep_get
(
policy
->
cpu
);
if
(
!
speed
)
return
-
EIO
;
...
...
@@ -360,11 +372,6 @@ 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
,
NULL
,
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
View file @
eb2b0751
...
...
@@ -115,6 +115,11 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
:
"=a"
(
result
),
"=b"
(
high_mhz
),
"=c"
(
low_mhz
),
"=d"
(
state
),
"=D"
(
edi
)
:
"a"
(
command
),
"b"
(
function
),
"c"
(
state
),
"d"
(
smi_port
),
"S"
(
0
)
);
/* abort if results are obviously incorrect... */
if
((
high_mhz
+
low_mhz
)
<
600
)
return
-
EINVAL
;
*
high
=
high_mhz
*
1000
;
*
low
=
low_mhz
*
1000
;
...
...
@@ -180,7 +185,7 @@ static void speedstep_set_state (unsigned int state)
local_irq_restore
(
flags
);
if
(
new_state
==
state
)
{
dprintk
(
KERN_INFO
"cpufreq: change to %u MHz succeeded after %u tries with result %u
\n
"
,
(
freqs
.
new
/
1000
),
retry
,
result
);
dprintk
(
KERN_INFO
"cpufreq: change to %u MHz succeeded after %u tries with result %u
\n
"
,
(
speedstep_freqs
[
new_state
].
frequency
/
1000
),
retry
,
result
);
}
else
{
printk
(
KERN_ERR
"cpufreq: change failed with new_state %u and result %u
\n
"
,
new_state
,
result
);
}
...
...
arch/i386/kernel/smpboot.c
View file @
eb2b0751
...
...
@@ -17,7 +17,7 @@
* Fixes
* Felix Koop : NR_CPUS used properly
* Jose Renau : Handle single CPU case.
* Alan Cox : By repeated request 8) - Total BogoMIP report.
* Alan Cox : By repeated request 8) - Total BogoMIP
S
report.
* Greg Wright : Fix for kernel stacks panic.
* Erich Boleyn : MP v1.4 and additional changes.
* Matthias Sattler : Changes for 2.1 kernel map.
...
...
arch/i386/kernel/timers/timer_tsc.c
View file @
eb2b0751
...
...
@@ -265,6 +265,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
{
struct
cpufreq_freqs
*
freq
=
data
;
if
(
val
!=
CPUFREQ_RESUMECHANGE
)
write_seqlock_irq
(
&
xtime_lock
);
if
(
!
ref_freq
)
{
ref_freq
=
freq
->
old
;
...
...
@@ -291,6 +292,8 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
}
#endif
}
if
(
val
!=
CPUFREQ_RESUMECHANGE
)
write_sequnlock_irq
(
&
xtime_lock
);
return
0
;
...
...
arch/x86_64/kernel/cpufreq/Kconfig
View file @
eb2b0751
...
...
@@ -41,4 +41,9 @@ config X86_POWERNOW_K8
If in doubt, say N.
config X86_POWERNOW_K8_ACPI
bool
depends on ((X86_POWERNOW_K8 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K8 = "y" && ACPI_PROCESSOR = "y"))
default y
endmenu
drivers/cpufreq/cpufreq.c
View file @
eb2b0751
...
...
@@ -99,6 +99,88 @@ static void cpufreq_cpu_put(struct cpufreq_policy *data)
module_put
(
cpufreq_driver
->
owner
);
}
/*********************************************************************
* EXTERNALLY AFFECTING FREQUENCY CHANGES *
*********************************************************************/
/**
* adjust_jiffies - adjust the system "loops_per_jiffy"
*
* This function alters the system "loops_per_jiffy" for the clock
* speed change. Note that loops_per_jiffy cannot be updated on SMP
* systems as each CPU might be scaled differently. So, use the arch
* per-CPU loops_per_jiffy value wherever possible.
*/
#ifndef CONFIG_SMP
static
unsigned
long
l_p_j_ref
;
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_RESUMECHANGE
))
loops_per_jiffy
=
cpufreq_scale
(
l_p_j_ref
,
l_p_j_ref_freq
,
ci
->
new
);
}
#else
static
inline
void
adjust_jiffies
(
unsigned
long
val
,
struct
cpufreq_freqs
*
ci
)
{
return
;
}
#endif
/**
* cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
*
* This function calls the transition notifiers and the "adjust_jiffies" function. It is called
* twice on all CPU frequency changes that have external effects.
*/
void
cpufreq_notify_transition
(
struct
cpufreq_freqs
*
freqs
,
unsigned
int
state
)
{
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
]))
&&
(
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 is %u, "
"cpufreq assumed %u kHz.
\n
"
,
freqs
->
old
,
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
);
freqs
->
old
=
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
;
}
}
notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_PRECHANGE
,
freqs
);
adjust_jiffies
(
CPUFREQ_PRECHANGE
,
freqs
);
break
;
case
CPUFREQ_POSTCHANGE
:
adjust_jiffies
(
CPUFREQ_POSTCHANGE
,
freqs
);
notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_POSTCHANGE
,
freqs
);
if
(
likely
(
cpufreq_cpu_data
[
freqs
->
cpu
]))
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
=
freqs
->
new
;
break
;
}
up_read
(
&
cpufreq_notifier_rwsem
);
}
EXPORT_SYMBOL_GPL
(
cpufreq_notify_transition
);
/*********************************************************************
* SYSFS INTERFACE *
*********************************************************************/
...
...
@@ -617,8 +699,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
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
"
"c
ore thinks of %u, is %u kHz.
\n
"
,
cpu_policy
->
cur
,
cur_freq
);
printk
(
KERN_WARNING
"Warning: CPU frequency
is %u,
"
"c
pufreq assumed %u kHz.
\n
"
,
cur_freq
,
cpu_policy
->
cur
);
freqs
.
cpu
=
cpu
;
freqs
.
old
=
cpu_policy
->
cur
;
...
...
@@ -626,6 +708,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_RESUMECHANGE
,
&
freqs
);
adjust_jiffies
(
CPUFREQ_RESUMECHANGE
,
&
freqs
);
cpu_policy
->
cur
=
cur_freq
;
}
}
...
...
@@ -1005,87 +1089,6 @@ int cpufreq_update_policy(unsigned int cpu)
EXPORT_SYMBOL
(
cpufreq_update_policy
);
/*********************************************************************
* EXTERNALLY AFFECTING FREQUENCY CHANGES *
*********************************************************************/
/**
* adjust_jiffies - adjust the system "loops_per_jiffy"
*
* This function alters the system "loops_per_jiffy" for the clock
* speed change. Note that loops_per_jiffy cannot be updated on SMP
* systems as each CPU might be scaled differently. So, use the arch
* per-CPU loops_per_jiffy value wherever possible.
*/
#ifndef CONFIG_SMP
static
unsigned
long
l_p_j_ref
;
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_RESUMECHANGE
))
loops_per_jiffy
=
cpufreq_scale
(
l_p_j_ref
,
l_p_j_ref_freq
,
ci
->
new
);
}
#else
static
inline
void
adjust_jiffies
(
unsigned
long
val
,
struct
cpufreq_freqs
*
ci
)
{
return
;
}
#endif
/**
* cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
*
* This function calls the transition notifiers and the "adjust_jiffies" function. It is called
* twice on all CPU frequency changes that have external effects.
*/
void
cpufreq_notify_transition
(
struct
cpufreq_freqs
*
freqs
,
unsigned
int
state
)
{
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
;
case
CPUFREQ_POSTCHANGE
:
adjust_jiffies
(
CPUFREQ_POSTCHANGE
,
freqs
);
notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_POSTCHANGE
,
freqs
);
cpufreq_cpu_data
[
freqs
->
cpu
]
->
cur
=
freqs
->
new
;
break
;
}
up_read
(
&
cpufreq_notifier_rwsem
);
}
EXPORT_SYMBOL_GPL
(
cpufreq_notify_transition
);
/*********************************************************************
* REGISTER / UNREGISTER CPUFREQ DRIVER *
*********************************************************************/
...
...
drivers/cpufreq/cpufreq_userspace.c
View file @
eb2b0751
...
...
@@ -82,6 +82,13 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
{
struct
cpufreq_freqs
*
freq
=
data
;
/* Don't update cur_freq if CPU is managed and we're
* waking up: else we won't remember what frequency
* we need to set the CPU to.
*/
if
(
cpu_is_managed
[
freq
->
cpu
]
&&
(
val
==
CPUFREQ_RESUMECHANGE
))
return
0
;
cpu_cur_freq
[
freq
->
cpu
]
=
freq
->
new
;
return
0
;
...
...
@@ -147,6 +154,9 @@ EXPORT_SYMBOL_GPL(cpufreq_setmax);
#ifdef CONFIG_CPU_FREQ_24_API
#warning The /proc/sys/cpu/ and sysctl interface to cpufreq will be removed from the 2.6. kernel series soon after 2005-01-01
static
unsigned
int
warning_print
=
0
;
/*********************** cpufreq_sysctl interface ********************/
static
int
...
...
@@ -162,6 +172,13 @@ cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
return
0
;
}
if
(
!
warning_print
)
{
warning_print
++
;
printk
(
KERN_INFO
"Access to /proc/sys/cpu/ is deprecated and "
"will be removed from (new) 2.6. kernels soon "
"after 2005-01-01
\n
"
);
}
if
(
write
)
{
unsigned
int
freq
;
...
...
@@ -197,6 +214,13 @@ cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
if
(
!
cpu_online
(
cpu
))
return
-
EINVAL
;
if
(
!
warning_print
)
{
warning_print
++
;
printk
(
KERN_INFO
"Access to /proc/sys/cpu/ is deprecated and "
"will be removed from (new) 2.6. kernels soon "
"after 2005-01-01
\n
"
);
}
if
(
oldval
&&
oldlenp
)
{
size_t
oldlen
;
...
...
@@ -522,6 +546,9 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
else
if
(
policy
->
min
>
cpu_cur_freq
[
cpu
])
__cpufreq_driver_target
(
&
current_policy
[
cpu
],
policy
->
min
,
CPUFREQ_RELATION_L
);
else
__cpufreq_driver_target
(
&
current_policy
[
cpu
],
cpu_cur_freq
[
cpu
],
CPUFREQ_RELATION_L
);
memcpy
(
&
current_policy
[
cpu
],
policy
,
sizeof
(
struct
cpufreq_policy
));
up
(
&
userspace_sem
);
break
;
...
...
drivers/cpufreq/proc_intf.c
View file @
eb2b0751
...
...
@@ -12,9 +12,12 @@
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#warning This module will be removed from the 2.6. kernel series soon after 2005-01-01
#define CPUFREQ_ALL_CPUS ((NR_CPUS))
static
unsigned
int
warning_print
=
0
;
/**
* cpufreq_parse_policy - parse a policy string
* @input_string: the string to parse.
...
...
@@ -110,6 +113,13 @@ static int cpufreq_proc_read (
if
(
off
!=
0
)
goto
end
;
if
(
!
warning_print
)
{
warning_print
++
;
printk
(
KERN_INFO
"Access to /proc/cpufreq is deprecated and "
"will be removed from (new) 2.6. kernels soon "
"after 2005-01-01
\n
"
);
}
p
+=
sprintf
(
p
,
" minimum CPU frequency - maximum CPU frequency - policy
\n
"
);
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
!
cpu_online
(
i
))
...
...
@@ -180,6 +190,13 @@ static int cpufreq_proc_write (
if
(
copy_from_user
(
proc_string
,
buffer
,
count
))
return
-
EFAULT
;
if
(
!
warning_print
)
{
warning_print
++
;
printk
(
KERN_INFO
"Access to /proc/cpufreq is deprecated and "
"will be removed from (new) 2.6. kernels soon "
"after 2005-01-01
\n
"
);
}
proc_string
[
count
]
=
'\0'
;
result
=
cpufreq_parse_policy
(
proc_string
,
&
policy
);
...
...
include/asm-i386/acpi.h
View file @
eb2b0751
...
...
@@ -101,6 +101,11 @@ __acpi_release_global_lock (unsigned int *lock)
:"=r"(n_hi), "=r"(n_lo) \
:"0"(n_hi), "1"(n_lo))
/*
* Refer Intel ACPI _PDC support document for bit definitions
*/
#define ACPI_PDC_EST_CAPABILITY_SMP 0xa
#define ACPI_PDC_EST_CAPABILITY_MSR 0x1
/*
* Refer Intel ACPI _PDC support document for bit definitions
...
...
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