diff options
Diffstat (limited to 'arch/microblaze/kernel/timer.c')
-rw-r--r-- | arch/microblaze/kernel/timer.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index ed61b2f17719..b1380ae93ae1 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <linux/cnt32_to_63.h> | ||
31 | 32 | ||
32 | #ifdef CONFIG_SELFMOD_TIMER | 33 | #ifdef CONFIG_SELFMOD_TIMER |
33 | #include <asm/selfmod.h> | 34 | #include <asm/selfmod.h> |
@@ -135,7 +136,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode, | |||
135 | static struct clock_event_device clockevent_microblaze_timer = { | 136 | static struct clock_event_device clockevent_microblaze_timer = { |
136 | .name = "microblaze_clockevent", | 137 | .name = "microblaze_clockevent", |
137 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, | 138 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, |
138 | .shift = 24, | 139 | .shift = 8, |
139 | .rating = 300, | 140 | .rating = 300, |
140 | .set_next_event = microblaze_timer_set_next_event, | 141 | .set_next_event = microblaze_timer_set_next_event, |
141 | .set_mode = microblaze_timer_set_mode, | 142 | .set_mode = microblaze_timer_set_mode, |
@@ -195,7 +196,7 @@ static cycle_t microblaze_cc_read(const struct cyclecounter *cc) | |||
195 | static struct cyclecounter microblaze_cc = { | 196 | static struct cyclecounter microblaze_cc = { |
196 | .read = microblaze_cc_read, | 197 | .read = microblaze_cc_read, |
197 | .mask = CLOCKSOURCE_MASK(32), | 198 | .mask = CLOCKSOURCE_MASK(32), |
198 | .shift = 24, | 199 | .shift = 8, |
199 | }; | 200 | }; |
200 | 201 | ||
201 | int __init init_microblaze_timecounter(void) | 202 | int __init init_microblaze_timecounter(void) |
@@ -213,7 +214,7 @@ static struct clocksource clocksource_microblaze = { | |||
213 | .rating = 300, | 214 | .rating = 300, |
214 | .read = microblaze_read, | 215 | .read = microblaze_read, |
215 | .mask = CLOCKSOURCE_MASK(32), | 216 | .mask = CLOCKSOURCE_MASK(32), |
216 | .shift = 24, /* I can shift it */ | 217 | .shift = 8, /* I can shift it */ |
217 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 218 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
218 | }; | 219 | }; |
219 | 220 | ||
@@ -235,6 +236,12 @@ static int __init microblaze_clocksource_init(void) | |||
235 | return 0; | 236 | return 0; |
236 | } | 237 | } |
237 | 238 | ||
239 | /* | ||
240 | * We have to protect accesses before timer initialization | ||
241 | * and return 0 for sched_clock function below. | ||
242 | */ | ||
243 | static int timer_initialized; | ||
244 | |||
238 | void __init time_init(void) | 245 | void __init time_init(void) |
239 | { | 246 | { |
240 | u32 irq, i = 0; | 247 | u32 irq, i = 0; |
@@ -289,4 +296,15 @@ void __init time_init(void) | |||
289 | #endif | 296 | #endif |
290 | microblaze_clocksource_init(); | 297 | microblaze_clocksource_init(); |
291 | microblaze_clockevent_init(); | 298 | microblaze_clockevent_init(); |
299 | timer_initialized = 1; | ||
300 | } | ||
301 | |||
302 | unsigned long long notrace sched_clock(void) | ||
303 | { | ||
304 | if (timer_initialized) { | ||
305 | struct clocksource *cs = &clocksource_microblaze; | ||
306 | cycle_t cyc = cnt32_to_63(cs->read(NULL)); | ||
307 | return clocksource_cyc2ns(cyc, cs->mult, cs->shift); | ||
308 | } | ||
309 | return 0; | ||
292 | } | 310 | } |