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 / us3_cpufreq.c
index 18fe54b..47e3aca 100644 (file)
@@ -56,7 +56,7 @@ static void write_safari_cfg(unsigned long val)
 
 static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg)
 {
-       unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+       unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
        unsigned long ret;
 
        switch (safari_cfg & SAFARI_CFG_DIV_MASK) {
@@ -76,6 +76,26 @@ static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg
        return ret;
 }
 
+static unsigned int us3_freq_get(unsigned int cpu)
+{
+       cpumask_t cpus_allowed;
+       unsigned long reg;
+       unsigned int ret;
+
+       if (!cpu_online(cpu))
+               return 0;
+
+       cpus_allowed = current->cpus_allowed;
+       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+       reg = read_safari_cfg();
+       ret = get_current_freq(cpu, reg);
+
+       set_cpus_allowed(current, cpus_allowed);
+
+       return ret;
+}
+
 static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
 {
        unsigned long new_bits, new_freq, reg;
@@ -88,7 +108,7 @@ static void us3_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 = sparc64_get_clock_tick(cpu);
+       new_freq = sparc64_get_clock_tick(cpu) / 1000;
        switch (index) {
        case 0:
                new_bits = SAFARI_CFG_DIV_1;
@@ -150,7 +170,7 @@ static int us3_freq_verify(struct cpufreq_policy *policy)
 static int __init us3_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 =
                &us3_freq_table[cpu].table[0];
 
@@ -183,32 +203,35 @@ static int __init us3_freq_init(void)
        unsigned long manuf, impl, ver;
        int ret;
 
+       if (tlb_type != cheetah && tlb_type != cheetah_plus)
+               return -ENODEV;
+
        __asm__("rdpr %%ver, %0" : "=r" (ver));
        manuf = ((ver >> 48) & 0xffff);
        impl  = ((ver >> 32) & 0xffff);
 
        if (manuf == CHEETAH_MANUF &&
-           (impl == CHEETAH_IMPL || impl == CHEETAH_PLUS_IMPL)) {
+           (impl == CHEETAH_IMPL ||
+            impl == CHEETAH_PLUS_IMPL ||
+            impl == JAGUAR_IMPL ||
+            impl == PANTHER_IMPL)) {
                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));
 
-               us3_freq_table = kmalloc(
+               us3_freq_table = kzalloc(
                        (NR_CPUS * sizeof(struct us3_freq_percpu_info)),
                        GFP_KERNEL);
                if (!us3_freq_table)
                        goto err_out;
 
-               memset(us3_freq_table, 0,
-                      (NR_CPUS * sizeof(struct us3_freq_percpu_info)));
-
+               driver->init = us3_freq_cpu_init;
                driver->verify = us3_freq_verify;
                driver->target = us3_freq_target;
-               driver->init = us3_freq_cpu_init;
+               driver->get = us3_freq_get;
                driver->exit = us3_freq_cpu_exit;
                driver->owner = THIS_MODULE,
                strcpy(driver->name, "UltraSPARC-III");
@@ -225,10 +248,8 @@ err_out:
                        kfree(driver);
                        cpufreq_us3_driver = NULL;
                }
-               if (us3_freq_table) {
-                       kfree(us3_freq_table);
-                       us3_freq_table = NULL;
-               }
+               kfree(us3_freq_table);
+               us3_freq_table = NULL;
                return ret;
        }
 
@@ -239,7 +260,6 @@ static void __exit us3_freq_exit(void)
 {
        if (cpufreq_us3_driver) {
                cpufreq_unregister_driver(cpufreq_us3_driver);
-
                kfree(cpufreq_us3_driver);
                cpufreq_us3_driver = NULL;
                kfree(us3_freq_table);