aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel/timer.c')
-rw-r--r--arch/microblaze/kernel/timer.c47
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
41static unsigned int freq_div_hz;
42static 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 = {
168static __init void microblaze_clockevent_init(void) 171static __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
202int __init init_microblaze_timecounter(void) 205static 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(&microblaze_tc, &microblaze_cc, sched_clock()); 210 timecounter_init(&microblaze_tc, &microblaze_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
221static int __init microblaze_clocksource_init(void) 223static 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