Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / sparc64 / kernel / us2e_cpufreq.c
index 7aae0a1..1f83fe6 100644 (file)
@@ -88,7 +88,6 @@ static void frob_mem_refresh(int cpu_slowing_down,
 {
        unsigned long old_refr_count, refr_count, mctrl;
 
-
        refr_count  = (clock_tick * MCTRL0_REFR_INTERVAL);
        refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL);
 
@@ -230,6 +229,25 @@ static unsigned long estar_to_divisor(unsigned long estar)
        return ret;
 }
 
+static unsigned int us2e_freq_get(unsigned int cpu)
+{
+       cpumask_t cpus_allowed;
+       unsigned long clock_tick, estar;
+
+       if (!cpu_online(cpu))
+               return 0;
+
+       cpus_allowed = current->cpus_allowed;
+       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+       clock_tick = sparc64_get_clock_tick(cpu) / 1000;
+       estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
+
+       set_cpus_allowed(current, cpus_allowed);
+
+       return clock_tick / estar_to_divisor(estar);
+}
+
 static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
 {
        unsigned long new_bits, new_freq;
@@ -243,7 +261,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
        cpus_allowed = current->cpus_allowed;
        set_cpus_allowed(current, cpumask_of_cpu(cpu));
 
-       new_freq = clock_tick = sparc64_get_clock_tick(cpu);
+       new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
        new_bits = index_to_estar_mode(index);
        divisor = index_to_divisor(index);
        new_freq /= divisor;
@@ -258,7 +276,8 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
        if (old_divisor != divisor)
-               us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor);
+               us2e_transition(estar, new_bits, clock_tick * 1000,
+                               old_divisor, divisor);
 
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
@@ -272,10 +291,8 @@ static int us2e_freq_target(struct cpufreq_policy *policy,
        unsigned int new_index = 0;
 
        if (cpufreq_frequency_table_target(policy,
-                                             &us2e_freq_table[policy->cpu].table[0],
-                                             target_freq,
-                                             relation,
-                                             &new_index))
+                                          &us2e_freq_table[policy->cpu].table[0],
+                                          target_freq, relation, &new_index))
                return -EINVAL;
 
        us2e_set_cpu_divider_index(policy->cpu, new_index);
@@ -292,7 +309,7 @@ static int us2e_freq_verify(struct cpufreq_policy *policy)
 static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
 {
        unsigned int cpu = policy->cpu;
-       unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+       unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
        struct cpufreq_frequency_table *table =
                &us2e_freq_table[cpu].table[0];
 
@@ -329,6 +346,9 @@ static int __init us2e_freq_init(void)
        unsigned long manuf, impl, ver;
        int ret;
 
+       if (tlb_type != spitfire)
+               return -ENODEV;
+
        __asm__("rdpr %%ver, %0" : "=r" (ver));
        manuf = ((ver >> 48) & 0xffff);
        impl  = ((ver >> 32) & 0xffff);
@@ -337,23 +357,20 @@ static int __init us2e_freq_init(void)
                struct cpufreq_driver *driver;
 
                ret = -ENOMEM;
-               driver = kmalloc(sizeof(struct cpufreq_driver), GFP_KERNEL);
+               driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL);
                if (!driver)
                        goto err_out;
-               memset(driver, 0, sizeof(*driver));
 
-               us2e_freq_table = kmalloc(
+               us2e_freq_table = kzalloc(
                        (NR_CPUS * sizeof(struct us2e_freq_percpu_info)),
                        GFP_KERNEL);
                if (!us2e_freq_table)
                        goto err_out;
 
-               memset(us2e_freq_table, 0,
-                      (NR_CPUS * sizeof(struct us2e_freq_percpu_info)));
-
+               driver->init = us2e_freq_cpu_init;
                driver->verify = us2e_freq_verify;
                driver->target = us2e_freq_target;
-               driver->init = us2e_freq_cpu_init;
+               driver->get = us2e_freq_get;
                driver->exit = us2e_freq_cpu_exit;
                driver->owner = THIS_MODULE,
                strcpy(driver->name, "UltraSPARC-IIe");
@@ -370,10 +387,8 @@ err_out:
                        kfree(driver);
                        cpufreq_us2e_driver = NULL;
                }
-               if (us2e_freq_table) {
-                       kfree(us2e_freq_table);
-                       us2e_freq_table = NULL;
-               }
+               kfree(us2e_freq_table);
+               us2e_freq_table = NULL;
                return ret;
        }
 
@@ -384,7 +399,6 @@ static void __exit us2e_freq_exit(void)
 {
        if (cpufreq_us2e_driver) {
                cpufreq_unregister_driver(cpufreq_us2e_driver);
-
                kfree(cpufreq_us2e_driver);
                cpufreq_us2e_driver = NULL;
                kfree(us2e_freq_table);