summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@osdl.org>2003-01-10 04:57:45 -0600
committerPatrick Mochel <mochel@osdl.org>2003-01-10 04:57:45 -0600
commit36aaef9f5e600cad25444782cc41eb0cccebb968 (patch)
treef3ed00aaafba41c38974babe42c10a179162ab99
parent8b0f4065ef46ead00bb630f74c0ed42eb00307a6 (diff)
parent1013687edc383b0f2912b0b5bc87331dd22a24e5 (diff)
Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin
into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core
-rw-r--r--arch/i386/kernel/cpu/cpufreq/elanfreq.c83
-rw-r--r--arch/i386/kernel/cpu/cpufreq/p4-clockmod.c97
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k6.c122
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep.c59
-rw-r--r--include/linux/cpufreq.h23
-rw-r--r--kernel/cpufreq.c125
-rw-r--r--mm/slab.c2
7 files changed, 263 insertions, 248 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c
index 08fac292dff8..1917510f0338 100644
--- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c
@@ -61,6 +61,18 @@ struct s_elan_multiplier elan_multiplier[] = {
{99000, 0x01, 0x05}
};
+static struct cpufreq_frequency_table elanfreq_table[] = {
+ {0, 1000},
+ {1, 2000},
+ {2, 4000},
+ {3, 8000},
+ {4, 16000},
+ {5, 33000},
+ {6, 66000},
+ {7, 99000},
+ {0, CPUFREQ_TABLE_END},
+};
+
/**
* elanfreq_get_cpu_frequency: determine current cpu speed
@@ -172,63 +184,17 @@ static void elanfreq_set_cpu_state (unsigned int state) {
static int elanfreq_verify (struct cpufreq_policy *policy)
{
- unsigned int number_states = 0;
- unsigned int i;
-
- if (!policy || !max_freq)
- return -EINVAL;
-
- policy->cpu = 0;
-
- cpufreq_verify_within_limits(policy, 1000, max_freq);
-
- for (i=7; i>=0; i--)
- if ((elan_multiplier[i].clock >= policy->min) &&
- (elan_multiplier[i].clock <= policy->max))
- number_states++;
-
- if (number_states)
- return 0;
-
- for (i=7; i>=0; i--)
- if (elan_multiplier[i].clock < policy->max)
- break;
-
- policy->max = elan_multiplier[i+1].clock;
-
- cpufreq_verify_within_limits(policy, 1000, max_freq);
-
- return 0;
+ return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]);
}
static int elanfreq_setpolicy (struct cpufreq_policy *policy)
{
- unsigned int i;
- unsigned int optimal = 8;
-
- if (!elanfreq_driver)
- return -EINVAL;
+ unsigned int newstate = 0;
- for (i=0; i<8; i++) {
- if ((elan_multiplier[i].clock > policy->max) ||
- (elan_multiplier[i].clock < policy->min))
- continue;
- switch(policy->policy) {
- case CPUFREQ_POLICY_POWERSAVE:
- if (optimal == 8)
- optimal = i;
- break;
- case CPUFREQ_POLICY_PERFORMANCE:
- optimal = i;
- break;
- default:
- return -EINVAL;
- }
- }
- if ((optimal == 8) || (elan_multiplier[optimal].clock > max_freq))
+ if (cpufreq_frequency_table_setpolicy(policy, &elanfreq_table[0], &newstate))
return -EINVAL;
- elanfreq_set_cpu_state(optimal);
+ elanfreq_set_cpu_state(newstate);
return 0;
}
@@ -262,7 +228,7 @@ static int __init elanfreq_init(void)
{
struct cpuinfo_x86 *c = cpu_data;
struct cpufreq_driver *driver;
- int ret;
+ int ret, i;
/* Test if we have the right hardware */
if ((c->x86_vendor != X86_VENDOR_AMD) ||
@@ -282,6 +248,12 @@ static int __init elanfreq_init(void)
if (!max_freq)
max_freq = elanfreq_get_cpu_frequency();
+ /* table init */
+ for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ if (elanfreq_table[i].frequency > max_freq)
+ elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ }
+
#ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency();
#endif
@@ -290,11 +262,12 @@ static int __init elanfreq_init(void)
driver->setpolicy = &elanfreq_setpolicy;
driver->policy[0].cpu = 0;
- driver->policy[0].min = 1000;
- driver->policy[0].max = max_freq;
+ ret = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &elanfreq_table[0]);
+ if (ret) {
+ kfree(driver);
+ return ret;
+ }
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
- driver->policy[0].cpuinfo.max_freq = max_freq;
- driver->policy[0].cpuinfo.min_freq = 1000;
driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
elanfreq_driver = driver;
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index 88b88508c4e1..e26c7918045e 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -141,39 +141,27 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
}
+static struct cpufreq_frequency_table p4clockmod_table[] = {
+ {DC_RESV, CPUFREQ_ENTRY_INVALID},
+ {DC_DFLT, 0},
+ {DC_25PT, 0},
+ {DC_38PT, 0},
+ {DC_50PT, 0},
+ {DC_64PT, 0},
+ {DC_75PT, 0},
+ {DC_88PT, 0},
+ {DC_DISABLE, 0},
+ {DC_RESV, CPUFREQ_TABLE_END},
+};
+
+
static int cpufreq_p4_setpolicy(struct cpufreq_policy *policy)
{
- unsigned int i;
- unsigned int newstate = 0;
- unsigned int number_states = 0;
- unsigned int minstate = 1;
+ unsigned int newstate = DC_RESV;
- if (!cpufreq_p4_driver || !stock_freq ||
- !policy || !cpu_online(policy->cpu))
+ if (cpufreq_frequency_table_setpolicy(policy, &p4clockmod_table[0], &newstate))
return -EINVAL;
- if (has_N44_O17_errata)
- minstate = 3;
-
- if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
- {
- for (i=8; i>=minstate; i--)
- if ((policy->min <= ((stock_freq / 8) * i)) &&
- (policy->max >= ((stock_freq / 8) * i)))
- {
- newstate = i;
- number_states++;
- }
- } else {
- for (i=minstate; i<=8; i++)
- if ((policy->min <= ((stock_freq / 8) * i)) &&
- (policy->max >= ((stock_freq / 8) * i)))
- {
- newstate = i;
- number_states++;
- }
- }
-
cpufreq_p4_setdc(policy->cpu, newstate);
return 0;
@@ -182,34 +170,7 @@ static int cpufreq_p4_setpolicy(struct cpufreq_policy *policy)
static int cpufreq_p4_verify(struct cpufreq_policy *policy)
{
- unsigned int number_states = 0;
- unsigned int i = 1;
-
- if (!cpufreq_p4_driver || !stock_freq ||
- !policy || !cpu_online(policy->cpu))
- return -EINVAL;
-
- cpufreq_verify_within_limits(policy,
- policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
-
- if (has_N44_O17_errata)
- i = 3;
-
- /* is there at least one state within the limit? */
- for (; i<=8; i++)
- if ((policy->min <= ((stock_freq / 8) * i)) &&
- (policy->max >= ((stock_freq / 8) * i)))
- number_states++;
-
- if (number_states)
- return 0;
-
- policy->max = (stock_freq / 8) * (((unsigned int) ((policy->max * 8) / stock_freq)) + 1);
- cpufreq_verify_within_limits(policy,
- policy->cpuinfo.min_freq,
- policy->cpuinfo.max_freq);
- return 0;
+ return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]);
}
@@ -262,6 +223,15 @@ static int __init cpufreq_p4_init(void)
driver->policy = (struct cpufreq_policy *) (driver + 1);
+ /* table init */
+ for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ if ((i<2) && (has_N44_O17_errata))
+ p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ else
+ p4clockmod_table[i].frequency = (stock_freq * i)/8;
+ }
+
+
#ifdef CONFIG_CPU_FREQ_24_API
for (i=0;i<NR_CPUS;i++) {
driver->cpu_cur_freq[i] = stock_freq;
@@ -272,17 +242,14 @@ static int __init cpufreq_p4_init(void)
driver->setpolicy = &cpufreq_p4_setpolicy;
for (i=0;i<NR_CPUS;i++) {
- if (has_N44_O17_errata)
- driver->policy[i].min = (stock_freq * 3) / 8;
- else
- driver->policy[i].min = stock_freq / 8;
- driver->policy[i].max = stock_freq;
+ driver->policy[i].cpu = i;
+ ret = cpufreq_frequency_table_cpuinfo(&driver->policy[i], &p4clockmod_table[0]);
+ if (ret) {
+ kfree(driver);
+ return ret;
+ }
driver->policy[i].policy = CPUFREQ_POLICY_PERFORMANCE;
- driver->policy[i].cpuinfo.min_freq = driver->policy[i].min;
- driver->policy[i].cpuinfo.max_freq = stock_freq;
driver->policy[i].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-
- driver->policy[i].cpu = i;
}
cpufreq_p4_driver = driver;
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
index b6ae33f21254..88085123ee3b 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
@@ -31,15 +31,16 @@ static unsigned int max_multiplier;
/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
-static int clock_ratio[8] = {
- 45, /* 000 -> 4.5x */
- 50, /* 001 -> 5.0x */
- 40, /* 010 -> 4.0x */
- 55, /* 011 -> 5.5x */
- 20, /* 100 -> 2.0x */
- 30, /* 101 -> 3.0x */
- 60, /* 110 -> 6.0x */
- 35 /* 111 -> 3.5x */
+static struct cpufreq_frequency_table clock_ratio[] = {
+ {45, /* 000 -> 4.5x */ 0},
+ {50, /* 001 -> 5.0x */ 0},
+ {40, /* 010 -> 4.0x */ 0},
+ {55, /* 011 -> 5.5x */ 0},
+ {20, /* 100 -> 2.0x */ 0},
+ {30, /* 101 -> 3.0x */ 0},
+ {60, /* 110 -> 6.0x */ 0},
+ {35, /* 111 -> 3.5x */ 0},
+ {0, CPUFREQ_TABLE_END}
};
@@ -60,7 +61,7 @@ static int powernow_k6_get_cpu_multiplier(void)
msrval = POWERNOW_IOPORT + 0x0;
wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
- return clock_ratio[(invalue >> 5)&7];
+ return clock_ratio[(invalue >> 5)&7].index;
}
@@ -82,7 +83,7 @@ static void powernow_k6_set_state (unsigned int best_i)
}
freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
- freqs.new = busfreq * clock_ratio[best_i];
+ freqs.new = busfreq * clock_ratio[best_i].index;
freqs.cpu = 0; /* powernow-k6.c is UP only driver */
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
@@ -115,39 +116,7 @@ static void powernow_k6_set_state (unsigned int best_i)
*/
static int powernow_k6_verify(struct cpufreq_policy *policy)
{
- unsigned int number_states = 0;
- unsigned int i, j;
-
- if (!policy || !busfreq)
- return -EINVAL;
-
- policy->cpu = 0;
- cpufreq_verify_within_limits(policy, (20 * busfreq),
- (max_multiplier * busfreq));
-
- for (i=0; i<8; i++)
- if ((policy->min <= (busfreq * clock_ratio[i])) &&
- (policy->max >= (busfreq * clock_ratio[i])))
- number_states++;
-
- if (number_states)
- return 0;
-
- /* no state is available within range -- find next larger state */
-
- j = 6;
-
- for (i=0; i<8; i++)
- if (((clock_ratio[i] * busfreq) >= policy->min) &&
- (clock_ratio[i] < clock_ratio[j]))
- j = i;
-
- policy->max = clock_ratio[j] * busfreq;
-
- cpufreq_verify_within_limits(policy, (20 * busfreq),
- (max_multiplier * busfreq));
-
- return 0;
+ return cpufreq_frequency_table_verify(policy, &clock_ratio[0]);
}
@@ -159,43 +128,12 @@ static int powernow_k6_verify(struct cpufreq_policy *policy)
*/
static int powernow_k6_setpolicy (struct cpufreq_policy *policy)
{
- unsigned int i;
- unsigned int optimal;
+ unsigned int newstate = 0;
- if (!powernow_driver || !policy || policy->cpu)
+ if (cpufreq_frequency_table_setpolicy(policy, &clock_ratio[0], &newstate))
return -EINVAL;
- switch(policy->policy) {
- case CPUFREQ_POLICY_POWERSAVE:
- optimal = 6;
- break;
- case CPUFREQ_POLICY_PERFORMANCE:
- optimal = max_multiplier;
- break;
- default:
- return -EINVAL;
- }
-
- for (i=0;i<8;i++) {
- unsigned int freq = busfreq * clock_ratio[i];
- if (clock_ratio[i] > max_multiplier)
- continue;
- if ((freq > policy->max) ||
- (freq < policy->min))
- continue;
- switch(policy->policy) {
- case CPUFREQ_POLICY_POWERSAVE:
- if (freq < (clock_ratio[optimal] * busfreq))
- optimal = i;
- break;
- case CPUFREQ_POLICY_PERFORMANCE:
- if (freq > (clock_ratio[optimal] * busfreq))
- optimal = i;
- break;
- }
- }
-
- powernow_k6_set_state(optimal);
+ powernow_k6_set_state(newstate);
return 0;
}
@@ -213,6 +151,7 @@ static int __init powernow_k6_init(void)
struct cpuinfo_x86 *c = cpu_data;
struct cpufreq_driver *driver;
unsigned int result;
+ unsigned int i;
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
((c->x86_model != 12) && (c->x86_model != 13)))
@@ -235,20 +174,29 @@ static int __init powernow_k6_init(void)
}
driver->policy = (struct cpufreq_policy *) (driver + 1);
-#ifdef CONFIG_CPU_FREQ_24_API
- driver->cpu_cur_freq[0] = busfreq * max_multiplier;
-#endif
+ /* table init */
+ for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
+ if (clock_ratio[i].index > max_multiplier)
+ clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
+ else
+ clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
+ }
driver->verify = &powernow_k6_verify;
driver->setpolicy = &powernow_k6_setpolicy;
+ /* cpuinfo and default policy values */
driver->policy[0].cpu = 0;
- driver->policy[0].min = busfreq * 20;
- driver->policy[0].max = busfreq * max_multiplier;
- driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
- driver->policy[0].cpuinfo.max_freq = busfreq * max_multiplier;
- driver->policy[0].cpuinfo.min_freq = busfreq * 20;
driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
+#ifdef CONFIG_CPU_FREQ_24_API
+ driver->cpu_cur_freq[0] = busfreq * max_multiplier;
+#endif
+ result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &clock_ratio[0]);
+ if (result) {
+ kfree(driver);
+ return result;
+ }
powernow_driver = driver;
@@ -274,7 +222,7 @@ static void __exit powernow_k6_exit(void)
if (powernow_driver) {
for (i=0;i<8;i++)
- if (clock_ratio[i] == max_multiplier)
+ if (clock_ratio[i].index == max_multiplier)
powernow_k6_set_state(i);
cpufreq_unregister();
kfree(powernow_driver);
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep.c b/arch/i386/kernel/cpu/cpufreq/speedstep.c
index 349f18b8d942..97212910fcff 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep.c
@@ -58,12 +58,18 @@ static int speedstep_coppermine = 0;
* There are only two frequency states for each processor. Values
* are in kHz for the time being.
*/
-static unsigned int speedstep_low_freq;
-static unsigned int speedstep_high_freq;
-
#define SPEEDSTEP_HIGH 0x00000000
#define SPEEDSTEP_LOW 0x00000001
+static struct cpufreq_frequency_table speedstep_freqs[] = {
+ {SPEEDSTEP_HIGH, 0},
+ {SPEEDSTEP_LOW, 0},
+ {0, CPUFREQ_TABLE_END},
+};
+
+#define speedstep_low_freq speedstep_freqs[SPEEDSTEP_LOW].frequency
+#define speedstep_high_freq speedstep_freqs[SPEEDSTEP_HIGH].frequency
+
/* DEBUG
* Define it if you want verbose debug output, e.g. for bug reporting
@@ -447,7 +453,7 @@ static unsigned int speedstep_detect_processor (void)
if (c->x86_model != 2)
return 0;
- if (c->x86_mask != 4)
+ if ((c->x86_mask != 4) && (c->x86_mask != 7))
return 0;
ebx = cpuid_ebx(0x00000001);
@@ -569,22 +575,13 @@ static int speedstep_detect_speeds (void)
*/
static int speedstep_setpolicy (struct cpufreq_policy *policy)
{
- if (!speedstep_driver || !policy)
+ unsigned int newstate = 0;
+
+ if (cpufreq_frequency_table_setpolicy(policy, &speedstep_freqs[0], &newstate))
return -EINVAL;
- if (policy->min > speedstep_low_freq)
- speedstep_set_state(SPEEDSTEP_HIGH, 1);
- else {
- if (policy->max < speedstep_high_freq)
- speedstep_set_state(SPEEDSTEP_LOW, 1);
- else {
- /* both frequency states are allowed */
- if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
- speedstep_set_state(SPEEDSTEP_LOW, 1);
- else
- speedstep_set_state(SPEEDSTEP_HIGH, 1);
- }
- }
+ speedstep_set_state(newstate, 1);
+
return 0;
}
@@ -598,19 +595,7 @@ static int speedstep_setpolicy (struct cpufreq_policy *policy)
*/
static int speedstep_verify (struct cpufreq_policy *policy)
{
- if (!policy || !speedstep_driver ||
- !speedstep_low_freq || !speedstep_high_freq)
- return -EINVAL;
-
- policy->cpu = 0; /* UP only */
-
- cpufreq_verify_within_limits(policy, speedstep_low_freq, speedstep_high_freq);
-
- if ((policy->min > speedstep_low_freq) &&
- (policy->max < speedstep_high_freq))
- policy->max = speedstep_high_freq;
-
- return 0;
+ return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
}
@@ -692,6 +677,13 @@ static int __init speedstep_init(void)
driver->policy = (struct cpufreq_policy *) (driver + 1);
+ driver->policy[0].cpu = 0;
+ result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &speedstep_freqs[0]);
+ if (result) {
+ kfree(driver);
+ return result;
+ }
+
#ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_cur_freq[0] = speed;
#endif
@@ -699,11 +691,6 @@ static int __init speedstep_init(void)
driver->verify = &speedstep_verify;
driver->setpolicy = &speedstep_setpolicy;
- driver->policy[0].cpu = 0;
- driver->policy[0].min = speedstep_low_freq;
- driver->policy[0].max = speedstep_high_freq;
- driver->policy[0].cpuinfo.min_freq = speedstep_low_freq;
- driver->policy[0].cpuinfo.max_freq = speedstep_high_freq;
driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
driver->policy[0].policy = (speed == speedstep_low_freq) ?
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index ab2890b619d0..0e008ba3618c 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -241,4 +241,27 @@ enum {
#endif /* CONFIG_CPU_FREQ_24_API */
+/*********************************************************************
+ * FREQUENCY TABLE HELPERS *
+ *********************************************************************/
+
+#define CPUFREQ_ENTRY_INVALID ~0
+#define CPUFREQ_TABLE_END ~1
+
+struct cpufreq_frequency_table {
+ unsigned int index; /* any */
+ unsigned int frequency; /* kHz - doesn't need to be in ascending
+ * order */
+};
+
+int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
+ struct cpufreq_frequency_table *table);
+
+int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
+ struct cpufreq_frequency_table *table);
+
+int cpufreq_frequency_table_setpolicy(struct cpufreq_policy *policy,
+ struct cpufreq_frequency_table *table,
+ unsigned int *index);
+
#endif /* _LINUX_CPUFREQ_H */
diff --git a/kernel/cpufreq.c b/kernel/cpufreq.c
index c0be78462c81..d5b4003ef3cd 100644
--- a/kernel/cpufreq.c
+++ b/kernel/cpufreq.c
@@ -734,8 +734,8 @@ static inline void cpufreq_sysctl_exit(void)
}
#else
-#define cpufreq_sysctl_init()
-#define cpufreq_sysctl_exit()
+#define cpufreq_sysctl_init() do {} while(0)
+#define cpufreq_sysctl_exit() do {} while(0)
#endif /* CONFIG_SYSCTL */
#endif /* CONFIG_CPU_FREQ_24_API */
@@ -946,7 +946,7 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
}
#else
-#define adjust_jiffies(...)
+#define adjust_jiffies(x...) do {} while (0)
#endif
@@ -1131,6 +1131,123 @@ int cpufreq_restore(void)
}
EXPORT_SYMBOL_GPL(cpufreq_restore);
#else
-#define cpufreq_restore()
+#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);
diff --git a/mm/slab.c b/mm/slab.c
index c6740a88a703..ceccd7bc7fcf 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -502,7 +502,7 @@ static void cache_estimate (unsigned long gfporder, size_t size,
#define slab_error(cachep, msg) __slab_error(__FUNCTION__, cachep, msg)
-static void __slab_error(char *function, kmem_cache_t *cachep, char *msg)
+static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg)
{
printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
function, cachep->name, msg);