]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] cpufreq: cleanups
authorDominik Brodowski <linux@brodo.de>
Fri, 22 Nov 2002 03:06:16 +0000 (19:06 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Fri, 22 Nov 2002 03:06:16 +0000 (19:06 -0800)
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.

14 files changed:
Documentation/cpufreq
arch/arm/mach-integrator/cpu.c
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-sa1100/generic.c
arch/i386/kernel/cpu/cpufreq/elanfreq.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/longrun.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/powernow-k6.c
arch/i386/kernel/cpu/cpufreq/speedstep.c
drivers/acpi/processor.c
include/linux/cpufreq.h
kernel/cpufreq.c

index 3f5c8229cf1a9a65cae95fdfaac16f9f6b08f687..902c8558873aea25d7df1ae9c790b55926757132 100644 (file)
@@ -87,7 +87,8 @@ PowerNow! K6:
 Transmeta Crusoe Longrun:
     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:
 
 cpufreq_verify_t verify: This is a pointer to a function with the
        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
        supported by the CPU, and at least one supported CPU is within
        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
        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
        "dumb" CPU which only allows fixed frequencies to be set, it
        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
 
 struct cpufreq_policy   *policy: This is an array of NR_CPUS struct
        cpufreq_policies, containing the current policies set for these
-       CPUs. Note that policy[0].max_cpu_freq must contain the
-       absolute maximum CPU frequency supported by _all_ CPUs.
+       CPUs. Note that policy[cpu].max_cpu_freq must contain the
+       absolute maximum CPU frequency supported by the specified cpu.
 
 In case the driver is expected to run with the 2.4.-style API
 (/proc/sys/cpu/.../), two more values must be passed
 #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];
 #endif
-       with cpu_min_freq being the minimum CPU frequency supported by
-       the CPUs; and the entries in cpu_cur_freq reflecting the
-       current speed of the appropriate CPU.
+       with cpu_min_freq[cpu] being the minimum CPU frequency
+       supported by the CPU; and the entries in cpu_cur_freq
+       reflecting the current speed of the appropriate CPU.
 
 Some Requirements to CPUFreq architecture drivers
 -------------------------------------------------
 * 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
   been successfully(!) called before.
 * kfree() the struct cpufreq_driver only after the call to 
   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!
 
 
 
index 773955c92d14ef0ad6bdeba6740a2b02f77fc972..23a8788ef76e1fb9e6c2e396e4f78ee6e3c42004 100644 (file)
@@ -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
  * 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;
 
@@ -93,6 +93,8 @@ static void integrator_verify_speed(struct cpufreq_policy *policy)
                vco.vdw = 152;
 
        policy->min = policy->max = vco_to_freq(vco, 1);
+
+       return 0;
 }
 
 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);
 }
 
