Commit 0c7eef6a authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Linus Torvalds

[PATCH] cpufreq: cleanups

This changes the return type of the verify and setpolicy functions from
void to int.  While doing this, I've changed the values for minimum and
maximum supported frequency to be per CPU, as UltraSPARC needs this.

Additionally, small cleanups in various drivers.
parent 645e448c
...@@ -87,7 +87,8 @@ PowerNow! K6: ...@@ -87,7 +87,8 @@ PowerNow! K6:
Transmeta Crusoe Longrun: Transmeta Crusoe Longrun:
Transmeta Crusoe processors: Transmeta Crusoe processors:
-------------------------------- --------------------------------
Does not work with the 2.4. /proc/sys/cpu/ interface. It is recommended to use the 2.6. /proc/cpufreq interface when
using this driver
...@@ -283,15 +284,17 @@ entries: ...@@ -283,15 +284,17 @@ entries:
cpufreq_verify_t verify: This is a pointer to a function with the cpufreq_verify_t verify: This is a pointer to a function with the
following definition: following definition:
void verify_function (struct cpufreq_policy *policy). int verify_function (struct cpufreq_policy *policy).
This function must verify the new policy is within the limits This function must verify the new policy is within the limits
supported by the CPU, and at least one supported CPU is within supported by the CPU, and at least one supported CPU is within
this range. It may be useful to use cpufreq.h / this range. It may be useful to use cpufreq.h /
cpufreq_verify_within_limits for this. cpufreq_verify_within_limits for this. If this is called with
CPUFREQ_ALL_CPUS, and there is no common subset of frequencies
for all CPUs, exit with an error.
cpufreq_setpolicy_t setpolicy: This is a pointer to a function with cpufreq_setpolicy_t setpolicy: This is a pointer to a function with
the following definition: the following definition:
void setpolicy_function (struct cpufreq_policy *policy). int setpolicy_function (struct cpufreq_policy *policy).
This function must set the CPU to the new policy. If it is a This function must set the CPU to the new policy. If it is a
"dumb" CPU which only allows fixed frequencies to be set, it "dumb" CPU which only allows fixed frequencies to be set, it
shall set it to the lowest within the limit for shall set it to the lowest within the limit for
...@@ -302,30 +305,30 @@ cpufreq_setpolicy_t setpolicy: This is a pointer to a function with ...@@ -302,30 +305,30 @@ cpufreq_setpolicy_t setpolicy: This is a pointer to a function with
struct cpufreq_policy *policy: This is an array of NR_CPUS struct struct cpufreq_policy *policy: This is an array of NR_CPUS struct
cpufreq_policies, containing the current policies set for these cpufreq_policies, containing the current policies set for these
CPUs. Note that policy[0].max_cpu_freq must contain the CPUs. Note that policy[cpu].max_cpu_freq must contain the
absolute maximum CPU frequency supported by _all_ CPUs. absolute maximum CPU frequency supported by the specified cpu.
In case the driver is expected to run with the 2.4.-style API In case the driver is expected to run with the 2.4.-style API
(/proc/sys/cpu/.../), two more values must be passed (/proc/sys/cpu/.../), two more values must be passed
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
unsigned int cpu_min_freq; unsigned int cpu_min_freq[NR_CPUS];
unsigned int cpu_cur_freq[NR_CPUS]; unsigned int cpu_cur_freq[NR_CPUS];
#endif #endif
with cpu_min_freq being the minimum CPU frequency supported by with cpu_min_freq[cpu] being the minimum CPU frequency
the CPUs; and the entries in cpu_cur_freq reflecting the supported by the CPU; and the entries in cpu_cur_freq
current speed of the appropriate CPU. reflecting the current speed of the appropriate CPU.
Some Requirements to CPUFreq architecture drivers Some Requirements to CPUFreq architecture drivers
------------------------------------------------- -------------------------------------------------
* Only call cpufreq_register() when the ability to switch CPU * Only call cpufreq_register() when the ability to switch CPU
frequencies is _verified_ or can't be missing frequencies is _verified_ or can't be missing. Also, all
other initialization must be done beofre this call, as
cpfureq_register calls the driver's verify and setpolicy code for
each CPU.
* cpufreq_unregister() may only be called if cpufreq_register() has * cpufreq_unregister() may only be called if cpufreq_register() has
been successfully(!) called before. been successfully(!) called before.
* kfree() the struct cpufreq_driver only after the call to * kfree() the struct cpufreq_driver only after the call to
cpufreq_unregister(), unless cpufreq_register() failed. cpufreq_unregister(), unless cpufreq_register() failed.
* Be aware that there is currently no error management in the
setpolicy() code in the CPUFreq core. So only call yourself a
cpufreq_driver if you are really a working cpufreq_driver!
......
...@@ -73,7 +73,7 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor) ...@@ -73,7 +73,7 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor)
* Validate the speed in khz. If it is outside our * Validate the speed in khz. If it is outside our
* range, then return the lowest. * range, then return the lowest.
*/ */
static void integrator_verify_speed(struct cpufreq_policy *policy) static int integrator_verify_speed(struct cpufreq_policy *policy)
{ {
struct vco vco; struct vco vco;
...@@ -93,6 +93,8 @@ static void integrator_verify_speed(struct cpufreq_policy *policy) ...@@ -93,6 +93,8 @@ static void integrator_verify_speed(struct cpufreq_policy *policy)
vco.vdw = 152; vco.vdw = 152;
policy->min = policy->max = vco_to_freq(vco, 1); policy->min = policy->max = vco_to_freq(vco, 1);
return 0;
} }
static void do_set_policy(int cpu, struct cpufreq_policy *policy) static void do_set_policy(int cpu, struct cpufreq_policy *policy)
...@@ -116,7 +118,7 @@ static void do_set_policy(int cpu, struct cpufreq_policy *policy) ...@@ -116,7 +118,7 @@ static void do_set_policy(int cpu, struct cpufreq_policy *policy)
__raw_writel(0, CM_LOCK); __raw_writel(0, CM_LOCK);
} }
static void integrator_set_policy(struct cpufreq_policy *policy) static int integrator_set_policy(struct cpufreq_policy *policy)
{ {
unsigned long cpus_allowed; unsigned long cpus_allowed;
int cpu; int cpu;
...@@ -139,6 +141,8 @@ static void integrator_set_policy(struct cpufreq_policy *policy) ...@@ -139,6 +141,8 @@ static void integrator_set_policy(struct cpufreq_policy *policy)
* Restore the CPUs allowed mask. * Restore the CPUs allowed mask.
*/ */
set_cpus_allowed(current, cpus_allowed); set_cpus_allowed(current, cpus_allowed);
return 0;
} }
static struct cpufreq_policy integrator_policy = { static struct cpufreq_policy integrator_policy = {
...@@ -151,7 +155,6 @@ static struct cpufreq_driver integrator_driver = { ...@@ -151,7 +155,6 @@ static struct cpufreq_driver integrator_driver = {
.verify = integrator_verify_speed, .verify = integrator_verify_speed,
.setpolicy = integrator_set_policy, .setpolicy = integrator_set_policy,
.policy = &integrator_policy, .policy = &integrator_policy,
.cpu_min_freq = 12000,
}; };
#endif #endif
...@@ -202,6 +205,8 @@ static int __init integrator_cpu_init(void) ...@@ -202,6 +205,8 @@ static int __init integrator_cpu_init(void)
set_cpus_allowed(current, cpus_allowed); set_cpus_allowed(current, cpus_allowed);
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
for (cpu=0; cpu<NR_CPUS; cpu++)
integrator_driver.cpu_min_freq[cpu] = 12000;
integrator_driver.policy = policies; integrator_driver.policy = policies;
cpufreq_register(&integrator_driver); cpufreq_register(&integrator_driver);
#else #else
......
...@@ -176,7 +176,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed) ...@@ -176,7 +176,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
} }
} }
static void sa1100_setspeed(struct cpufreq_policy *policy) static int sa1100_setspeed(struct cpufreq_policy *policy)
{ {
unsigned int cur = sa11x0_getspeed(); unsigned int cur = sa11x0_getspeed();
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
...@@ -196,6 +196,8 @@ static void sa1100_setspeed(struct cpufreq_policy *policy) ...@@ -196,6 +196,8 @@ static void sa1100_setspeed(struct cpufreq_policy *policy)
sa1100_update_dram_timings(cur, policy->max); sa1100_update_dram_timings(cur, policy->max);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
} }
static struct cpufreq_policy sa1100_policy = { static struct cpufreq_policy sa1100_policy = {
...@@ -208,7 +210,7 @@ static struct cpufreq_driver sa1100_driver = { ...@@ -208,7 +210,7 @@ static struct cpufreq_driver sa1100_driver = {
.verify = sa11x0_verify_speed, .verify = sa11x0_verify_speed,
.setpolicy = sa1100_setspeed, .setpolicy = sa1100_setspeed,
.policy = &sa1100_policy, .policy = &sa1100_policy,
.cpu_min_freq = 59000, .cpu_min_freq[0]= 59000,
}; };
static int __init sa1100_dram_init(void) static int __init sa1100_dram_init(void)
...@@ -216,7 +218,7 @@ static int __init sa1100_dram_init(void) ...@@ -216,7 +218,7 @@ static int __init sa1100_dram_init(void)
int ret = -ENODEV; int ret = -ENODEV;
if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) { if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
sa1100_driver.cpu_curr_freq[0] = sa1100_driver.cpu_cur_freq[0] =
sa1100_policy.min = sa1100_policy.min =
sa1100_policy.max = sa11x0_getspeed(); sa1100_policy.max = sa11x0_getspeed();
......
...@@ -212,7 +212,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) ...@@ -212,7 +212,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
* above, we can match for an exact frequency. If we don't find * above, we can match for an exact frequency. If we don't find
* an exact match, we will to set the lowest frequency to be safe. * an exact match, we will to set the lowest frequency to be safe.
*/ */
static void sa1110_setspeed(struct cpufreq_policy *policy) static int sa1110_setspeed(struct cpufreq_policy *policy)
{ {
struct sdram_params *sdram = &sdram_params; struct sdram_params *sdram = &sdram_params;
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
...@@ -291,6 +291,8 @@ static void sa1110_setspeed(struct cpufreq_policy *policy) ...@@ -291,6 +291,8 @@ static void sa1110_setspeed(struct cpufreq_policy *policy)
sdram_update_refresh(policy->max, sdram); sdram_update_refresh(policy->max, sdram);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
} }
static struct cpufreq_policy sa1110_policy = { static struct cpufreq_policy sa1110_policy = {
...@@ -300,10 +302,10 @@ static struct cpufreq_policy sa1110_policy = { ...@@ -300,10 +302,10 @@ static struct cpufreq_policy sa1110_policy = {
}; };
static struct cpufreq_driver sa1110_driver = { static struct cpufreq_driver sa1110_driver = {
.verify = sa11x0_verify_speed, .verify = sa11x0_verify_speed,
.setpolicy = sa1110_setspeed, .setpolicy = sa1110_setspeed,
.policy = &sa1110_policy, .policy = &sa1110_policy,
.cpu_min_freq = 59000, .cpu_min_freq[0] = 59000,
}; };
static int __init sa1110_clk_init(void) static int __init sa1110_clk_init(void)
......
...@@ -67,7 +67,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz) ...@@ -67,7 +67,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
* scaling, so we force min=max, and set the policy to "performance". * scaling, so we force min=max, and set the policy to "performance".
* If we can't generate the precise frequency requested, round it up. * If we can't generate the precise frequency requested, round it up.
*/ */
void sa11x0_verify_speed(struct cpufreq_policy *policy) int sa11x0_verify_speed(struct cpufreq_policy *policy)
{ {
if (policy->max > policy->max_cpu_freq) if (policy->max > policy->max_cpu_freq)
policy->max = policy->max_cpu_freq; policy->max = policy->max_cpu_freq;
...@@ -75,6 +75,7 @@ void sa11x0_verify_speed(struct cpufreq_policy *policy) ...@@ -75,6 +75,7 @@ void sa11x0_verify_speed(struct cpufreq_policy *policy)
policy->max = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->max)] * 100; policy->max = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->max)] * 100;
policy->min = policy->max; policy->min = policy->max;
policy->policy = CPUFREQ_POLICY_POWERSAVE; policy->policy = CPUFREQ_POLICY_POWERSAVE;
return 0;
} }
unsigned int sa11x0_getspeed(void) unsigned int sa11x0_getspeed(void)
......
...@@ -172,13 +172,13 @@ static void elanfreq_set_cpu_state (unsigned int state) { ...@@ -172,13 +172,13 @@ static void elanfreq_set_cpu_state (unsigned int state) {
* for the hardware supported by the driver. * for the hardware supported by the driver.
*/ */
static void elanfreq_verify (struct cpufreq_policy *policy) static int elanfreq_verify (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
if (!policy || !max_freq) if (!policy || !max_freq)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
...@@ -190,7 +190,7 @@ static void elanfreq_verify (struct cpufreq_policy *policy) ...@@ -190,7 +190,7 @@ static void elanfreq_verify (struct cpufreq_policy *policy)
number_states++; number_states++;
if (number_states) if (number_states)
return; return 0;
for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--) for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--)
if (elan_multiplier[i].clock < policy->max) if (elan_multiplier[i].clock < policy->max)
...@@ -198,16 +198,16 @@ static void elanfreq_verify (struct cpufreq_policy *policy) ...@@ -198,16 +198,16 @@ static void elanfreq_verify (struct cpufreq_policy *policy)
policy->max = elan_multiplier[i+1].clock; policy->max = elan_multiplier[i+1].clock;
return; return 0;
} }
static void elanfreq_setpolicy (struct cpufreq_policy *policy) static int elanfreq_setpolicy (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i, j=4; unsigned int i, j=4;
if (!elanfreq_driver) if (!elanfreq_driver)
return; return -EINVAL;
for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--) for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--)
if ((elan_multiplier[i].clock >= policy->min) && if ((elan_multiplier[i].clock >= policy->min) &&
...@@ -219,7 +219,7 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy) ...@@ -219,7 +219,7 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy)
if (number_states == 1) { if (number_states == 1) {
elanfreq_set_cpu_state(j); elanfreq_set_cpu_state(j);
return; return 0;
} }
switch (policy->policy) { switch (policy->policy) {
...@@ -236,14 +236,14 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy) ...@@ -236,14 +236,14 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy)
j = i; j = i;
break; break;
default: default:
return; return -EINVAL;
} }
if (elan_multiplier[j].clock > max_freq) if (elan_multiplier[j].clock > max_freq)
BUG(); return -EINVAL;
elanfreq_set_cpu_state(j); elanfreq_set_cpu_state(j);
return; return 0;
} }
...@@ -296,7 +296,7 @@ static int __init elanfreq_init(void) ...@@ -296,7 +296,7 @@ static int __init elanfreq_init(void)
max_freq = elanfreq_get_cpu_frequency(); max_freq = elanfreq_get_cpu_frequency();
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = 1000; driver->cpu_min_freq[0] = 1000;
driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency(); driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency();
#endif #endif
...@@ -309,15 +309,15 @@ static int __init elanfreq_init(void) ...@@ -309,15 +309,15 @@ static int __init elanfreq_init(void)
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].max_cpu_freq = max_freq; driver->policy[0].max_cpu_freq = max_freq;
elanfreq_driver = driver;
ret = cpufreq_register(driver); ret = cpufreq_register(driver);
if (ret) { if (ret) {
elanfreq_driver = NULL;
kfree(driver); kfree(driver);
return ret;
} }
elanfreq_driver = driver; return ret;
return 0;
} }
......
/* /*
* $Id: longhaul.c,v 1.72 2002/09/29 23:43:10 db Exp $ * $Id: longhaul.c,v 1.77 2002/10/31 21:17:40 db Exp $
* *
* (C) 2001 Dave Jones. <davej@suse.de> * (C) 2001 Dave Jones. <davej@suse.de>
* (C) 2002 Padraig Brady. <padraig@antefacto.com> * (C) 2002 Padraig Brady. <padraig@antefacto.com>
...@@ -436,8 +436,10 @@ static void __init longhaul_get_ranges (void) ...@@ -436,8 +436,10 @@ static void __init longhaul_get_ranges (void)
switch (longhaul) { switch (longhaul) {
case 1: case 1:
/* Ugh, Longhaul v1 didn't have the min/max MSRs. /* Ugh, Longhaul v1 didn't have the min/max MSRs.
Assume max = whatever we booted at. */ Assume min=3.0x & max = whatever we booted at. */
minmult = 30;
maxmult = longhaul_get_cpu_mult(); maxmult = longhaul_get_cpu_mult();
minfsb = maxfsb = current_fsb;
break; break;
case 2 ... 3: case 2 ... 3:
...@@ -531,7 +533,7 @@ static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy ...@@ -531,7 +533,7 @@ static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy
} }
static void longhaul_verify(struct cpufreq_policy *policy) static int longhaul_verify(struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
...@@ -540,7 +542,7 @@ static void longhaul_verify(struct cpufreq_policy *policy) ...@@ -540,7 +542,7 @@ static void longhaul_verify(struct cpufreq_policy *policy)
unsigned int newmax = -1; unsigned int newmax = -1;
if (!policy || !longhaul_driver) if (!policy || !longhaul_driver)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
cpufreq_verify_within_limits(policy, lowest_speed, highest_speed); cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
...@@ -552,7 +554,7 @@ static void longhaul_verify(struct cpufreq_policy *policy) ...@@ -552,7 +554,7 @@ static void longhaul_verify(struct cpufreq_policy *policy)
number_states = longhaul_statecount_fsb(policy, current_fsb); number_states = longhaul_statecount_fsb(policy, current_fsb);
if (number_states) if (number_states)
return; return 0;
/* get frequency closest above current policy->max */ /* get frequency closest above current policy->max */
if (can_scale_fsb==1) { if (can_scale_fsb==1) {
...@@ -579,10 +581,12 @@ static void longhaul_verify(struct cpufreq_policy *policy) ...@@ -579,10 +581,12 @@ static void longhaul_verify(struct cpufreq_policy *policy)
} }
policy->max = newmax; policy->max = newmax;
return 0;
} }
static void longhaul_setpolicy (struct cpufreq_policy *policy) static int longhaul_setpolicy (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
...@@ -592,7 +596,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy) ...@@ -592,7 +596,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
unsigned int best_freq = -1; unsigned int best_freq = -1;
if (!longhaul_driver) if (!longhaul_driver)
return; return -EINVAL;
if (policy->policy==CPUFREQ_POLICY_PERFORMANCE) if (policy->policy==CPUFREQ_POLICY_PERFORMANCE)
fsb_search_table = perf_fsb_table; fsb_search_table = perf_fsb_table;
...@@ -613,7 +617,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy) ...@@ -613,7 +617,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
} }
if (!number_states) if (!number_states)
return; return -EINVAL;
else if (number_states == 1) { else if (number_states == 1) {
for(i=0; i<numscales; i++) { for(i=0; i<numscales; i++) {
if ((clock_ratio[i] != -1) && if ((clock_ratio[i] != -1) &&
...@@ -692,11 +696,11 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy) ...@@ -692,11 +696,11 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
} }
break; break;
default: default:
return; return -EINVAL;
} }
longhaul_setstate(new_clock_ratio, new_fsb); longhaul_setstate(new_clock_ratio, new_fsb);
return; return 0;
} }
...@@ -775,7 +779,7 @@ static int __init longhaul_init (void) ...@@ -775,7 +779,7 @@ static int __init longhaul_init (void)
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = (unsigned int) lowest_speed; driver->cpu_min_freq[0] = (unsigned int) lowest_speed;
driver->cpu_cur_freq[0] = currentspeed; driver->cpu_cur_freq[0] = currentspeed;
#endif #endif
...@@ -788,15 +792,15 @@ static int __init longhaul_init (void) ...@@ -788,15 +792,15 @@ static int __init longhaul_init (void)
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].max_cpu_freq = (unsigned int) highest_speed; driver->policy[0].max_cpu_freq = (unsigned int) highest_speed;
ret = cpufreq_register(driver); longhaul_driver = driver;
ret = cpufreq_register(driver);
if (ret) { if (ret) {
longhaul_driver = NULL;
kfree(driver); kfree(driver);
return ret;
} }
longhaul_driver = driver; return ret;
return 0;
} }
......
/* /*
* $Id: longrun.c,v 1.12 2002/09/29 23:43:10 db Exp $ * $Id: longrun.c,v 1.14 2002/10/31 21:17:40 db Exp $
* *
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
* *
...@@ -67,13 +67,13 @@ static void longrun_get_policy(struct cpufreq_policy *policy) ...@@ -67,13 +67,13 @@ static void longrun_get_policy(struct cpufreq_policy *policy)
* Sets a new CPUFreq policy on LongRun-capable processors. This function * Sets a new CPUFreq policy on LongRun-capable processors. This function
* has to be called with cpufreq_driver locked. * has to be called with cpufreq_driver locked.
*/ */
static void longrun_set_policy(struct cpufreq_policy *policy) static int longrun_set_policy(struct cpufreq_policy *policy)
{ {
u32 msr_lo, msr_hi; u32 msr_lo, msr_hi;
u32 pctg_lo, pctg_hi; u32 pctg_lo, pctg_hi;
if (!longrun_driver || !policy) if (!longrun_driver || !policy)
return; return -EINVAL;
pctg_lo = (policy->min - longrun_low_freq) / pctg_lo = (policy->min - longrun_low_freq) /
((longrun_high_freq - longrun_low_freq) / 100); ((longrun_high_freq - longrun_low_freq) / 100);
...@@ -105,7 +105,7 @@ static void longrun_set_policy(struct cpufreq_policy *policy) ...@@ -105,7 +105,7 @@ static void longrun_set_policy(struct cpufreq_policy *policy)
msr_hi |= pctg_hi; msr_hi |= pctg_hi;
wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
return; return 0;
} }
...@@ -115,16 +115,16 @@ static void longrun_set_policy(struct cpufreq_policy *policy) ...@@ -115,16 +115,16 @@ static void longrun_set_policy(struct cpufreq_policy *policy)
* Validates a new CPUFreq policy. This function has to be called with * Validates a new CPUFreq policy. This function has to be called with
* cpufreq_driver locked. * cpufreq_driver locked.
*/ */
static void longrun_verify_policy(struct cpufreq_policy *policy) static int longrun_verify_policy(struct cpufreq_policy *policy)
{ {
if (!policy || !longrun_driver) if (!policy || !longrun_driver)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
cpufreq_verify_within_limits(policy, 0, cpufreq_verify_within_limits(policy, 0,
longrun_driver->policy[0].max_cpu_freq); longrun_driver->policy[0].max_cpu_freq);
return; return 0;
} }
...@@ -252,20 +252,22 @@ static int __init longrun_init(void) ...@@ -252,20 +252,22 @@ static int __init longrun_init(void)
longrun_get_policy(&driver->policy[0]); longrun_get_policy(&driver->policy[0]);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = longrun_low_freq; driver->cpu_min_freq[0] = longrun_low_freq;
driver->cpu_cur_freq[0] = longrun_high_freq; /* dummy value */ driver->cpu_cur_freq[0] = longrun_high_freq; /* dummy value */
#endif #endif
driver->verify = &longrun_verify_policy; driver->verify = &longrun_verify_policy;
driver->setpolicy = &longrun_set_policy; driver->setpolicy = &longrun_set_policy;
longrun_driver = driver;
result = cpufreq_register(driver); result = cpufreq_register(driver);
if (result) { if (result) {
longrun_driver = NULL;
kfree(driver); kfree(driver);
return result;
} }
longrun_driver = driver;
return 0; return result;
} }
......
...@@ -78,7 +78,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) ...@@ -78,7 +78,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
} }
#endif #endif
set_cpus_allowed(current, affected_cpu_map); set_cpus_allowed(current, affected_cpu_map);
BUG_ON(!(smp_processor_id() & affected_cpu_map)); BUG_ON(!(affected_cpu_map & (1 << smp_processor_id())));
/* get current state */ /* get current state */
rdmsr(MSR_IA32_THERM_CONTROL, l, h); rdmsr(MSR_IA32_THERM_CONTROL, l, h);
...@@ -136,14 +136,14 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) ...@@ -136,14 +136,14 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
} }
static void cpufreq_p4_setpolicy(struct cpufreq_policy *policy) static int cpufreq_p4_setpolicy(struct cpufreq_policy *policy)
{ {
unsigned int i; unsigned int i;
unsigned int newstate = 0; unsigned int newstate = 0;
unsigned int number_states = 0; unsigned int number_states = 0;
if (!cpufreq_p4_driver || !stock_freq || !policy) if (!cpufreq_p4_driver || !stock_freq || !policy)
return; return -EINVAL;
if (policy->policy == CPUFREQ_POLICY_POWERSAVE) if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
{ {
...@@ -183,16 +183,17 @@ static void cpufreq_p4_setpolicy(struct cpufreq_policy *policy) ...@@ -183,16 +183,17 @@ static void cpufreq_p4_setpolicy(struct cpufreq_policy *policy)
min_state = newstate - (number_states - 1); min_state = newstate - (number_states - 1);
} }
} */ } */
return 0;
} }
static void cpufreq_p4_verify(struct cpufreq_policy *policy) static int cpufreq_p4_verify(struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i; unsigned int i;
if (!cpufreq_p4_driver || !stock_freq || !policy) if (!cpufreq_p4_driver || !stock_freq || !policy)
return; return -EINVAL;
if (!cpu_online(policy->cpu)) if (!cpu_online(policy->cpu))
policy->cpu = CPUFREQ_ALL_CPUS; policy->cpu = CPUFREQ_ALL_CPUS;
...@@ -205,10 +206,10 @@ static void cpufreq_p4_verify(struct cpufreq_policy *policy) ...@@ -205,10 +206,10 @@ static void cpufreq_p4_verify(struct cpufreq_policy *policy)
number_states++; number_states++;
if (number_states) if (number_states)
return; return 0;
policy->max = (stock_freq / 8) * (((unsigned int) ((policy->max * 8) / stock_freq)) + 1); policy->max = (stock_freq / 8) * (((unsigned int) ((policy->max * 8) / stock_freq)) + 1);
return; return 0;
} }
...@@ -255,9 +256,10 @@ int __init cpufreq_p4_init(void) ...@@ -255,9 +256,10 @@ int __init cpufreq_p4_init(void)
stock_freq = cpu_khz; stock_freq = cpu_khz;
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = stock_freq / 8; for (i=0;i<NR_CPUS;i++) {
for (i=0;i<NR_CPUS;i++) driver->cpu_min_freq[i] = stock_freq / 8;
driver->cpu_cur_freq[i] = stock_freq; driver->cpu_cur_freq[i] = stock_freq;
}
#endif #endif
driver->verify = &cpufreq_p4_verify; driver->verify = &cpufreq_p4_verify;
...@@ -274,15 +276,15 @@ int __init cpufreq_p4_init(void) ...@@ -274,15 +276,15 @@ int __init cpufreq_p4_init(void)
driver->policy[i].cpu = i; driver->policy[i].cpu = i;
} }
cpufreq_p4_driver = driver;
ret = cpufreq_register(driver); ret = cpufreq_register(driver);
if (ret) { if (ret) {
cpufreq_p4_driver = NULL;
kfree(driver); kfree(driver);
return ret;
} }
cpufreq_p4_driver = driver; return ret;
return 0;
} }
......
/* /*
* $Id: powernow-k6.c,v 1.33 2002/09/29 23:43:11 db Exp $ * $Id: powernow-k6.c,v 1.36 2002/10/31 21:17:40 db Exp $
* This file was part of Powertweak Linux (http://powertweak.sf.net) * This file was part of Powertweak Linux (http://powertweak.sf.net)
* and is shared with the Linux Kernel module. * and is shared with the Linux Kernel module.
* *
...@@ -113,13 +113,13 @@ static void powernow_k6_set_state (unsigned int best_i) ...@@ -113,13 +113,13 @@ static void powernow_k6_set_state (unsigned int best_i)
* Policy must be within lowest and highest possible CPU Frequency, * Policy must be within lowest and highest possible CPU Frequency,
* and at least one possible state must be within min and max. * and at least one possible state must be within min and max.
*/ */
static void powernow_k6_verify(struct cpufreq_policy *policy) static int powernow_k6_verify(struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i, j; unsigned int i, j;
if (!policy || !busfreq) if (!policy || !busfreq)
return; return -EINVAL;
policy->cpu = 0; policy->cpu = 0;
cpufreq_verify_within_limits(policy, (20 * busfreq), cpufreq_verify_within_limits(policy, (20 * busfreq),
...@@ -131,7 +131,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy) ...@@ -131,7 +131,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
number_states++; number_states++;
if (number_states) if (number_states)
return; return 0;
/* no state is available within range -- find next larger state */ /* no state is available within range -- find next larger state */
...@@ -144,7 +144,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy) ...@@ -144,7 +144,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
policy->max = clock_ratio[j] * busfreq; policy->max = clock_ratio[j] * busfreq;
return; return 0;
} }
...@@ -154,13 +154,13 @@ static void powernow_k6_verify(struct cpufreq_policy *policy) ...@@ -154,13 +154,13 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
* *
* sets a new CPUFreq policy * sets a new CPUFreq policy
*/ */
static void powernow_k6_setpolicy (struct cpufreq_policy *policy) static int powernow_k6_setpolicy (struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; unsigned int number_states = 0;
unsigned int i, j=4; unsigned int i, j=4;
if (!powernow_driver) if (!powernow_driver)
return; return -EINVAL;
for (i=0; i<8; i++) for (i=0; i<8; i++)
if ((policy->min <= (busfreq * clock_ratio[i])) && if ((policy->min <= (busfreq * clock_ratio[i])) &&
...@@ -174,7 +174,7 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy) ...@@ -174,7 +174,7 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy)
/* if only one state is within the limit borders, it /* if only one state is within the limit borders, it
is easily detected and set */ is easily detected and set */
powernow_k6_set_state(j); powernow_k6_set_state(j);
return; return 0;
} }
/* more than one state within limit */ /* more than one state within limit */
...@@ -196,14 +196,14 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy) ...@@ -196,14 +196,14 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy)
j = i; j = i;
break; break;
default: default:
return; return -EINVAL;
} }
if (clock_ratio[i] > max_multiplier) if (clock_ratio[i] > max_multiplier)
BUG(); return -EINVAL;
powernow_k6_set_state(j); powernow_k6_set_state(j);
return; return 0;
} }
...@@ -242,7 +242,7 @@ static int __init powernow_k6_init(void) ...@@ -242,7 +242,7 @@ static int __init powernow_k6_init(void)
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = busfreq * 20; driver->cpu_min_freq[0] = busfreq * 20;
driver->cpu_cur_freq[0] = busfreq * max_multiplier; driver->cpu_cur_freq[0] = busfreq * max_multiplier;
#endif #endif
...@@ -255,16 +255,16 @@ static int __init powernow_k6_init(void) ...@@ -255,16 +255,16 @@ static int __init powernow_k6_init(void)
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE; driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].max_cpu_freq = busfreq * max_multiplier; driver->policy[0].max_cpu_freq = busfreq * max_multiplier;
powernow_driver = driver;
result = cpufreq_register(driver); result = cpufreq_register(driver);
if (result) { if (result) {
release_region (POWERNOW_IOPORT, 16); release_region (POWERNOW_IOPORT, 16);
powernow_driver = NULL;
kfree(driver); kfree(driver);
return result;
} }
powernow_driver = driver;
return 0; return result;
} }
......
/* /*
* $Id: speedstep.c,v 1.57 2002/11/05 12:01:12 db Exp $ * $Id: speedstep.c,v 1.58 2002/11/11 15:35:46 db Exp $
* *
* (C) 2001 Dave Jones, Arjan van de ven. * (C) 2001 Dave Jones, Arjan van de ven.
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
...@@ -567,10 +567,10 @@ static int speedstep_detect_speeds (void) ...@@ -567,10 +567,10 @@ static int speedstep_detect_speeds (void)
* *
* Sets a new CPUFreq policy. * Sets a new CPUFreq policy.
*/ */
static void speedstep_setpolicy (struct cpufreq_policy *policy) static int speedstep_setpolicy (struct cpufreq_policy *policy)
{ {
if (!speedstep_driver || !policy) if (!speedstep_driver || !policy)
return; return -EINVAL;
if (policy->min > speedstep_low_freq) if (policy->min > speedstep_low_freq)
speedstep_set_state(SPEEDSTEP_HIGH, 1); speedstep_set_state(SPEEDSTEP_HIGH, 1);
...@@ -585,6 +585,7 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy) ...@@ -585,6 +585,7 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy)
speedstep_set_state(SPEEDSTEP_HIGH, 1); speedstep_set_state(SPEEDSTEP_HIGH, 1);
} }
} }
return 0;
} }
...@@ -595,11 +596,11 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy) ...@@ -595,11 +596,11 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy)
* Limit must be within speedstep_low_freq and speedstep_high_freq, with * Limit must be within speedstep_low_freq and speedstep_high_freq, with
* at least one border included. * at least one border included.
*/ */
static void speedstep_verify (struct cpufreq_policy *policy) static int speedstep_verify (struct cpufreq_policy *policy)
{ {
if (!policy || !speedstep_driver || if (!policy || !speedstep_driver ||
!speedstep_low_freq || !speedstep_high_freq) !speedstep_low_freq || !speedstep_high_freq)
return; return -EINVAL;
policy->cpu = 0; /* UP only */ policy->cpu = 0; /* UP only */
...@@ -609,7 +610,7 @@ static void speedstep_verify (struct cpufreq_policy *policy) ...@@ -609,7 +610,7 @@ static void speedstep_verify (struct cpufreq_policy *policy)
(policy->max < speedstep_high_freq)) (policy->max < speedstep_high_freq))
policy->max = speedstep_high_freq; policy->max = speedstep_high_freq;
return; return 0;
} }
...@@ -654,12 +655,11 @@ static int __init speedstep_init(void) ...@@ -654,12 +655,11 @@ static int __init speedstep_init(void)
speedstep_processor = speedstep_detect_processor(); speedstep_processor = speedstep_detect_processor();
if ((!speedstep_chipset) || (!speedstep_processor)) { if ((!speedstep_chipset) || (!speedstep_processor)) {
printk(KERN_INFO "a 0x%x b 0x%x\n", speedstep_processor, speedstep_chipset);
printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this %s not (yet) available.\n", speedstep_chipset ? "processor" : "chipset"); printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this %s not (yet) available.\n", speedstep_chipset ? "processor" : "chipset");
return -ENODEV; return -ENODEV;
} }
dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.57 $\n"); dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.58 $\n");
dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n", dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n",
speedstep_chipset, speedstep_processor); speedstep_chipset, speedstep_processor);
...@@ -693,7 +693,7 @@ static int __init speedstep_init(void) ...@@ -693,7 +693,7 @@ static int __init speedstep_init(void)
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = speedstep_low_freq; driver->cpu_min_freq[0] = speedstep_low_freq;
driver->cpu_cur_freq[0] = speed; driver->cpu_cur_freq[0] = speed;
#endif #endif
...@@ -707,14 +707,15 @@ static int __init speedstep_init(void) ...@@ -707,14 +707,15 @@ static int __init speedstep_init(void)
driver->policy[0].policy = (speed == speedstep_low_freq) ? driver->policy[0].policy = (speed == speedstep_low_freq) ?
CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE; CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
speedstep_driver = driver;
result = cpufreq_register(driver); result = cpufreq_register(driver);
if (result) { if (result) {
speedstep_driver = NULL;
kfree(driver); kfree(driver);
return result;
} }
speedstep_driver = driver;
return 0; return result;
} }
......
...@@ -1613,7 +1613,7 @@ acpi_processor_get_limit_info ( ...@@ -1613,7 +1613,7 @@ acpi_processor_get_limit_info (
cpufreq interface cpufreq interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCESSOR_PERF #ifdef CONFIG_ACPI_PROCESSOR_PERF
static void static int
acpi_cpufreq_setpolicy ( acpi_cpufreq_setpolicy (
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
{ {
...@@ -1626,7 +1626,7 @@ acpi_cpufreq_setpolicy ( ...@@ -1626,7 +1626,7 @@ acpi_cpufreq_setpolicy (
ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy"); ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
if (!policy) if (!policy)
return_VOID; return_VALUE(-EINVAL);
/* get a present, initialized CPU */ /* get a present, initialized CPU */
if (policy->cpu == CPUFREQ_ALL_CPUS) if (policy->cpu == CPUFREQ_ALL_CPUS)
...@@ -1644,7 +1644,7 @@ acpi_cpufreq_setpolicy ( ...@@ -1644,7 +1644,7 @@ acpi_cpufreq_setpolicy (
cpu = policy->cpu; cpu = policy->cpu;
pr = processors[cpu]; pr = processors[cpu];
if (!pr) if (!pr)
return_VOID; return_VALUE(-EINVAL);
} }
/* select appropriate P-State */ /* select appropriate P-State */
...@@ -1686,11 +1686,11 @@ acpi_cpufreq_setpolicy ( ...@@ -1686,11 +1686,11 @@ acpi_cpufreq_setpolicy (
result = acpi_processor_set_performance (pr, next_state); result = acpi_processor_set_performance (pr, next_state);
} }
return_VOID; return_VALUE(0);
} }
static void static int
acpi_cpufreq_verify ( acpi_cpufreq_verify (
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
{ {
...@@ -1703,7 +1703,7 @@ acpi_cpufreq_verify ( ...@@ -1703,7 +1703,7 @@ acpi_cpufreq_verify (
ACPI_FUNCTION_TRACE("acpi_cpufreq_verify"); ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
if (!policy) if (!policy)
return_VOID; return_VALUE(-EINVAL);
/* get a present, initialized CPU */ /* get a present, initialized CPU */
if (policy->cpu == CPUFREQ_ALL_CPUS) if (policy->cpu == CPUFREQ_ALL_CPUS)
...@@ -1721,7 +1721,7 @@ acpi_cpufreq_verify ( ...@@ -1721,7 +1721,7 @@ acpi_cpufreq_verify (
cpu = policy->cpu; cpu = policy->cpu;
pr = processors[cpu]; pr = processors[cpu];
if (!pr) if (!pr)
return_VOID; return_VALUE(-EINVAL);
} }
/* first check if min and max are within valid limits */ /* first check if min and max are within valid limits */
...@@ -1741,13 +1741,12 @@ acpi_cpufreq_verify ( ...@@ -1741,13 +1741,12 @@ acpi_cpufreq_verify (
next_larger_state = i; next_larger_state = i;
} }
if (number_states) if (!number_states) {
return_VOID; /* round up now */
policy->max = pr->performance.states[next_larger_state].core_frequency * 1000;
/* round up now */ }
policy->max = pr->performance.states[next_larger_state].core_frequency * 1000;
return_VOID; return_VALUE(0);
} }
static int static int
...@@ -1807,9 +1806,10 @@ acpi_cpufreq_init ( ...@@ -1807,9 +1806,10 @@ acpi_cpufreq_init (
driver->policy = (struct cpufreq_policy *) (driver + 1); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000; for (i=0;i<NR_CPUS;i++) {
for (i=0;i<NR_CPUS;i++)
driver->cpu_cur_freq[0] = pr->performance.states[current_state].core_frequency * 1000; driver->cpu_cur_freq[0] = pr->performance.states[current_state].core_frequency * 1000;
driver->cpu_min_freq[0] = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000;
}
#endif #endif
driver->verify = &acpi_cpufreq_verify; driver->verify = &acpi_cpufreq_verify;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
* *
* *
* $Id: cpufreq.h,v 1.27 2002/10/08 14:54:23 db Exp $ * $Id: cpufreq.h,v 1.29 2002/11/11 15:35:47 db Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -104,7 +104,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu ...@@ -104,7 +104,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu
* CPUFREQ DRIVER INTERFACE * * CPUFREQ DRIVER INTERFACE *
*********************************************************************/ *********************************************************************/
typedef void (*cpufreq_policy_t) (struct cpufreq_policy *policy); typedef int (*cpufreq_policy_t) (struct cpufreq_policy *policy);
struct cpufreq_driver { struct cpufreq_driver {
/* needed by all drivers */ /* needed by all drivers */
...@@ -116,7 +116,7 @@ struct cpufreq_driver { ...@@ -116,7 +116,7 @@ struct cpufreq_driver {
#endif #endif
/* 2.4. compatible API */ /* 2.4. compatible API */
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
unsigned int cpu_min_freq; unsigned int cpu_min_freq[NR_CPUS];
unsigned int cpu_cur_freq[NR_CPUS]; unsigned int cpu_cur_freq[NR_CPUS];
#endif #endif
}; };
...@@ -205,19 +205,19 @@ enum { ...@@ -205,19 +205,19 @@ enum {
CPU_NR_FREQ = 3, CPU_NR_FREQ = 3,
}; };
#define CTL_CPU_VARS_SPEED_MAX { \ #define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
.ctl_name = CPU_NR_FREQ_MAX, \ .ctl_name = CPU_NR_FREQ_MAX, \
.data = &cpu_max_freq, \ .data = &cpu_max_freq[cpunr], \
.procname = "speed-max", \ .procname = "speed-max", \
.maxlen = sizeof(cpu_max_freq),\ .maxlen = sizeof(cpu_max_freq[cpunr]),\
.mode = 0444, \ .mode = 0444, \
.proc_handler = proc_dointvec, } .proc_handler = proc_dointvec, }
#define CTL_CPU_VARS_SPEED_MIN { \ #define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
.ctl_name = CPU_NR_FREQ_MIN, \ .ctl_name = CPU_NR_FREQ_MIN, \
.data = &cpu_min_freq, \ .data = &cpu_min_freq[cpunr], \
.procname = "speed-min", \ .procname = "speed-min", \
.maxlen = sizeof(cpu_min_freq),\ .maxlen = sizeof(cpu_min_freq[cpunr]),\
.mode = 0444, \ .mode = 0444, \
.proc_handler = proc_dointvec, } .proc_handler = proc_dointvec, }
...@@ -230,8 +230,8 @@ enum { ...@@ -230,8 +230,8 @@ enum {
.extra1 = (void*) (cpunr), } .extra1 = (void*) (cpunr), }
#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\ #define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
CTL_CPU_VARS_SPEED_MAX, \ CTL_CPU_VARS_SPEED_MAX(cpunr), \
CTL_CPU_VARS_SPEED_MIN, \ CTL_CPU_VARS_SPEED_MIN(cpunr), \
CTL_CPU_VARS_SPEED(cpunr), \ CTL_CPU_VARS_SPEED(cpunr), \
{ .ctl_name = 0, }, } { .ctl_name = 0, }, }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (C) 2001 Russell King * Copyright (C) 2001 Russell King
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
* *
* $Id: cpufreq.c,v 1.45 2002/10/08 14:54:23 db Exp $ * $Id: cpufreq.c,v 1.50 2002/11/11 15:35:48 db Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -69,8 +69,8 @@ static struct cpufreq_policy default_policy = { ...@@ -69,8 +69,8 @@ static struct cpufreq_policy default_policy = {
/** /**
* A few values needed by the 2.4.-compatible API * A few values needed by the 2.4.-compatible API
*/ */
static unsigned int cpu_max_freq; static unsigned int cpu_max_freq[NR_CPUS];
static unsigned int cpu_min_freq; static unsigned int cpu_min_freq[NR_CPUS];
static unsigned int cpu_cur_freq[NR_CPUS]; static unsigned int cpu_cur_freq[NR_CPUS];
#endif #endif
...@@ -228,6 +228,10 @@ static int cpufreq_proc_read ( ...@@ -228,6 +228,10 @@ static int cpufreq_proc_read (
continue; continue;
cpufreq_get_policy(&policy, i); cpufreq_get_policy(&policy, i);
if (!policy.max_cpu_freq)
continue;
min_pctg = (policy.min * 100) / policy.max_cpu_freq; min_pctg = (policy.min * 100) / policy.max_cpu_freq;
max_pctg = (policy.max * 100) / policy.max_cpu_freq; max_pctg = (policy.max * 100) / policy.max_cpu_freq;
...@@ -378,7 +382,7 @@ int cpufreq_setmax(unsigned int cpu) ...@@ -378,7 +382,7 @@ int cpufreq_setmax(unsigned int cpu)
{ {
if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS)) if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS))
return -EINVAL; return -EINVAL;
return cpufreq_set(cpu_max_freq, cpu); return cpufreq_set(cpu_max_freq[cpu], cpu);
} }
EXPORT_SYMBOL_GPL(cpufreq_setmax); EXPORT_SYMBOL_GPL(cpufreq_setmax);
...@@ -807,13 +811,14 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) ...@@ -807,13 +811,14 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
policy->min = cpufreq_driver->policy[cpu].min; policy->min = cpufreq_driver->policy[cpu].min;
policy->max = cpufreq_driver->policy[cpu].max; policy->max = cpufreq_driver->policy[cpu].max;
policy->policy = cpufreq_driver->policy[cpu].policy; policy->policy = cpufreq_driver->policy[cpu].policy;
policy->max_cpu_freq = cpufreq_driver->policy[0].max_cpu_freq; policy->max_cpu_freq = cpufreq_driver->policy[cpu].max_cpu_freq;
policy->cpu = cpu; policy->cpu = cpu;
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
return 0; return 0;
} }
EXPORT_SYMBOL(cpufreq_get_policy);
/** /**
...@@ -825,6 +830,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) ...@@ -825,6 +830,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
int cpufreq_set_policy(struct cpufreq_policy *policy) int cpufreq_set_policy(struct cpufreq_policy *policy)
{ {
unsigned int i; unsigned int i;
int ret;
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
if (!cpufreq_driver || !cpufreq_driver->verify || if (!cpufreq_driver || !cpufreq_driver->verify ||
...@@ -834,12 +840,20 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) ...@@ -834,12 +840,20 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
return -EINVAL; return -EINVAL;
} }
down(&cpufreq_notifier_sem); if (policy->cpu == CPUFREQ_ALL_CPUS)
policy->max_cpu_freq = cpufreq_driver->policy[0].max_cpu_freq;
else
policy->max_cpu_freq = cpufreq_driver->policy[policy->cpu].max_cpu_freq;
policy->max_cpu_freq = cpufreq_driver->policy[0].max_cpu_freq;
/* verify the cpu speed can be set within this limit */ /* verify the cpu speed can be set within this limit */
cpufreq_driver->verify(policy); ret = cpufreq_driver->verify(policy);
if (ret) {
up(&cpufreq_driver_sem);
return ret;
}
down(&cpufreq_notifier_sem);
/* adjust if neccessary - all reasons */ /* adjust if neccessary - all reasons */
notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST, notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST,
...@@ -851,7 +865,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) ...@@ -851,7 +865,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
/* verify the cpu speed can be set within this limit, /* verify the cpu speed can be set within this limit,
which might be different to the first one */ which might be different to the first one */
cpufreq_driver->verify(policy); ret = cpufreq_driver->verify(policy);
if (ret) {
up(&cpufreq_notifier_sem);
up(&cpufreq_driver_sem);
return ret;
}
/* notification of the new policy */ /* notification of the new policy */
notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY, notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY,
...@@ -879,11 +898,11 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) ...@@ -879,11 +898,11 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
cpu_cur_freq[policy->cpu] = policy->max; cpu_cur_freq[policy->cpu] = policy->max;
#endif #endif
cpufreq_driver->setpolicy(policy); ret = cpufreq_driver->setpolicy(policy);
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
return 0; return ret;
} }
EXPORT_SYMBOL(cpufreq_set_policy); EXPORT_SYMBOL(cpufreq_set_policy);
...@@ -968,6 +987,8 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition); ...@@ -968,6 +987,8 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
int cpufreq_register(struct cpufreq_driver *driver_data) int cpufreq_register(struct cpufreq_driver *driver_data)
{ {
unsigned int ret; unsigned int ret;
unsigned int i;
struct cpufreq_policy policy;
if (cpufreq_driver) if (cpufreq_driver)
return -EBUSY; return -EBUSY;
...@@ -979,41 +1000,55 @@ int cpufreq_register(struct cpufreq_driver *driver_data) ...@@ -979,41 +1000,55 @@ int cpufreq_register(struct cpufreq_driver *driver_data)
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
cpufreq_driver = driver_data; cpufreq_driver = driver_data;
if (!default_policy.policy) /* check for a default policy - if it exists, use it on _all_ CPUs*/
default_policy.policy = driver_data->policy[0].policy; for (i=0; i<NR_CPUS; i++)
if (!default_policy.min) {
default_policy.min = driver_data->policy[0].min; if (default_policy.policy)
if (!default_policy.max) cpufreq_driver->policy[i].policy = default_policy.policy;
default_policy.max = driver_data->policy[0].max; if (default_policy.min)
default_policy.cpu = CPUFREQ_ALL_CPUS; cpufreq_driver->policy[i].min = default_policy.min;
if (default_policy.max)
cpufreq_driver->policy[i].max = default_policy.max;
}
up(&cpufreq_driver_sem); /* set default policy on all CPUs. Must be called per-CPU and not
* with CPUFREQ_ALL_CPUs as there might be no common policy for all
* CPUs (UltraSPARC etc.)
*/
for (i=0; i<NR_CPUS; i++)
{
policy.policy = cpufreq_driver->policy[i].policy;
policy.min = cpufreq_driver->policy[i].min;
policy.max = cpufreq_driver->policy[i].max;
policy.cpu = i;
up(&cpufreq_driver_sem);
ret = cpufreq_set_policy(&policy);
down(&cpufreq_driver_sem);
if (ret) {
cpufreq_driver = NULL;
up(&cpufreq_driver_sem);
return ret;
}
}
ret = cpufreq_set_policy(&default_policy); up(&cpufreq_driver_sem);
cpufreq_proc_init(); cpufreq_proc_init();
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
cpu_min_freq = driver_data->cpu_min_freq; for (i=0; i<NR_CPUS; i++)
cpu_max_freq = driver_data->policy[0].max_cpu_freq;
{ {
unsigned int i; cpu_min_freq[i] = driver_data->cpu_min_freq[i];
for (i=0; i<NR_CPUS; i++) { cpu_max_freq[i] = driver_data->policy[i].max_cpu_freq;
cpu_cur_freq[i] = driver_data->cpu_cur_freq[i]; cpu_cur_freq[i] = driver_data->cpu_cur_freq[i];
}
} }
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
cpufreq_sysctl_init(); cpufreq_sysctl_init();
#endif #endif
if (ret) {
down(&cpufreq_driver_sem);
cpufreq_driver = NULL;
up(&cpufreq_driver_sem);
}
return ret; return 0;
} }
EXPORT_SYMBOL_GPL(cpufreq_register); EXPORT_SYMBOL_GPL(cpufreq_register);
...@@ -1061,6 +1096,7 @@ int cpufreq_restore(void) ...@@ -1061,6 +1096,7 @@ int cpufreq_restore(void)
{ {
struct cpufreq_policy policy; struct cpufreq_policy policy;
unsigned int i; unsigned int i;
unsigned int ret = 0;
if (in_interrupt()) if (in_interrupt())
panic("cpufreq_restore() called from interrupt context!"); panic("cpufreq_restore() called from interrupt context!");
...@@ -1081,10 +1117,10 @@ int cpufreq_restore(void) ...@@ -1081,10 +1117,10 @@ int cpufreq_restore(void)
policy.cpu = i; policy.cpu = i;
up(&cpufreq_driver_sem); up(&cpufreq_driver_sem);
cpufreq_set_policy(&policy); ret += cpufreq_set_policy(&policy);
} }
return 0; return ret;
} }
EXPORT_SYMBOL_GPL(cpufreq_restore); EXPORT_SYMBOL_GPL(cpufreq_restore);
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment