9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/sched.h>
15 #include <linux/slab.h>
19 #include <asm/timer.h>
33 #define SAFARI_CFG_DIV_1 0x0000000000000000UL
34 #define SAFARI_CFG_DIV_2 0x0000000040000000UL
35 #define SAFARI_CFG_DIV_32 0x0000000080000000UL
36 #define SAFARI_CFG_DIV_MASK 0x00000000C0000000UL
38 static unsigned long read_safari_cfg(
void)
42 __asm__ __volatile__(
"ldxa [%%g0] %1, %0"
48 static void write_safari_cfg(
unsigned long val)
50 __asm__ __volatile__(
"stxa %0, [%%g0] %1\n\t"
57 static unsigned long get_current_freq(
unsigned int cpu,
unsigned long safari_cfg)
70 ret = clock_tick / 32;
79 static unsigned int us3_freq_get(
unsigned int cpu)
91 reg = read_safari_cfg();
92 ret = get_current_freq(cpu, reg);
94 set_cpus_allowed_ptr(
current, &cpus_allowed);
99 static void us3_set_cpu_divider_index(
unsigned int cpu,
unsigned int index)
101 unsigned long new_bits, new_freq,
reg;
130 reg = read_safari_cfg();
132 freqs.old = get_current_freq(cpu, reg);
133 freqs.new = new_freq;
139 write_safari_cfg(reg);
143 set_cpus_allowed_ptr(
current, &cpus_allowed);
147 unsigned int target_freq,
148 unsigned int relation)
150 unsigned int new_index = 0;
153 &us3_freq_table[policy->
cpu].
table[0],
159 us3_set_cpu_divider_index(policy->
cpu, new_index);
167 &us3_freq_table[policy->
cpu].
table[0]);
172 unsigned int cpu = policy->
cpu;
186 policy->
cpuinfo.transition_latency = 0;
187 policy->
cur = clock_tick;
194 if (cpufreq_us3_driver)
195 us3_set_cpu_divider_index(policy->
cpu, 0);
200 static int __init us3_freq_init(
void)
202 unsigned long manuf, impl,
ver;
208 __asm__(
"rdpr %%ver, %0" :
"=r" (ver));
209 manuf = ((ver >> 48) & 0xffff);
210 impl = ((ver >> 32) & 0xffff);
224 us3_freq_table = kzalloc(
230 driver->
init = us3_freq_cpu_init;
231 driver->
verify = us3_freq_verify;
232 driver->
target = us3_freq_target;
233 driver->
get = us3_freq_get;
234 driver->
exit = us3_freq_cpu_exit;
238 cpufreq_us3_driver =
driver;
248 cpufreq_us3_driver =
NULL;
250 kfree(us3_freq_table);
251 us3_freq_table =
NULL;
258 static void __exit us3_freq_exit(
void)
260 if (cpufreq_us3_driver) {
262 kfree(cpufreq_us3_driver);
263 cpufreq_us3_driver =
NULL;
264 kfree(us3_freq_table);
265 us3_freq_table =
NULL;