-static void integrator_set_policy(struct cpufreq_policy *policy)
+static int integrator_set_policy(struct cpufreq_policy *policy)
 {
        unsigned long cpus_allowed;
        int cpu;
@@ -139,6 +141,8 @@ static void integrator_set_policy(struct cpufreq_policy *policy)
         * Restore the CPUs allowed mask.
         */
        set_cpus_allowed(current, cpus_allowed);
+
+       return 0;
 }
 
 static struct cpufreq_policy integrator_policy = {
@@ -151,7 +155,6 @@ static struct cpufreq_driver integrator_driver = {
        .verify         = integrator_verify_speed,
        .setpolicy      = integrator_set_policy,
        .policy         = &integrator_policy,
-       .cpu_min_freq   = 12000,
 };
 #endif
 
@@ -202,6 +205,8 @@ static int __init integrator_cpu_init(void)
        set_cpus_allowed(current, cpus_allowed);
 
 #ifdef CONFIG_CPU_FREQ
+       for (cpu=0; cpu<NR_CPUS; cpu++)
+               integrator_driver.cpu_min_freq[cpu] = 12000;
        integrator_driver.policy = policies;
        cpufreq_register(&integrator_driver);
 #else
index 64295a0fbe562bc0cb3762c454cf436416f2d70c..0268144875d720801dff5fc79d26a30c7a8c8071 100644 (file)
@@ -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();
        struct cpufreq_freqs freqs;
@@ -196,6 +196,8 @@ static void sa1100_setspeed(struct cpufreq_policy *policy)
                sa1100_update_dram_timings(cur, policy->max);
 
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+       return 0;
 }
 
 static struct cpufreq_policy sa1100_policy = {
@@ -208,7 +210,7 @@ static struct cpufreq_driver sa1100_driver = {
        .verify         = sa11x0_verify_speed,
        .setpolicy      = sa1100_setspeed,
        .policy         = &sa1100_policy,
-       .cpu_min_freq   = 59000,
+       .cpu_min_freq[0]= 59000,
 };
 
 static int __init sa1100_dram_init(void)
@@ -216,7 +218,7 @@ static int __init sa1100_dram_init(void)
        int ret = -ENODEV;
 
        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.max = sa11x0_getspeed();
 
index ee0b097fc2a839674737338cc1449a62b1897008..69223d1daa2f1553323226ba4de161da70a4cf23 100644 (file)
@@ -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
  * 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 cpufreq_freqs freqs;
@@ -291,6 +291,8 @@ static void sa1110_setspeed(struct cpufreq_policy *policy)
        sdram_update_refresh(policy->max, sdram);
 
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+       return 0;
 }
 
 static struct cpufreq_policy sa1110_policy = {
@@ -300,10 +302,10 @@ static struct cpufreq_policy sa1110_policy = {
 };
 
 static struct cpufreq_driver sa1110_driver = {
-       .verify         = sa11x0_verify_speed,
-       .setpolicy      = sa1110_setspeed,
-       .policy         = &sa1110_policy,
-       .cpu_min_freq   = 59000,
+       .verify          = sa11x0_verify_speed,
+       .setpolicy       = sa1110_setspeed,
+       .policy          = &sa1110_policy,
+       .cpu_min_freq[0] = 59000,
 };
 
 static int __init sa1110_clk_init(void)
index 461bec6b956b14188ecbcdf04079e597df0705a9..8b7f34ad6153d86eafd16c5c0c537ad8e52f21c0 100644 (file)
@@ -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".
  * 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)
                policy->max = policy->max_cpu_freq;
@@ -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->min = policy->max;
        policy->policy = CPUFREQ_POLICY_POWERSAVE;
+       return 0;
 }
 
 unsigned int sa11x0_getspeed(void)
index d5485109c61eabe9fbd2aef9f88f2339de683089..bc71cc376350a07da3e5bc32f55cce31d9c2246a 100644 (file)
@@ -172,13 +172,13 @@ static void elanfreq_set_cpu_state (unsigned int state) {
  *      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    i;
 
        if (!policy || !max_freq)
-               return;
+               return -EINVAL;
 
        policy->cpu = 0;
 
@@ -190,7 +190,7 @@ static void elanfreq_verify (struct cpufreq_policy *policy)
                        number_states++;
 
        if (number_states)
-               return;
+               return 0;
 
        for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--)
                if (elan_multiplier[i].clock < policy->max)
@@ -198,16 +198,16 @@ static void elanfreq_verify (struct cpufreq_policy *policy)
 
        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    i, j=4;
 
        if (!elanfreq_driver)
-               return;
+               return -EINVAL;
 
        for (i=(sizeof(elan_multiplier)/sizeof(struct s_elan_multiplier) - 1); i>=0; i--)
                if ((elan_multiplier[i].clock >= policy->min) &&
@@ -219,7 +219,7 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy)
 
        if (number_states == 1) {
                elanfreq_set_cpu_state(j);
-               return;
+               return 0;
        }
 
        switch (policy->policy) {
@@ -236,14 +236,14 @@ static void elanfreq_setpolicy (struct cpufreq_policy *policy)
                                j = i;
                break;
        default:
-               return;
+               return -EINVAL;
        }
 
        if (elan_multiplier[j].clock > max_freq)
-               BUG();
+               return -EINVAL;
 
        elanfreq_set_cpu_state(j);
-       return;
+       return 0;
 }
 
 
@@ -296,7 +296,7 @@ static int __init elanfreq_init(void)
                max_freq = elanfreq_get_cpu_frequency();
 
 #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();
 #endif
 
@@ -309,15 +309,15 @@ static int __init elanfreq_init(void)
        driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
        driver->policy[0].max_cpu_freq  = max_freq;
 
