diff options
Diffstat (limited to 'arch/microblaze/kernel/timer.c')
-rw-r--r-- | arch/microblaze/kernel/timer.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index b1380ae93ae1..e5550ce4e0eb 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 | static unsigned int freq_div_hz; | ||
42 | static 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); |
@@ -199,9 +202,9 @@ static struct cyclecounter microblaze_cc = { | |||
199 | .shift = 8, | 202 | .shift = 8, |
200 | }; | 203 | }; |
201 | 204 | ||
202 | int __init init_microblaze_timecounter(void) | 205 | static 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()); |
@@ -214,16 +217,12 @@ static struct clocksource clocksource_microblaze = { | |||
214 | .rating = 300, | 217 | .rating = 300, |
215 | .read = microblaze_read, | 218 | .read = microblaze_read, |
216 | .mask = CLOCKSOURCE_MASK(32), | 219 | .mask = CLOCKSOURCE_MASK(32), |
217 | .shift = 8, /* I can shift it */ | ||
218 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 220 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
219 | }; | 221 | }; |
220 | 222 | ||
221 | static int __init microblaze_clocksource_init(void) | 223 | static int __init microblaze_clocksource_init(void) |
222 | { | 224 | { |
223 | clocksource_microblaze.mult = | 225 | if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq)) |
224 | clocksource_hz2mult(cpuinfo.cpu_clock_freq, | ||
225 | clocksource_microblaze.shift); | ||
226 | if (clocksource_register(&clocksource_microblaze)) | ||
227 | panic("failed to register clocksource"); | 226 | panic("failed to register clocksource"); |
228 | 227 | ||
229 | /* stop timer1 */ | 228 | /* stop timer1 */ |
@@ -247,6 +246,7 @@ void __init time_init(void) | |||
247 | u32 irq, i = 0; | 246 | u32 irq, i = 0; |
248 | u32 timer_num = 1; | 247 | u32 timer_num = 1; |
249 | struct device_node *timer = NULL; | 248 | struct device_node *timer = NULL; |
249 | const void *prop; | ||
250 | #ifdef CONFIG_SELFMOD_TIMER | 250 | #ifdef CONFIG_SELFMOD_TIMER |
251 | unsigned int timer_baseaddr = 0; | 251 | unsigned int timer_baseaddr = 0; |
252 | int arr_func[] = { | 252 | int arr_func[] = { |
@@ -258,12 +258,10 @@ void __init time_init(void) | |||
258 | 0 | 258 | 0 |
259 | }; | 259 | }; |
260 | #endif | 260 | #endif |
261 | char *timer_list[] = { | 261 | const char * const timer_list[] = { |
262 | "xlnx,xps-timer-1.00.a", | 262 | "xlnx,xps-timer-1.00.a", |
263 | "xlnx,opb-timer-1.00.b", | 263 | NULL |
264 | "xlnx,opb-timer-1.00.a", | 264 | }; |
265 | NULL | ||
266 | }; | ||
267 | 265 | ||
268 | for (i = 0; timer_list[i] != NULL; i++) { | 266 | for (i = 0; timer_list[i] != NULL; i++) { |
269 | timer = of_find_compatible_node(NULL, NULL, timer_list[i]); | 267 | timer = of_find_compatible_node(NULL, NULL, timer_list[i]); |
@@ -272,13 +270,13 @@ void __init time_init(void) | |||
272 | } | 270 | } |
273 | BUG_ON(!timer); | 271 | BUG_ON(!timer); |
274 | 272 | ||
275 | timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); | 273 | timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL)); |
276 | timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); | 274 | timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); |
277 | irq = *(int *) of_get_property(timer, "interrupts", NULL); | 275 | irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL)); |
278 | timer_num = | 276 | timer_num = be32_to_cpup(of_get_property(timer, |
279 | *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); | 277 | "xlnx,one-timer-only", NULL)); |
280 | if (timer_num) { | 278 | if (timer_num) { |
281 | printk(KERN_EMERG "Please enable two timers in HW\n"); | 279 | eprintk(KERN_EMERG "Please enable two timers in HW\n"); |
282 | BUG(); | 280 | BUG(); |
283 | } | 281 | } |
284 | 282 | ||
@@ -288,7 +286,14 @@ void __init time_init(void) | |||
288 | printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", | 286 | printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", |
289 | timer_list[i], timer_baseaddr, irq); | 287 | timer_list[i], timer_baseaddr, irq); |
290 | 288 | ||
291 | cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; | 289 | /* If there is clock-frequency property than use it */ |
290 | prop = of_get_property(timer, "clock-frequency", NULL); | ||
291 | if (prop) | ||
292 | timer_clock_freq = be32_to_cpup(prop); | ||
293 | else | ||
294 | timer_clock_freq = cpuinfo.cpu_clock_freq; | ||
295 | |||
296 | freq_div_hz = timer_clock_freq / HZ; | ||
292 | 297 | ||
293 | setup_irq(irq, &timer_irqaction); | 298 | setup_irq(irq, &timer_irqaction); |
294 | #ifdef CONFIG_HEART_BEAT | 299 | #ifdef CONFIG_HEART_BEAT |