2 * Copyright (C) 2004-2007 Atmel Corporation
4 * Based on MIPS implementation arch/mips/kernel/time.c
5 * Copyright 2001 MontaVista Software Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
14 #include <linux/kernel.h>
15 #include <linux/types.h>
16 #include <linux/init.h>
17 #include <linux/cpufreq.h>
19 #include <linux/clk.h>
20 #include <linux/err.h>
21 #include <asm/system.h>
23 static struct clk
*cpuclk
;
25 static int at32_verify_speed(struct cpufreq_policy
*policy
)
30 cpufreq_verify_within_limits(policy
, policy
->cpuinfo
.min_freq
,
31 policy
->cpuinfo
.max_freq
);
35 static unsigned int at32_get_speed(unsigned int cpu
)
40 return (unsigned int)((clk_get_rate(cpuclk
) + 500) / 1000);
43 static int at32_set_target(struct cpufreq_policy
*policy
,
44 unsigned int target_freq
,
45 unsigned int relation
)
47 struct cpufreq_freqs freqs
;
50 /* Convert target_freq from kHz to Hz */
51 freq
= clk_round_rate(cpuclk
, target_freq
* 1000);
53 /* Check if policy->min <= new_freq <= policy->max */
54 if(freq
< (policy
->min
* 1000) || freq
> (policy
->max
* 1000))
57 pr_debug("cpufreq: requested frequency %u Hz\n", target_freq
* 1000);
59 freqs
.old
= at32_get_speed(0);
60 freqs
.new = (freq
+ 500) / 1000;
64 cpufreq_notify_transition(&freqs
, CPUFREQ_PRECHANGE
);
65 clk_set_rate(cpuclk
, freq
);
66 cpufreq_notify_transition(&freqs
, CPUFREQ_POSTCHANGE
);
68 pr_debug("cpufreq: set frequency %lu Hz\n", freq
);
73 static int __init
at32_cpufreq_driver_init(struct cpufreq_policy
*policy
)
78 cpuclk
= clk_get(NULL
, "cpu");
80 pr_debug("cpufreq: could not get CPU clk\n");
81 return PTR_ERR(cpuclk
);
84 policy
->cpuinfo
.min_freq
= (clk_round_rate(cpuclk
, 1) + 500) / 1000;
85 policy
->cpuinfo
.max_freq
= (clk_round_rate(cpuclk
, ~0UL) + 500) / 1000;
86 policy
->cpuinfo
.transition_latency
= 0;
87 policy
->cur
= at32_get_speed(0);
88 policy
->min
= policy
->cpuinfo
.min_freq
;
89 policy
->max
= policy
->cpuinfo
.max_freq
;
90 policy
->governor
= CPUFREQ_DEFAULT_GOVERNOR
;
92 printk("cpufreq: AT32AP CPU frequency driver\n");
97 static struct cpufreq_driver at32_driver
= {
100 .init
= at32_cpufreq_driver_init
,
101 .verify
= at32_verify_speed
,
102 .target
= at32_set_target
,
103 .get
= at32_get_speed
,
104 .flags
= CPUFREQ_STICKY
,
107 static int __init
at32_cpufreq_init(void)
109 return cpufreq_register_driver(&at32_driver
);
112 arch_initcall(at32_cpufreq_init
);