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
2342d6cb
Commit
2342d6cb
authored
Jul 09, 2003
by
Dave Jones
Browse files
Options
Browse Files
Download
Plain Diff
Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/bk-linus
into tetrachloride.(none):/mnt/raid/src/kernel/2.5/cpufreq
parents
a1bafab5
92175044
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
109 additions
and
104 deletions
+109
-104
Documentation/cpu-freq/user-guide.txt
Documentation/cpu-freq/user-guide.txt
+16
-0
drivers/cpufreq/Makefile
drivers/cpufreq/Makefile
+5
-2
drivers/cpufreq/proc_intf.c
drivers/cpufreq/proc_intf.c
+2
-0
include/linux/cpufreq.h
include/linux/cpufreq.h
+38
-35
kernel/cpufreq.c
kernel/cpufreq.c
+48
-67
No files found.
Documentation/cpu-freq/user-guide.txt
View file @
2342d6cb
...
...
@@ -21,6 +21,8 @@ Contents:
1.1 ARM
1.2 x86
1.3 sparc64
1.4 ppc
1.5 SuperH
2. "Policy" / "Governor"?
2.1 Policy
...
...
@@ -77,6 +79,20 @@ cpufreq:
UltraSPARC-III
1.4 ppc
-------
Several "PowerBook" and "iBook2" notebooks are supported.
1.5 SuperH
----------
The following SuperH processors are supported by cpufreq:
SH-3
SH-4
2. "Policy" / "Governor" ?
==========================
...
...
drivers/cpufreq/Makefile
View file @
2342d6cb
#CPUfreq governors and cross-arch helpers
# CPUfreq governors
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)
+=
userspace.o
# CPUfreq cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE)
+=
freq_table.o
obj-$(CONFIG_CPU_FREQ_PROC_INTF)
+=
proc_intf.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)
+=
userspace.o
drivers/cpufreq/proc_intf.c
View file @
2342d6cb
...
...
@@ -13,6 +13,8 @@
#include <asm/uaccess.h>
#define CPUFREQ_ALL_CPUS ((NR_CPUS))
/**
* cpufreq_parse_policy - parse a policy string
* @input_string: the string to parse.
...
...
include/linux/cpufreq.h
View file @
2342d6cb
...
...
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/completion.h>
#define CPUFREQ_NAME_LEN 16
...
...
@@ -31,17 +32,15 @@
int
cpufreq_register_notifier
(
struct
notifier_block
*
nb
,
unsigned
int
list
);
int
cpufreq_unregister_notifier
(
struct
notifier_block
*
nb
,
unsigned
int
list
);
#define CPUFREQ_TRANSITION_NOTIFIER (0)
#define CPUFREQ_POLICY_NOTIFIER (1)
#define CPUFREQ_ALL_CPUS ((NR_CPUS))
#define CPUFREQ_TRANSITION_NOTIFIER (0)
#define CPUFREQ_POLICY_NOTIFIER (1)
/********************** cpufreq policy notifiers *********************/
#define CPUFREQ_POLICY_POWERSAVE
(1)
#define CPUFREQ_POLICY_PERFORMANCE
(2)
#define CPUFREQ_POLICY_GOVERNOR
(3)
#define CPUFREQ_POLICY_POWERSAVE
(1)
#define CPUFREQ_POLICY_PERFORMANCE
(2)
#define CPUFREQ_POLICY_GOVERNOR
(3)
/* Frequency values here are CPU kHz so that hardware which doesn't run
* with some frequencies can complain without having to guess what per
...
...
@@ -52,30 +51,34 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
struct
cpufreq_governor
;
#define CPUFREQ_ETERNAL
(-1)
#define CPUFREQ_ETERNAL
(-1)
struct
cpufreq_cpuinfo
{
unsigned
int
max_freq
;
unsigned
int
min_freq
;
unsigned
int
transition_latency
;
unsigned
int
max_freq
;
unsigned
int
min_freq
;
unsigned
int
transition_latency
;
/* in 10^(-9) s */
};
struct
cpufreq_policy
{
unsigned
int
cpu
;
/* cpu nr or CPUFREQ_ALL_CPUS */
unsigned
int
min
;
/* in kHz */
unsigned
int
max
;
/* in kHz */
unsigned
int
cur
;
/* in kHz, only needed if cpufreq
unsigned
int
cpu
;
/* cpu nr */
struct
cpufreq_cpuinfo
cpuinfo
;
/* see above */
unsigned
int
min
;
/* in kHz */
unsigned
int
max
;
/* in kHz */
unsigned
int
cur
;
/* in kHz, only needed if cpufreq
* governors are used */
unsigned
int
policy
;
/* see above */
struct
cpufreq_governor
*
governor
;
/* see below */
struct
cpufreq_cpuinfo
cpuinfo
;
/* see above */
struct
kobject
kobj
;
unsigned
int
policy
;
/* see above */
struct
cpufreq_governor
*
governor
;
/* see below */
struct
semaphore
lock
;
/* CPU ->setpolicy or ->target may
only be called once a time */
struct
kobject
kobj
;
struct
completion
kobj_unregister
;
};
#define CPUFREQ_ADJUST
(0)
#define CPUFREQ_INCOMPATIBLE
(1)
#define CPUFREQ_NOTIFY
(2)
#define CPUFREQ_ADJUST
(0)
#define CPUFREQ_INCOMPATIBLE
(1)
#define CPUFREQ_NOTIFY
(2)
/******************** cpufreq transition notifiers *******************/
...
...
@@ -84,7 +87,7 @@ struct cpufreq_policy {
#define CPUFREQ_POSTCHANGE (1)
struct
cpufreq_freqs
{
unsigned
int
cpu
;
/* cpu nr or CPUFREQ_ALL_CPUS
*/
unsigned
int
cpu
;
/* cpu nr
*/
unsigned
int
old
;
unsigned
int
new
;
};
...
...
@@ -125,11 +128,11 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu
#define CPUFREQ_GOV_LIMITS 3
struct
cpufreq_governor
{
char
name
[
CPUFREQ_NAME_LEN
];
int
(
*
governor
)
(
struct
cpufreq_policy
*
policy
,
char
name
[
CPUFREQ_NAME_LEN
];
int
(
*
governor
)
(
struct
cpufreq_policy
*
policy
,
unsigned
int
event
);
struct
list_head
governor_list
;
struct
module
*
owner
;
struct
module
*
owner
;
};
/* pass a target to the cpufreq driver
...
...
@@ -154,18 +157,22 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor);
struct
freq_attr
;
struct
cpufreq_driver
{
struct
module
*
owner
;
char
name
[
CPUFREQ_NAME_LEN
];
struct
cpufreq_policy
*
policy
;
/* needed by all drivers */
int
(
*
init
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
verify
)
(
struct
cpufreq_policy
*
policy
);
struct
cpufreq_policy
*
policy
;
char
name
[
CPUFREQ_NAME_LEN
];
/* define one out of two */
int
(
*
setpolicy
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
target
)
(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
);
struct
module
*
owner
;
/* optional, for the moment */
int
(
*
init
)
(
struct
cpufreq_policy
*
policy
);
/* optional */
int
(
*
exit
)
(
struct
cpufreq_policy
*
policy
);
struct
freq_attr
**
attr
;
};
...
...
@@ -306,8 +313,4 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu);
#endif
/* CONFIG_CPU_FREQ_TABLE */
/* Currently exported only for the proc interface, remove when that goes */
extern
struct
cpufreq_driver
*
cpufreq_driver
;
#endif
/* _LINUX_CPUFREQ_H */
kernel/cpufreq.c
View file @
2342d6cb
...
...
@@ -23,6 +23,7 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/completion.h>
/**
* The "cpufreq driver" - the arch- or hardware-dependend low
...
...
@@ -297,6 +298,12 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
return
ret
;
}
static
void
cpufreq_sysfs_release
(
struct
kobject
*
kobj
)
{
struct
cpufreq_policy
*
policy
=
to_policy
(
kobj
);
complete
(
&
policy
->
kobj_unregister
);
}
static
struct
sysfs_ops
sysfs_ops
=
{
.
show
=
show
,
.
store
=
store
,
...
...
@@ -305,6 +312,7 @@ static struct sysfs_ops sysfs_ops = {
static
struct
kobj_type
ktype_cpufreq
=
{
.
sysfs_ops
=
&
sysfs_ops
,
.
default_attrs
=
default_attrs
,
.
release
=
cpufreq_sysfs_release
,
};
...
...
@@ -329,11 +337,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
*/
policy
=
&
cpufreq_driver
->
policy
[
cpu
];
policy
->
cpu
=
cpu
;
if
(
cpufreq_driver
->
init
)
{
ret
=
cpufreq_driver
->
init
(
policy
);
if
(
ret
)
goto
out
;
}
ret
=
cpufreq_driver
->
init
(
policy
);
if
(
ret
)
goto
out
;
/* set default policy on this CPU */
down
(
&
cpufreq_driver_sem
);
...
...
@@ -343,6 +349,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
up
(
&
cpufreq_driver_sem
);
init_MUTEX
(
&
policy
->
lock
);
init_completion
(
&
policy
->
kobj_unregister
);
/* prepare interface data */
policy
->
kobj
.
parent
=
&
sys_dev
->
kobj
;
policy
->
kobj
.
ktype
=
&
ktype_cpufreq
;
...
...
@@ -352,18 +360,19 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
if
(
ret
)
goto
out
;
/* set up files for this cpu device */
drv_attr
=
cpufreq_driver
->
attr
;
while
((
drv_attr
)
&&
(
*
drv_attr
))
{
sysfs_create_file
(
&
policy
->
kobj
,
&
((
*
drv_attr
)
->
attr
));
drv_attr
++
;
}
/* set up files for this cpu device */
/* set default policy */
ret
=
cpufreq_set_policy
(
&
new_policy
);
if
(
ret
)
if
(
ret
)
{
kobject_unregister
(
&
policy
->
kobj
);
wait_for_completion
(
&
policy
->
kobj_unregister
);
}
out:
module_put
(
cpufreq_driver
->
owner
);
...
...
@@ -401,10 +410,39 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
up
(
&
cpufreq_driver_sem
);
kobject_put
(
&
cpufreq_driver
->
policy
[
cpu
].
kobj
);
/* we need to make sure that the underlying kobj is actually
* destroyed before we proceed e.g. with cpufreq driver module
* unloading
*/
wait_for_completion
(
&
cpufreq_driver
->
policy
[
cpu
].
kobj_unregister
);
return
0
;
}
static
int
cpufreq_restore
(
struct
sys_device
*
);
/**
* cpufreq_restore - restore the CPU clock frequency after resume
*
* Restore the CPU clock frequency so that our idea of the current
* frequency reflects the actual hardware.
*/
static
int
cpufreq_restore
(
struct
sys_device
*
sysdev
)
{
int
cpu
=
sysdev
->
id
;
unsigned
int
ret
=
0
;
struct
cpufreq_policy
policy
;
if
(
cpu_online
(
cpu
)
&&
cpufreq_cpu_get
(
cpu
))
{
down
(
&
cpufreq_driver_sem
);
memcpy
(
&
policy
,
&
cpufreq_driver
->
policy
[
cpu
],
sizeof
(
struct
cpufreq_policy
));
up
(
&
cpufreq_driver_sem
);
ret
=
cpufreq_set_policy
(
&
policy
);
cpufreq_cpu_put
(
cpu
);
}
return
ret
;
}
static
struct
sysdev_driver
cpufreq_sysdev_driver
=
{
.
add
=
cpufreq_add_dev
,
...
...
@@ -587,33 +625,10 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);
void
cpufreq_unregister_governor
(
struct
cpufreq_governor
*
governor
)
{
unsigned
int
i
;
if
(
!
governor
)
return
;
down
(
&
cpufreq_governor_sem
);
/*
* Unless the user uses rmmod -f, we can be safe. But we never
* know, so check whether if it's currently used. If so,
* stop it and replace it with the default governor.
*/
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
!
cpufreq_cpu_get
(
i
))
continue
;
if
((
cpufreq_driver
->
policy
[
i
].
policy
==
CPUFREQ_POLICY_GOVERNOR
)
&&
(
cpufreq_driver
->
policy
[
i
].
governor
==
governor
))
{
cpufreq_governor
(
i
,
CPUFREQ_GOV_STOP
);
cpufreq_driver
->
policy
[
i
].
policy
=
CPUFREQ_POLICY_PERFORMANCE
;
cpufreq_governor
(
i
,
CPUFREQ_GOV_START
);
cpufreq_governor
(
i
,
CPUFREQ_GOV_LIMITS
);
}
cpufreq_cpu_put
(
i
);
}
/* now we can safely remove it from the list */
list_del
(
&
governor
->
governor_list
);
up
(
&
cpufreq_governor_sem
);
return
;
...
...
@@ -781,7 +796,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
switch
(
state
)
{
case
CPUFREQ_PRECHANGE
:
notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_PRECHANGE
,
freqs
);
adjust_jiffies
(
CPUFREQ_PRECHANGE
,
freqs
);
adjust_jiffies
(
CPUFREQ_PRECHANGE
,
freqs
);
break
;
case
CPUFREQ_POSTCHANGE
:
adjust_jiffies
(
CPUFREQ_POSTCHANGE
,
freqs
);
...
...
@@ -859,37 +874,3 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
return
0
;
}
EXPORT_SYMBOL_GPL
(
cpufreq_unregister_driver
);
#ifdef CONFIG_PM
/**
* cpufreq_restore - restore the CPU clock frequency after resume
*
* Restore the CPU clock frequency so that our idea of the current
* frequency reflects the actual hardware.
*/
static
int
cpufreq_restore
(
struct
sys_device
*
sysdev
)
{
int
cpu
=
sysdev
->
id
;
unsigned
int
ret
=
0
;
struct
cpufreq_policy
policy
;
if
(
cpu_online
(
cpu
)
&&
cpufreq_cpu_get
(
cpu
))
{
down
(
&
cpufreq_driver_sem
);
memcpy
(
&
policy
,
&
cpufreq_driver
->
policy
[
cpu
],
sizeof
(
struct
cpufreq_policy
));
up
(
&
cpufreq_driver_sem
);
ret
=
cpufreq_set_policy
(
&
policy
);
cpufreq_cpu_put
(
cpu
);
}
return
ret
;
}
#else
static
int
cpufreq_restore
(
struct
sys_device
*
sysdev
)
{
return
0
;
}
#endif
/* CONFIG_PM */
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