+       elanfreq_driver = driver;
+
        ret = cpufreq_register(driver);
        if (ret) {
+               elanfreq_driver = NULL;
                kfree(driver);
-               return ret;
        }
 
-       elanfreq_driver = driver;
-
-       return 0;
+       return ret;
 }
 
 
index aa684efaa1cb274a5a6b116765c58c0a192c0f7d..511d5205151208e12e426309bc2493d18dafb59d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  $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) 2002  Padraig Brady. <padraig@antefacto.com>
@@ -436,8 +436,10 @@ static void __init longhaul_get_ranges (void)
        switch (longhaul) {
        case 1:
                /* 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();
+               minfsb = maxfsb = current_fsb;
                break;
 
        case 2 ... 3:
@@ -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    i;
@@ -540,7 +542,7 @@ static void longhaul_verify(struct cpufreq_policy *policy)
        unsigned int    newmax = -1;
 
        if (!policy || !longhaul_driver)
-               return;
+               return -EINVAL;
 
        policy->cpu = 0;
        cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
@@ -552,7 +554,7 @@ static void longhaul_verify(struct cpufreq_policy *policy)
                number_states = longhaul_statecount_fsb(policy, current_fsb);
 
        if (number_states)
-               return;
+               return 0;
 
        /* get frequency closest above current policy->max */
        if (can_scale_fsb==1) {
@@ -579,10 +581,12 @@ static void longhaul_verify(struct cpufreq_policy *policy)
        }
 
        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    i;
@@ -592,7 +596,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
        unsigned int    best_freq = -1;
 
        if (!longhaul_driver)
-               return;
+               return -EINVAL;
 
        if (policy->policy==CPUFREQ_POLICY_PERFORMANCE)
                fsb_search_table = perf_fsb_table;
@@ -613,7 +617,7 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
        }
 
        if (!number_states)
-               return;
+               return -EINVAL;
        else if (number_states == 1) {
                for(i=0; i<numscales; i++) {
                        if ((clock_ratio[i] != -1) &&
@@ -692,11 +696,11 @@ static void longhaul_setpolicy (struct cpufreq_policy *policy)
                }
                break;
        default:
-               return;
+               return -EINVAL;
        }
 
        longhaul_setstate(new_clock_ratio, new_fsb);
-       return;
+       return 0;
 }
 
 
@@ -775,7 +779,7 @@ static int __init longhaul_init (void)
        driver->policy = (struct cpufreq_policy *) (driver + 1);
 
 #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;
 #endif
 
@@ -788,15 +792,15 @@ static int __init longhaul_init (void)
        driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
        driver->policy[0].max_cpu_freq = (unsigned int) highest_speed;
 
-       ret = cpufreq_register(driver);
+       longhaul_driver = driver;
 
+       ret = cpufreq_register(driver);
        if (ret) {
+               longhaul_driver = NULL;
                kfree(driver);
-               return ret;
        }
 
-       longhaul_driver = driver;
-       return 0;
+       return ret;
 }
 
 
index ab8cb35484504397584b786032e6abebd0cc67c0..982314536c79eba1a08842b6ae126d6191dfa03a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  $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>
  *
@@ -67,13 +67,13 @@ static void longrun_get_policy(struct cpufreq_policy *policy)
  * Sets a new CPUFreq policy on LongRun-capable processors. This function
  * 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 pctg_lo, pctg_hi;
 
        if (!longrun_driver || !policy)
-               return;
+               return -EINVAL;
 
        pctg_lo = (policy->min - longrun_low_freq) / 
                ((longrun_high_freq - longrun_low_freq) / 100);
@@ -105,7 +105,7 @@ static void longrun_set_policy(struct cpufreq_policy *policy)
        msr_hi |= pctg_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)
  * Validates a new CPUFreq policy. This function has to be called with 
  * 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)
-               return;
+               return -EINVAL;
 
        policy->cpu = 0;
        cpufreq_verify_within_limits(policy, 0, 
                longrun_driver->policy[0].max_cpu_freq);
 
-       return;
+       return 0;
 }
 
 
@@ -252,20 +252,22 @@ static int __init longrun_init(void)
        longrun_get_policy(&driver->policy[0]);
 
 #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 */
 #endif
 
        driver->verify         = &longrun_verify_policy;
        driver->setpolicy      = &longrun_set_policy;
