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
4eabfbb6
Commit
4eabfbb6
authored
Jul 08, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux-dj.bkbits.net/cpufreq
into home.osdl.org:/home/torvalds/v2.5/linux
parents
85bce232
2342d6cb
Changes
5
Show 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 @
4eabfbb6
...
@@ -21,6 +21,8 @@ Contents:
...
@@ -21,6 +21,8 @@ Contents:
1.1 ARM
1.1 ARM
1.2 x86
1.2 x86
1.3 sparc64
1.3 sparc64
1.4 ppc
1.5 SuperH
2. "Policy" / "Governor"?
2. "Policy" / "Governor"?
2.1 Policy
2.1 Policy
...
@@ -77,6 +79,20 @@ cpufreq:
...
@@ -77,6 +79,20 @@ cpufreq:
UltraSPARC-III
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" ?
2. "Policy" / "Governor" ?
==========================
==========================
...
...
drivers/cpufreq/Makefile
View file @
4eabfbb6
#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_TABLE)
+=
freq_table.o
obj-$(CONFIG_CPU_FREQ_PROC_INTF)
+=
proc_intf.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 @
4eabfbb6
...
@@ -13,6 +13,8 @@
...
@@ -13,6 +13,8 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#define CPUFREQ_ALL_CPUS ((NR_CPUS))
/**
/**
* cpufreq_parse_policy - parse a policy string
* cpufreq_parse_policy - parse a policy string
* @input_string: the string to parse.
* @input_string: the string to parse.
...
...
include/linux/cpufreq.h
View file @
4eabfbb6
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/device.h>
#include <linux/kobject.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/sysfs.h>
#include <linux/completion.h>
#define CPUFREQ_NAME_LEN 16
#define CPUFREQ_NAME_LEN 16
...
@@ -34,8 +35,6 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
...
@@ -34,8 +35,6 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
#define CPUFREQ_TRANSITION_NOTIFIER (0)
#define CPUFREQ_TRANSITION_NOTIFIER (0)
#define CPUFREQ_POLICY_NOTIFIER (1)
#define CPUFREQ_POLICY_NOTIFIER (1)
#define CPUFREQ_ALL_CPUS ((NR_CPUS))
/********************** cpufreq policy notifiers *********************/
/********************** cpufreq policy notifiers *********************/
...
@@ -56,21 +55,25 @@ struct cpufreq_governor;
...
@@ -56,21 +55,25 @@ struct cpufreq_governor;
struct
cpufreq_cpuinfo
{
struct
cpufreq_cpuinfo
{
unsigned
int
max_freq
;
unsigned
int
max_freq
;
unsigned
int
min_freq
;
unsigned
int
min_freq
;
unsigned
int
transition_latency
;
unsigned
int
transition_latency
;
/* in 10^(-9) s */
};
};
struct
cpufreq_policy
{
struct
cpufreq_policy
{
unsigned
int
cpu
;
/* cpu nr or CPUFREQ_ALL_CPUS */
unsigned
int
cpu
;
/* cpu nr */
struct
cpufreq_cpuinfo
cpuinfo
;
/* see above */
unsigned
int
min
;
/* in kHz */
unsigned
int
min
;
/* in kHz */
unsigned
int
max
;
/* in kHz */
unsigned
int
max
;
/* in kHz */
unsigned
int
cur
;
/* in kHz, only needed if cpufreq
unsigned
int
cur
;
/* in kHz, only needed if cpufreq
* governors are used */
* governors are used */
unsigned
int
policy
;
/* see above */
unsigned
int
policy
;
/* see above */
struct
cpufreq_governor
*
governor
;
/* see below */
struct
cpufreq_governor
*
governor
;
/* see below */
struct
cpufreq_cpuinfo
cpuinfo
;
/* see above */
struct
kobject
kobj
;
struct
semaphore
lock
;
/* CPU ->setpolicy or ->target may
struct
semaphore
lock
;
/* CPU ->setpolicy or ->target may
only be called once a time */
only be called once a time */
struct
kobject
kobj
;
struct
completion
kobj_unregister
;
};
};
#define CPUFREQ_ADJUST (0)
#define CPUFREQ_ADJUST (0)
...
@@ -84,7 +87,7 @@ struct cpufreq_policy {
...
@@ -84,7 +87,7 @@ struct cpufreq_policy {
#define CPUFREQ_POSTCHANGE (1)
#define CPUFREQ_POSTCHANGE (1)
struct
cpufreq_freqs
{
struct
cpufreq_freqs
{
unsigned
int
cpu
;
/* cpu nr or CPUFREQ_ALL_CPUS
*/
unsigned
int
cpu
;
/* cpu nr
*/
unsigned
int
old
;
unsigned
int
old
;
unsigned
int
new
;
unsigned
int
new
;
};
};
...
@@ -154,18 +157,22 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor);
...
@@ -154,18 +157,22 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor);
struct
freq_attr
;
struct
freq_attr
;
struct
cpufreq_driver
{
struct
cpufreq_driver
{
struct
module
*
owner
;
char
name
[
CPUFREQ_NAME_LEN
];
struct
cpufreq_policy
*
policy
;
/* needed by all drivers */
/* needed by all drivers */
int
(
*
init
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
verify
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
verify
)
(
struct
cpufreq_policy
*
policy
);
struct
cpufreq_policy
*
policy
;
char
name
[
CPUFREQ_NAME_LEN
];
/* define one out of two */
/* define one out of two */
int
(
*
setpolicy
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
setpolicy
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
target
)
(
struct
cpufreq_policy
*
policy
,
int
(
*
target
)
(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
target_freq
,
unsigned
int
relation
);
unsigned
int
relation
);
struct
module
*
owner
;
/* optional, for the moment */
/* optional */
int
(
*
init
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
exit
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
exit
)
(
struct
cpufreq_policy
*
policy
);
struct
freq_attr
**
attr
;
struct
freq_attr
**
attr
;
};
};
...
@@ -306,8 +313,4 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu);
...
@@ -306,8 +313,4 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu);
#endif
/* CONFIG_CPU_FREQ_TABLE */
#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 */
#endif
/* _LINUX_CPUFREQ_H */
kernel/cpufreq.c
View file @
4eabfbb6
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include <linux/device.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/cpu.h>
#include <linux/completion.h>
/**
/**
* The "cpufreq driver" - the arch- or hardware-dependend low
* The "cpufreq driver" - the arch- or hardware-dependend low
...
@@ -297,6 +298,12 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
...
@@ -297,6 +298,12 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
return
ret
;
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
=
{
static
struct
sysfs_ops
sysfs_ops
=
{
.
show
=
show
,
.
show
=
show
,
.
store
=
store
,
.
store
=
store
,
...
@@ -305,6 +312,7 @@ static struct sysfs_ops sysfs_ops = {
...
@@ -305,6 +312,7 @@ static struct sysfs_ops sysfs_ops = {
static
struct
kobj_type
ktype_cpufreq
=
{
static
struct
kobj_type
ktype_cpufreq
=
{
.
sysfs_ops
=
&
sysfs_ops
,
.
sysfs_ops
=
&
sysfs_ops
,
.
default_attrs
=
default_attrs
,
.
default_attrs
=
default_attrs
,
.
release
=
cpufreq_sysfs_release
,
};
};
...
@@ -329,11 +337,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
...
@@ -329,11 +337,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
*/
*/
policy
=
&
cpufreq_driver
->
policy
[
cpu
];
policy
=
&
cpufreq_driver
->
policy
[
cpu
];
policy
->
cpu
=
cpu
;
policy
->
cpu
=
cpu
;
if
(
cpufreq_driver
->
init
)
{
ret
=
cpufreq_driver
->
init
(
policy
);
ret
=
cpufreq_driver
->
init
(
policy
);
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
}
/* set default policy on this CPU */
/* set default policy on this CPU */
down
(
&
cpufreq_driver_sem
);
down
(
&
cpufreq_driver_sem
);
...
@@ -343,6 +349,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
...
@@ -343,6 +349,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
up
(
&
cpufreq_driver_sem
);
up
(
&
cpufreq_driver_sem
);
init_MUTEX
(
&
policy
->
lock
);
init_MUTEX
(
&
policy
->
lock
);
init_completion
(
&
policy
->
kobj_unregister
);
/* prepare interface data */
/* prepare interface data */
policy
->
kobj
.
parent
=
&
sys_dev
->
kobj
;
policy
->
kobj
.
parent
=
&
sys_dev
->
kobj
;
policy
->
kobj
.
ktype
=
&
ktype_cpufreq
;
policy
->
kobj
.
ktype
=
&
ktype_cpufreq
;
...
@@ -352,18 +360,19 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
...
@@ -352,18 +360,19 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
/* set up files for this cpu device */
drv_attr
=
cpufreq_driver
->
attr
;
drv_attr
=
cpufreq_driver
->
attr
;
while
((
drv_attr
)
&&
(
*
drv_attr
))
{
while
((
drv_attr
)
&&
(
*
drv_attr
))
{
sysfs_create_file
(
&
policy
->
kobj
,
&
((
*
drv_attr
)
->
attr
));
sysfs_create_file
(
&
policy
->
kobj
,
&
((
*
drv_attr
)
->
attr
));
drv_attr
++
;
drv_attr
++
;
}
}
/* set up files for this cpu device */
/* set default policy */
/* set default policy */
ret
=
cpufreq_set_policy
(
&
new_policy
);
ret
=
cpufreq_set_policy
(
&
new_policy
);
if
(
ret
)
if
(
ret
)
{
kobject_unregister
(
&
policy
->
kobj
);
kobject_unregister
(
&
policy
->
kobj
);
wait_for_completion
(
&
policy
->
kobj_unregister
);
}
out:
out:
module_put
(
cpufreq_driver
->
owner
);
module_put
(
cpufreq_driver
->
owner
);
...
@@ -401,10 +410,39 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
...
@@ -401,10 +410,39 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
up
(
&
cpufreq_driver_sem
);
up
(
&
cpufreq_driver_sem
);
kobject_put
(
&
cpufreq_driver
->
policy
[
cpu
].
kobj
);
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
;
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
=
{
static
struct
sysdev_driver
cpufreq_sysdev_driver
=
{
.
add
=
cpufreq_add_dev
,
.
add
=
cpufreq_add_dev
,
...
@@ -587,33 +625,10 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);
...
@@ -587,33 +625,10 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);
void
cpufreq_unregister_governor
(
struct
cpufreq_governor
*
governor
)
void
cpufreq_unregister_governor
(
struct
cpufreq_governor
*
governor
)
{
{
unsigned
int
i
;
if
(
!
governor
)
if
(
!
governor
)
return
;
return
;
down
(
&
cpufreq_governor_sem
);
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
);
list_del
(
&
governor
->
governor_list
);
up
(
&
cpufreq_governor_sem
);
up
(
&
cpufreq_governor_sem
);
return
;
return
;
...
@@ -859,37 +874,3 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
...
@@ -859,37 +874,3 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
return
0
;
return
0
;
}
}
EXPORT_SYMBOL_GPL
(
cpufreq_unregister_driver
);
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