diff options
Diffstat (limited to 'arch/microblaze/kernel/timer.c')
-rw-r--r-- | arch/microblaze/kernel/timer.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index b1380ae93ae..a5aa33db1df 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c | |||
@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr; | |||
38 | #define TIMER_BASE timer_baseaddr | 38 | #define TIMER_BASE timer_baseaddr |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | unsigned int freq_div_hz; | ||
42 | unsigned int timer_clock_freq; | ||
43 | |||
41 | #define TCSR0 (0x00) | 44 | #define TCSR0 (0x00) |
42 | #define TLR0 (0x04) | 45 | #define TLR0 (0x04) |
43 | #define TCR0 (0x08) | 46 | #define TCR0 (0x08) |
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode, | |||
115 | switch (mode) { | 118 | switch (mode) { |
116 | case CLOCK_EVT_MODE_PERIODIC: | 119 | case CLOCK_EVT_MODE_PERIODIC: |
117 | printk(KERN_INFO "%s: periodic\n", __func__); | 120 | printk(KERN_INFO "%s: periodic\n", __func__); |
118 | microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); | 121 | microblaze_timer0_start_periodic(freq_div_hz); |
119 | break; | 122 | break; |
120 | case CLOCK_EVT_MODE_ONESHOT: | 123 | case CLOCK_EVT_MODE_ONESHOT: |
121 | printk(KERN_INFO "%s: oneshot\n", __func__); | 124 | printk(KERN_INFO "%s: oneshot\n", __func__); |
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = { | |||
168 | static __init void microblaze_clockevent_init(void) | 171 | static __init void microblaze_clockevent_init(void) |
169 | { | 172 | { |
170 | clockevent_microblaze_timer.mult = | 173 | clockevent_microblaze_timer.mult = |
171 | div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, | 174 | div_sc(timer_clock_freq, NSEC_PER_SEC, |
172 | clockevent_microblaze_timer.shift); | 175 | clockevent_microblaze_timer.shift); |
173 | clockevent_microblaze_timer.max_delta_ns = | 176 | clockevent_microblaze_timer.max_delta_ns = |
174 | clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); | 177 | clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); |
@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = { | |||
201 | 204 | ||
202 | int __init init_microblaze_timecounter(void) | 205 | int __init init_microblaze_timecounter(void) |
203 | { | 206 | { |
204 | microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, | 207 | microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, |
205 | microblaze_cc.shift); | 208 | microblaze_cc.shift); |
206 | 209 | ||
207 | timecounter_init(µblaze_tc, µblaze_cc, sched_clock()); | 210 | timecounter_init(µblaze_tc, µblaze_cc, sched_clock()); |
@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = { | |||
221 | static int __init microblaze_clocksource_init(void) | 224 | static int __init microblaze_clocksource_init(void) |
222 | { | 225 | { |
223 | clocksource_microblaze.mult = | 226 | clocksource_microblaze.mult = |
224 | clocksource_hz2mult(cpuinfo.cpu_clock_freq, | 227 | clocksource_hz2mult(timer_clock_freq, |
225 | clocksource_microblaze.shift); | 228 | clocksource_microblaze.shift); |
226 | if (clocksource_register(&clocksource_microblaze)) | 229 | if (clocksource_register(&clocksource_microblaze)) |
227 | panic("failed to register clocksource"); | 230 | panic("failed to register clocksource"); |
@@ -247,6 +250,7 @@ void __init time_init(void) | |||
247 | u32 irq, i = 0; | 250 | u32 irq, i = 0; |
248 | u32 timer_num = 1; | 251 | u32 timer_num = 1; |
249 | struct device_node *timer = NULL; | 252 | struct device_node *timer = NULL; |
253 | const void *prop; | ||
250 | #ifdef CONFIG_SELFMOD_TIMER | 254 | #ifdef CONFIG_SELFMOD_TIMER |
251 | unsigned int timer_baseaddr = 0; | 255 | unsigned int timer_baseaddr = 0; |
252 | int arr_func[] = { | 256 | int arr_func[] = { |
@@ -258,12 +262,10 @@ void __init time_init(void) | |||
258 | 0 | 262 | 0 |
259 | }; | 263 | }; |
260 | #endif | 264 | #endif |
261 | char *timer_list[] = { | 265 | const char * const timer_list[] = { |
262 | "xlnx,xps-timer-1.00.a", | 266 | "xlnx,xps-timer-1.00.a", |
263 | "xlnx,opb-timer-1.00.b", | 267 | NULL |
264 | "xlnx,opb-timer-1.00.a", | 268 | }; |
265 | NULL | ||
266 | }; | ||
267 | 269 | ||
268 | for (i = 0; timer_list[i] != NULL; i++) { | 270 | for (i = 0; timer_list[i] != NULL; i++) { |
269 | timer = of_find_compatible_node(NULL, NULL, timer_list[i]); | 271 | timer = of_find_compatible_node(NULL, NULL, timer_list[i]); |
@@ -272,13 +274,13 @@ void __init time_init(void) | |||
272 | } | 274 | } |
273 | BUG_ON(!timer); | 275 | BUG_ON(!timer); |
274 | 276 | ||
275 | timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); | 277 | timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL)); |
276 | timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); | 278 | timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); |
277 | irq = *(int *) of_get_property(timer, "interrupts", NULL); | 279 | irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL)); |
278 | timer_num = | 280 | timer_num = be32_to_cpup(of_get_property(timer, |
279 | *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); | 281 | "xlnx,one-timer-only", NULL)); |
280 | if (timer_num) { | 282 | if (timer_num) { |
281 | printk(KERN_EMERG "Please enable two timers in HW\n"); | 283 | eprintk(KERN_EMERG "Please enable two timers in HW\n"); |
282 | BUG(); | 284 | BUG(); |
283 | } | 285 | } |
284 | 286 | ||
@@ -288,7 +290,14 @@ void __init time_init(void) | |||
288 | printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", | 290 | printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", |
289 | timer_list[i], timer_baseaddr, irq); | 291 | timer_list[i], timer_baseaddr, irq); |
290 | 292 | ||
291 | cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; | 293 | /* If there is clock-frequency property than use it */ |
294 | prop = of_get_property(timer, "clock-frequency", NULL); | ||
295 | if (prop) | ||
296 | timer_clock_freq = be32_to_cpup(prop); | ||
297 | else | ||
298 | timer_clock_freq = cpuinfo.cpu_clock_freq; | ||
299 | |||
300 | freq_div_hz = timer_clock_freq / HZ; | ||
292 | 301 | ||
293 | setup_irq(irq, &timer_irqaction); | 302 | setup_irq(irq, &timer_irqaction); |
294 | #ifdef CONFIG_HEART_BEAT | 303 | #ifdef CONFIG_HEART_BEAT |