+
+       longrun_driver = driver;
+
        result = cpufreq_register(driver);
        if (result) {
+               longrun_driver = NULL;
                kfree(driver);
-               return result;
        }
-       longrun_driver = driver;
 
-       return 0;
+       return result;
 }
 
 
index e9c846879fe49d37a173dd0b5524d59173a4ff23..a86f3cc32f7a085cf84b5bef3f786a8d9b3d46c7 100644 (file)
@@ -78,7 +78,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
        }
 #endif
        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 */
        rdmsr(MSR_IA32_THERM_CONTROL, l, h);
@@ -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    newstate = 0;
        unsigned int    number_states = 0;
 
        if (!cpufreq_p4_driver || !stock_freq || !policy)
-               return;
+               return -EINVAL;
 
        if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
        {
@@ -183,16 +183,17 @@ static void cpufreq_p4_setpolicy(struct cpufreq_policy *policy)
                        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    i;
 
        if (!cpufreq_p4_driver || !stock_freq || !policy)
-               return;
+               return -EINVAL;
 
        if (!cpu_online(policy->cpu))
                policy->cpu = CPUFREQ_ALL_CPUS;
@@ -205,10 +206,10 @@ static void cpufreq_p4_verify(struct cpufreq_policy *policy)
                        number_states++;
 
        if (number_states)
-               return;
+               return 0;
 
        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)
                stock_freq = cpu_khz;
 
 #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;
+       }
 #endif
 
        driver->verify        = &cpufreq_p4_verify;
@@ -274,15 +276,15 @@ int __init cpufreq_p4_init(void)
                driver->policy[i].cpu    = i;
        }
 
+       cpufreq_p4_driver = driver;
+       
        ret = cpufreq_register(driver);
        if (ret) {
+               cpufreq_p4_driver = NULL;
                kfree(driver);
-               return ret;
        }
 
-       cpufreq_p4_driver = driver;
-       
-       return 0;
+       return ret;
 }
 
 
index 2f77db051412269ee8af1124f23846f32faeba8d..c43c9a6ddac25c81ad41d6e53a0673a2a87fb3e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  $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)
  *  and is shared with the Linux Kernel module.
  *
@@ -113,13 +113,13 @@ static void powernow_k6_set_state (unsigned int best_i)
  * Policy must be within lowest and highest possible CPU Frequency,
  * 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    i, j;
 
        if (!policy || !busfreq)
-               return;
+               return -EINVAL;
 
        policy->cpu = 0;
        cpufreq_verify_within_limits(policy, (20 * busfreq),
@@ -131,7 +131,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
                        number_states++;
 
        if (number_states)
-               return;
+               return 0;
 
        /* no state is available within range -- find next larger state */
 
@@ -144,7 +144,7 @@ static void powernow_k6_verify(struct cpufreq_policy *policy)
 
        policy->max = clock_ratio[j] * busfreq;
 
-       return;
+       return 0;
 }
 
 
@@ -154,13 +154,13 @@ static void powernow_k6_verify(struct cpufreq_policy *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    i, j=4;
 
        if (!powernow_driver)
-               return;
+               return -EINVAL;
 
        for (i=0; i<8; i++)
                if ((policy->min <= (busfreq * clock_ratio[i])) &&
@@ -174,7 +174,7 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy)
                /* if only one state is within the limit borders, it
                   is easily detected and set */
                powernow_k6_set_state(j);
-               return;
+               return 0;
        }
 
        /* more than one state within limit */
@@ -196,14 +196,14 @@ static void powernow_k6_setpolicy (struct cpufreq_policy *policy)
                                j = i;
                break;
        default:
-               return;
+               return -EINVAL;
        }
 
        if (clock_ratio[i] > max_multiplier)
-               BUG();
+               return -EINVAL;
 
        powernow_k6_set_state(j);
-       return;
+       return 0;
 }
 
 
@@ -242,7 +242,7 @@ static int __init powernow_k6_init(void)
        driver->policy = (struct cpufreq_policy *) (driver + 1);
 
 #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;
 #endif
 
@@ -255,16 +255,16 @@ static int __init powernow_k6_init(void)
        driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
        driver->policy[0].max_cpu_freq  = busfreq * max_multiplier;
 
