summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Brodowski <linux@brodo.de>2003-02-14 20:44:13 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-02-14 20:44:13 -0800
commit589e8be90ac9053d12eff741aed5430edf062298 (patch)
tree0488bce01e62a65a0e1a5e2da93912dba28b0122
parent4e075e505c8abcbc1ceb16f5fad01900751fe389 (diff)
[PATCH] cpufreq: move frequency table helpers to extra module
The CPU frequency table helpers can easily be modularized -- especially as they are not needed on all architectures, or for all drivers (even on x86 -- see longrun and gx-suspmod)
-rw-r--r--arch/i386/Kconfig22
-rw-r--r--arch/sparc64/Kconfig7
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/cpufreq/Makefile2
-rw-r--r--drivers/cpufreq/freq_table.c203
-rw-r--r--include/linux/cpufreq.h3
-rw-r--r--kernel/cpufreq.c188
7 files changed, 231 insertions, 195 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index c0652a981423..5c86a7951d5b 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -994,9 +994,19 @@ config CPU_FREQ_24_API
If in doubt, say N.
+config CPU_FREQ_TABLE
+ tristate "CPU frequency table helpers"
+ depends on CPU_FREQ
+ default y
+ help
+ Many CPUFreq drivers use these helpers, so only say N here if
+ the CPUFreq driver of your choice doesn't need these helpers.
+
+ If in doubt, say Y.
+
config X86_ACPI_CPUFREQ
tristate "ACPI Processor P-States driver"
- depends on CPU_FREQ && ACPI_PROCESSOR
+ depends on CPU_FREQ_TABLE && ACPI_PROCESSOR
help
This driver adds a CPUFreq driver which utilizes the ACPI
Processor Performance States.
@@ -1007,7 +1017,7 @@ config X86_ACPI_CPUFREQ
config X86_POWERNOW_K6
tristate "AMD Mobile K6-2/K6-3 PowerNow!"
- depends on CPU_FREQ
+ depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
AMD K6-3+ processors.
@@ -1018,7 +1028,7 @@ config X86_POWERNOW_K6
config X86_POWERNOW_K7
tristate "AMD Mobile Athlon/Duron PowerNow!"
- depends on CPU_FREQ
+ depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for mobile AMD K7 mobile processors.
@@ -1028,7 +1038,7 @@ config X86_POWERNOW_K7
config ELAN_CPUFREQ
tristate "AMD Elan"
- depends on CPU_FREQ && MELAN
+ depends on CPU_FREQ_TABLE && MELAN
---help---
This adds the CPUFreq driver for AMD Elan SC400 and SC410
processors.
@@ -1055,7 +1065,7 @@ config X86_LONGHAUL
config X86_SPEEDSTEP
tristate "Intel Speedstep"
- depends on CPU_FREQ
+ depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for certain mobile Intel Pentium III
(Coppermine), all mobile Intel Pentium III-M (Tulatin) and all
@@ -1067,7 +1077,7 @@ config X86_SPEEDSTEP
config X86_P4_CLOCKMOD
tristate "Intel Pentium 4 clock modulation"
- depends on CPU_FREQ
+ depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for Intel Pentium 4 / XEON
processors.
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 6aaf45263442..e3bf2f1e5ec2 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -162,9 +162,14 @@ config CPU_FREQ_PROC_INTF
If in doubt, say N.
+config CPU_FREQ_TABLE
+ tristate
+ default y
+
+
config US3_FREQ
tristate "UltraSPARC-III CPU Frequency driver"
- depends on CPU_FREQ
+ depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for UltraSPARC-III processors.
diff --git a/drivers/Makefile b/drivers/Makefile
index 24a5350f7d53..458e82e75568 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -45,3 +45,4 @@ obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
obj-$(CONFIG_ISDN_BOOL) += isdn/
obj-$(CONFIG_MCA) += mca/
obj-$(CONFIG_EISA) += eisa/
+obj-$(CONFIG_CPU_FREQ) += cpufreq/
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
new file mode 100644
index 000000000000..6be9f5e6998c
--- /dev/null
+++ b/drivers/cpufreq/Makefile
@@ -0,0 +1,2 @@
+#CPUfreq governors and cross-arch helpers
+obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
new file mode 100644
index 000000000000..8922d0d4a363
--- /dev/null
+++ b/drivers/cpufreq/freq_table.c
@@ -0,0 +1,203 @@
+/*
+ * linux/drivers/cpufreq/freq_table.c
+ *
+ * Copyright (C) 2002 - 2003 Dominik Brodowski
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+/*********************************************************************
+ * FREQUENCY TABLE HELPERS *
+ *********************************************************************/
+
+int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
+ struct cpufreq_frequency_table *table)
+{
+ unsigned int min_freq = ~0;
+ unsigned int max_freq = 0;
+ unsigned int i = 0;
+
+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ unsigned int freq = table[i].frequency;
+ if (freq == CPUFREQ_ENTRY_INVALID)
+ continue;
+ if (freq < min_freq)
+ min_freq = freq;
+ if (freq > max_freq)
+ max_freq = freq;
+ }
+
+ policy->min = policy->cpuinfo.min_freq = min_freq;
+ policy->max = policy->cpuinfo.max_freq = max_freq;
+
+ if (policy->min == ~0)
+ return -EINVAL;
+ else
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo);
+
+
+int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
+ struct cpufreq_frequency_table *table)
+{
+ unsigned int next_larger = ~0;
+ unsigned int i = 0;
+ unsigned int count = 0;
+
+ if (!cpu_online(policy->cpu))
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy,
+ policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ unsigned int freq = table[i].frequency;
+ if (freq == CPUFREQ_ENTRY_INVALID)
+ continue;
+ if ((freq >= policy->min) && (freq <= policy->max))
+ count++;
+ else if ((next_larger > freq) && (freq > policy->max))
+ next_larger = freq;
+ }
+
+ if (!count)
+ policy->max = next_larger;
+
+ cpufreq_verify_within_limits(policy,
+ policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
+
+
+int cpufreq_frequency_table_setpolicy(struct cpufreq_policy *policy,
+ struct cpufreq_frequency_table *table,
+ unsigned int *index)
+{
+ struct cpufreq_frequency_table optimal = { .index = ~0, };
+ unsigned int i;
+
+ switch (policy->policy) {
+ case CPUFREQ_POLICY_PERFORMANCE:
+ optimal.frequency = 0;
+ break;
+ case CPUFREQ_POLICY_POWERSAVE:
+ optimal.frequency = ~0;
+ break;
+ }
+
+ if (!cpu_online(policy->cpu))
+ return -EINVAL;
+
+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ unsigned int freq = table[i].frequency;
+ if (freq == CPUFREQ_ENTRY_INVALID)
+ continue;
+ if ((freq < policy->min) || (freq > policy->max))
+ continue;
+ switch(policy->policy) {
+ case CPUFREQ_POLICY_PERFORMANCE:
+ if (optimal.frequency <= freq) {
+ optimal.frequency = freq;
+ optimal.index = i;
+ }
+ break;
+ case CPUFREQ_POLICY_POWERSAVE:
+ if (optimal.frequency >= freq) {
+ optimal.frequency = freq;
+ optimal.index = i;
+ }
+ break;
+ }
+ }
+ if (optimal.index > i)
+ return -EINVAL;
+
+ *index = optimal.index;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_setpolicy);
+
+
+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+ struct cpufreq_frequency_table *table,
+ unsigned int target_freq,
+ unsigned int relation,
+ unsigned int *index)
+{
+ struct cpufreq_frequency_table optimal = { .index = ~0, };
+ struct cpufreq_frequency_table suboptimal = { .index = ~0, };
+ unsigned int i;
+
+ switch (relation) {
+ case CPUFREQ_RELATION_H:
+ optimal.frequency = 0;
+ suboptimal.frequency = ~0;
+ break;
+ case CPUFREQ_RELATION_L:
+ optimal.frequency = ~0;
+ suboptimal.frequency = 0;
+ break;
+ }
+
+ if (!cpu_online(policy->cpu))
+ return -EINVAL;
+
+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ unsigned int freq = table[i].frequency;
+ if (freq == CPUFREQ_ENTRY_INVALID)
+ continue;
+ if ((freq < policy->min) || (freq > policy->max))
+ continue;
+ switch(relation) {
+ case CPUFREQ_RELATION_H:
+ if (freq <= target_freq) {
+ if (freq >= optimal.frequency) {
+ optimal.frequency = freq;
+ optimal.index = i;
+ }
+ } else {
+ if (freq <= suboptimal.frequency) {
+ suboptimal.frequency = freq;
+ suboptimal.index = i;
+ }
+ }
+ break;
+ case CPUFREQ_RELATION_L:
+ if (freq >= target_freq) {
+ if (freq <= optimal.frequency) {
+ optimal.frequency = freq;
+ optimal.index = i;
+ }
+ } else {
+ if (freq >= suboptimal.frequency) {
+ suboptimal.frequency = freq;
+ suboptimal.index = i;
+ }
+ }
+ break;
+ }
+ }
+ if (optimal.index > i) {
+ if (suboptimal.index > i)
+ return -EINVAL;
+ *index = suboptimal.index;
+ } else
+ *index = optimal.index;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
+
+
+MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
+MODULE_LICENSE ("GPL");
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 68571eca8e70..a49e134b2b6a 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -297,6 +297,7 @@ enum {
#endif /* CONFIG_CPU_FREQ_24_API */
+#if defined(CONFIG_CPU_FREQ_TABLE) || defined(CONFIG_CPU_FREQ_TABLE_MODULE)
/*********************************************************************
* FREQUENCY TABLE HELPERS *
*********************************************************************/
@@ -326,4 +327,6 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
unsigned int relation,
unsigned int *index);
+#endif /* CONFIG_CPU_FREQ_TABLE */
+
#endif /* _LINUX_CPUFREQ_H */
diff --git a/kernel/cpufreq.c b/kernel/cpufreq.c
index b28ebbd7ef3b..4de004bf4aa6 100644
--- a/kernel/cpufreq.c
+++ b/kernel/cpufreq.c
@@ -1582,191 +1582,3 @@ EXPORT_SYMBOL_GPL(cpufreq_restore);
#else
#define cpufreq_restore() do {} while (0)
#endif /* CONFIG_PM */
-
-
-/*********************************************************************
- * FREQUENCY TABLE HELPERS *
- *********************************************************************/
-
-int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table)
-{
- unsigned int min_freq = ~0;
- unsigned int max_freq = 0;
- unsigned int i = 0;
-
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
- unsigned int freq = table[i].frequency;
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
- if (freq < min_freq)
- min_freq = freq;
- if (freq > max_freq)
- max_freq = freq;
- }
-
- policy->min = policy->cpuinfo.min_freq = min_freq;
- policy->max = policy->cpuinfo.max_freq = max_freq;
-
- if (policy->min == ~0)
- return -EINVAL;
- else
- return 0;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo);
-
-
-int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table)
-{
- unsigned int next_larger = ~0;
- unsigned int i = 0;
- unsigned int count = 0;
-
- if (!cpu_online(policy->cpu))
- return -EINVAL;
-
- cpufreq_verify_within_limits(policy,
- policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
- unsigned int freq = table[i].frequency;
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
- if ((freq >= policy->min) && (freq <= policy->max))
- count++;
- else if ((next_larger > freq) && (freq > policy->max))
- next_larger = freq;
- }
-
- if (!count)
- policy->max = next_larger;
-
- cpufreq_verify_within_limits(policy,
- policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
-
-
-int cpufreq_frequency_table_setpolicy(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table,
- unsigned int *index)
-{
- struct cpufreq_frequency_table optimal = { .index = ~0, };
- unsigned int i;
-
- switch (policy->policy) {
- case CPUFREQ_POLICY_PERFORMANCE:
- optimal.frequency = 0;
- break;
- case CPUFREQ_POLICY_POWERSAVE:
- optimal.frequency = ~0;
- break;
- }
-
- if (!cpu_online(policy->cpu))
- return -EINVAL;
-
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
- unsigned int freq = table[i].frequency;
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
- if ((freq < policy->min) || (freq > policy->max))
- continue;
- switch(policy->policy) {
- case CPUFREQ_POLICY_PERFORMANCE:
- if (optimal.frequency <= freq) {
- optimal.frequency = freq;
- optimal.index = i;
- }
- break;
- case CPUFREQ_POLICY_POWERSAVE:
- if (optimal.frequency >= freq) {
- optimal.frequency = freq;
- optimal.index = i;
- }
- break;
- }
- }
- if (optimal.index > i)
- return -EINVAL;
-
- *index = optimal.index;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_table_setpolicy);
-
-int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table,
- unsigned int target_freq,
- unsigned int relation,
- unsigned int *index)
-{
- struct cpufreq_frequency_table optimal = { .index = ~0, };
- struct cpufreq_frequency_table suboptimal = { .index = ~0, };
- unsigned int i;
-
- switch (relation) {
- case CPUFREQ_RELATION_H:
- optimal.frequency = 0;
- suboptimal.frequency = ~0;
- break;
- case CPUFREQ_RELATION_L:
- optimal.frequency = ~0;
- suboptimal.frequency = 0;
- break;
- }
-
- if (!cpu_online(policy->cpu))
- return -EINVAL;
-
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
- unsigned int freq = table[i].frequency;
- if (freq == CPUFREQ_ENTRY_INVALID)
- continue;
- if ((freq < policy->min) || (freq > policy->max))
- continue;
- switch(relation) {
- case CPUFREQ_RELATION_H:
- if (freq <= target_freq) {
- if (freq >= optimal.frequency) {
- optimal.frequency = freq;
- optimal.index = i;
- }
- } else {
- if (freq <= suboptimal.frequency) {
- suboptimal.frequency = freq;
- suboptimal.index = i;
- }
- }
- break;
- case CPUFREQ_RELATION_L:
- if (freq >= target_freq) {
- if (freq <= optimal.frequency) {
- optimal.frequency = freq;
- optimal.index = i;
- }
- } else {
- if (freq >= suboptimal.frequency) {
- suboptimal.frequency = freq;
- suboptimal.index = i;
- }
- }
- break;
- }
- }
- if (optimal.index > i) {
- if (suboptimal.index > i)
- return -EINVAL;
- *index = suboptimal.index;
- } else
- *index = optimal.index;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);