+       powernow_driver = driver;
 
        result = cpufreq_register(driver);
        if (result) {
                release_region (POWERNOW_IOPORT, 16);
+               powernow_driver = NULL;
                kfree(driver);
-               return result;
        }
-       powernow_driver = driver;
 
-       return 0;
+       return result;
 }
 
 
index d5ee5fb11a6952915226354c603f85981f2bbd98..2e7e50fca8183798ae483048ef0b03e36878e771 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  $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) 2002  Dominik Brodowski <linux@brodo.de>
@@ -567,10 +567,10 @@ static int speedstep_detect_speeds (void)
  *
  * 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)
-               return;
+               return -EINVAL;
 
        if (policy->min > speedstep_low_freq) 
                speedstep_set_state(SPEEDSTEP_HIGH, 1);
@@ -585,6 +585,7 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy)
                                speedstep_set_state(SPEEDSTEP_HIGH, 1);
                }
        }
+       return 0;
 }
 
 
@@ -595,11 +596,11 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy)
  * Limit must be within speedstep_low_freq and speedstep_high_freq, with
  * 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 || 
            !speedstep_low_freq || !speedstep_high_freq)
-               return;
+               return -EINVAL;
 
        policy->cpu = 0; /* UP only */
 
@@ -609,7 +610,7 @@ static void speedstep_verify (struct cpufreq_policy *policy)
            (policy->max < speedstep_high_freq))
                policy->max = speedstep_high_freq;
        
-       return;
+       return 0;
 }
 
 
@@ -654,12 +655,11 @@ static int __init speedstep_init(void)
                speedstep_processor = speedstep_detect_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");
                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", 
               speedstep_chipset, speedstep_processor);
 
@@ -693,7 +693,7 @@ static int __init speedstep_init(void)
        driver->policy = (struct cpufreq_policy *) (driver + 1);
 
 #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;
 #endif
 
@@ -707,14 +707,15 @@ static int __init speedstep_init(void)
        driver->policy[0].policy = (speed == speedstep_low_freq) ? 
            CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
 
+       speedstep_driver = driver;
+
        result = cpufreq_register(driver);
        if (result) {
+               speedstep_driver = NULL;
                kfree(driver);
-               return result;
        }
-       speedstep_driver = driver;
 
-       return 0;
+       return result;
 }
 
 
index 46b64579ef5edda8c6b55e3face120d17efc9c9e..13b8adb64ce20c65d1ce5dd401a439606568f04d 100644 (file)
@@ -1613,7 +1613,7 @@ acpi_processor_get_limit_info (
                                cpufreq interface
    -------------------------------------------------------------------------- */
 #ifdef CONFIG_ACPI_PROCESSOR_PERF
-static void
+static int
 acpi_cpufreq_setpolicy (
        struct cpufreq_policy   *policy)
 {
@@ -1626,7 +1626,7 @@ acpi_cpufreq_setpolicy (
        ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
 
        if (!policy)
-               return_VOID;
+               return_VALUE(-EINVAL);
 
        /* get a present, initialized CPU */
        if (policy->cpu == CPUFREQ_ALL_CPUS)
@@ -1644,7 +1644,7 @@ acpi_cpufreq_setpolicy (
                cpu = policy->cpu;
                pr = processors[cpu];
                if (!pr)
-                       return_VOID;
+                       return_VALUE(-EINVAL);
        }
 
        /* select appropriate P-State */
@@ -1686,11 +1686,11 @@ acpi_cpufreq_setpolicy (
                result = acpi_processor_set_performance (pr, next_state);
        }
 
-       return_VOID;
+       return_VALUE(0);
 }
 
 
-static void
+static int
 acpi_cpufreq_verify (
        struct cpufreq_policy   *policy)
 {
@@ -1703,7 +1703,7 @@ acpi_cpufreq_verify (
        ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
 
        if (!policy)
-               return_VOID;
+               return_VALUE(-EINVAL);
 
        /* get a present, initialized CPU */
        if (policy->cpu == CPUFREQ_ALL_CPUS)
@@ -1721,7 +1721,7 @@ acpi_cpufreq_verify (
                cpu = policy->cpu;
                pr = processors[cpu];
                if (!pr)
-                       return_VOID;
+                       return_VALUE(-EINVAL);
        }
 
        /* first check if min and max are within valid limits */
@@ -1741,13 +1741,12 @@ acpi_cpufreq_verify (
                        next_larger_state = i;
        }
 
-       if (number_states)
-               return_VOID;
-
-       /* round up now */
-       policy->max = pr->performance.states[next_larger_state].core_frequency * 1000;
+       if (!number_states) {
+               /* round up now */
+               policy->max = pr->performance.states[next_larger_state].core_frequency * 1000;
+       }
 
-       return_VOID;
+       return_VALUE(0);
 }
 
 static int
@@ -1807,9 +1806,10 @@ acpi_cpufreq_init (
        driver->policy = (struct cpufreq_policy *) (driver + 1);
 
 #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_min_freq[0] = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000;
+       }
 #endif
 
        driver->verify      = &acpi_cpufreq_verify;
index a5aa299cf92c4282fbb89f6aa75cf56ce9b93e5d..a8f8d2a3193688e4d4fba776b208ced0ac8c217b 100644 (file)
@@ -5,7 +5,7 @@
  *            (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
  * 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
  *                      CPUFREQ DRIVER INTERFACE                     *
  *********************************************************************/
 
-typedef void (*cpufreq_policy_t)          (struct cpufreq_policy *policy);
+typedef int (*cpufreq_policy_t)          (struct cpufreq_policy *policy);
 
 struct cpufreq_driver {
        /* needed by all drivers */
@@ -116,7 +116,7 @@ struct cpufreq_driver {
 #endif
        /* 2.4. compatible 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];
 #endif
 };
@@ -205,19 +205,19 @@ enum {
        CPU_NR_FREQ = 3,
 };
 
-#define CTL_CPU_VARS_SPEED_MAX { \
+#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
                 .ctl_name      = CPU_NR_FREQ_MAX, \
-                .data          = &cpu_max_freq, \
+                .data          = &cpu_max_freq[cpunr], \
                 .procname      = "speed-max", \
-                .maxlen                = sizeof(cpu_max_freq),\
+                .maxlen                = sizeof(cpu_max_freq[cpunr]),\
                 .mode          = 0444, \
                 .proc_handler  = proc_dointvec, }
 
-#define CTL_CPU_VARS_SPEED_MIN { \
+#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
                 .ctl_name      = CPU_NR_FREQ_MIN, \
-                .data          = &cpu_min_freq, \
+                .data          = &cpu_min_freq[cpunr], \
                 .procname      = "speed-min", \
-                .maxlen                = sizeof(cpu_min_freq),\
+                .maxlen                = sizeof(cpu_min_freq[cpunr]),\
                 .mode          = 0444, \
                 .proc_handler  = proc_dointvec, }
 
@@ -230,8 +230,8 @@ enum {
                 .extra1                = (void*) (cpunr), }
 
 #define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
-                CTL_CPU_VARS_SPEED_MAX, \
-                CTL_CPU_VARS_SPEED_MIN, \
+                CTL_CPU_VARS_SPEED_MAX(cpunr), \
+                CTL_CPU_VARS_SPEED_MIN(cpunr), \
                 CTL_CPU_VARS_SPEED(cpunr),  \
                 { .ctl_name = 0, }, }
 
index 74b54ac2cea709f5c1c30fd172791498bc5c3493..1cfc2489a08afc81d8d45fc4d85ba6f6690a0f32 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (C) 2001 Russell King
  *            (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
  * it under the terms of the GNU General Public License version 2 as
@@ -69,8 +69,8 @@ static struct cpufreq_policy default_policy = {
 /**
  * A few values needed by the 2.4.-compatible API
  */
-static unsigned int     cpu_max_freq;
-static unsigned int     cpu_min_freq;
+static unsigned int     cpu_max_freq[NR_CPUS];
+static unsigned int     cpu_min_freq[NR_CPUS];
 static unsigned int     cpu_cur_freq[NR_CPUS];
 #endif
 
@@ -228,6 +228,10 @@ static int cpufreq_proc_read (
                        continue;
 
                cpufreq_get_policy(&policy, i);
+
+               if (!policy.max_cpu_freq)
+                       continue;
+
                min_pctg = (policy.min * 100) / policy.max_cpu_freq;
                max_pctg = (policy.max * 100) / policy.max_cpu_freq;
 
@@ -378,7 +382,7 @@ int cpufreq_setmax(unsigned int cpu)
 {
        if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS))
                return -EINVAL;
-       return cpufreq_set(cpu_max_freq, cpu);
+       return cpufreq_set(cpu_max_freq[cpu], cpu);
 }
 EXPORT_SYMBOL_GPL(cpufreq_setmax);
 
@@ -807,13 +811,14 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
        policy->min    = cpufreq_driver->policy[cpu].min;
        policy->max    = cpufreq_driver->policy[cpu].max;
        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;
 
        up(&cpufreq_driver_sem);
 
        return 0;
 }
+EXPORT_SYMBOL(cpufreq_get_policy);
 
 
 /**
@@ -825,6 +830,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
 int cpufreq_set_policy(struct cpufreq_policy *policy)
 {
        unsigned int i;
+       int ret;
 
        down(&cpufreq_driver_sem);
        if (!cpufreq_driver || !cpufreq_driver->verify || 
@@ -834,12 +840,20 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
                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 */
-       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 */
        notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST,
@@ -851,7 +865,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
 
        /* verify the cpu speed can be set within this limit,
           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 */
        notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY,
@@ -879,11 +898,11 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
                cpu_cur_freq[policy->cpu] = policy->max;
 #endif
 
-       cpufreq_driver->setpolicy(policy);
+       ret = cpufreq_driver->setpolicy(policy);
        
        up(&cpufreq_driver_sem);
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL(cpufreq_set_policy);
 
@@ -968,6 +987,8 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
 int cpufreq_register(struct cpufreq_driver *driver_data)
 {
        unsigned int            ret;
+       unsigned int            i;
+       struct cpufreq_policy   policy;
 
        if (cpufreq_driver)
                return -EBUSY;
@@ -979,41 +1000,55 @@ int cpufreq_register(struct cpufreq_driver *driver_data)
        down(&cpufreq_driver_sem);
        cpufreq_driver        = driver_data;
        
-       if (!default_policy.policy)
-               default_policy.policy = driver_data->policy[0].policy;
-       if (!default_policy.min)
-               default_policy.min = driver_data->policy[0].min;
-       if (!default_policy.max)
-               default_policy.max = driver_data->policy[0].max;
-       default_policy.cpu = CPUFREQ_ALL_CPUS;
+       /* check for a default policy - if it exists, use it on _all_ CPUs*/
+       for (i=0; i<NR_CPUS; i++)
+       {
+               if (default_policy.policy)
+                       cpufreq_driver->policy[i].policy = default_policy.policy;
+               if (default_policy.min)
+                       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();
 
 #ifdef CONFIG_CPU_FREQ_24_API
-       down(&cpufreq_driver_sem);
-       cpu_min_freq          = driver_data->cpu_min_freq;
-       cpu_max_freq          = driver_data->policy[0].max_cpu_freq;
+       down(&cpufreq_driver_sem);
+       for (i=0; i<NR_CPUS; i++) 
        {
-               unsigned int i;
-               for (i=0; i<NR_CPUS; i++) {
-                       cpu_cur_freq[i] = driver_data->cpu_cur_freq[i];
-               }
+               cpu_min_freq[i] = driver_data->cpu_min_freq[i];
+               cpu_max_freq[i] = driver_data->policy[i].max_cpu_freq;
+               cpu_cur_freq[i] = driver_data->cpu_cur_freq[i];
        }
        up(&cpufreq_driver_sem);
 
        cpufreq_sysctl_init();
 #endif
-       if (ret) {
-               down(&cpufreq_driver_sem);
-               cpufreq_driver = NULL;
-               up(&cpufreq_driver_sem);
-       }
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(cpufreq_register);
 
@@ -1061,6 +1096,7 @@ int cpufreq_restore(void)
 {
        struct cpufreq_policy policy;
        unsigned int i;
+       unsigned int ret = 0;
 
        if (in_interrupt())
                panic("cpufreq_restore() called from interrupt context!");
@@ -1081,10 +1117,10 @@ int cpufreq_restore(void)
                policy.cpu    = i;
                up(&cpufreq_driver_sem);
 
-               cpufreq_set_policy(&policy);
+               ret += cpufreq_set_policy(&policy);
        }
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(cpufreq_restore);
 #else