diff options
Diffstat (limited to 'arch/i386/kernel/hpet.c')
-rw-r--r-- | arch/i386/kernel/hpet.c | 80 |
1 files changed, 37 insertions, 43 deletions
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c index e1006b7acc9e..f3ab61ee7498 100644 --- a/arch/i386/kernel/hpet.c +++ b/arch/i386/kernel/hpet.c | |||
@@ -201,12 +201,30 @@ static int hpet_next_event(unsigned long delta, | |||
201 | } | 201 | } |
202 | 202 | ||
203 | /* | 203 | /* |
204 | * Clock source related code | ||
205 | */ | ||
206 | static cycle_t read_hpet(void) | ||
207 | { | ||
208 | return (cycle_t)hpet_readl(HPET_COUNTER); | ||
209 | } | ||
210 | |||
211 | static struct clocksource clocksource_hpet = { | ||
212 | .name = "hpet", | ||
213 | .rating = 250, | ||
214 | .read = read_hpet, | ||
215 | .mask = HPET_MASK, | ||
216 | .shift = HPET_SHIFT, | ||
217 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
218 | }; | ||
219 | |||
220 | /* | ||
204 | * Try to setup the HPET timer | 221 | * Try to setup the HPET timer |
205 | */ | 222 | */ |
206 | int __init hpet_enable(void) | 223 | int __init hpet_enable(void) |
207 | { | 224 | { |
208 | unsigned long id; | 225 | unsigned long id; |
209 | uint64_t hpet_freq; | 226 | uint64_t hpet_freq; |
227 | u64 tmp; | ||
210 | 228 | ||
211 | if (!is_hpet_capable()) | 229 | if (!is_hpet_capable()) |
212 | return 0; | 230 | return 0; |
@@ -253,6 +271,25 @@ int __init hpet_enable(void) | |||
253 | /* Start the counter */ | 271 | /* Start the counter */ |
254 | hpet_start_counter(); | 272 | hpet_start_counter(); |
255 | 273 | ||
274 | /* Initialize and register HPET clocksource | ||
275 | * | ||
276 | * hpet period is in femto seconds per cycle | ||
277 | * so we need to convert this to ns/cyc units | ||
278 | * aproximated by mult/2^shift | ||
279 | * | ||
280 | * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift | ||
281 | * fsec/cyc * 1ns/1000000fsec * 2^shift = mult | ||
282 | * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult | ||
283 | * (fsec/cyc << shift)/1000000 = mult | ||
284 | * (hpet_period << shift)/FSEC_PER_NSEC = mult | ||
285 | */ | ||
286 | tmp = (u64)hpet_period << HPET_SHIFT; | ||
287 | do_div(tmp, FSEC_PER_NSEC); | ||
288 | clocksource_hpet.mult = (u32)tmp; | ||
289 | |||
290 | clocksource_register(&clocksource_hpet); | ||
291 | |||
292 | |||
256 | if (id & HPET_ID_LEGSUP) { | 293 | if (id & HPET_ID_LEGSUP) { |
257 | hpet_enable_int(); | 294 | hpet_enable_int(); |
258 | hpet_reserve_platform_timers(id); | 295 | hpet_reserve_platform_timers(id); |
@@ -273,49 +310,6 @@ out_nohpet: | |||
273 | return 0; | 310 | return 0; |
274 | } | 311 | } |
275 | 312 | ||
276 | /* | ||
277 | * Clock source related code | ||
278 | */ | ||
279 | static cycle_t read_hpet(void) | ||
280 | { | ||
281 | return (cycle_t)hpet_readl(HPET_COUNTER); | ||
282 | } | ||
283 | |||
284 | static struct clocksource clocksource_hpet = { | ||
285 | .name = "hpet", | ||
286 | .rating = 250, | ||
287 | .read = read_hpet, | ||
288 | .mask = HPET_MASK, | ||
289 | .shift = HPET_SHIFT, | ||
290 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
291 | }; | ||
292 | |||
293 | static int __init init_hpet_clocksource(void) | ||
294 | { | ||
295 | u64 tmp; | ||
296 | |||
297 | if (!hpet_virt_address) | ||
298 | return -ENODEV; | ||
299 | |||
300 | /* | ||
301 | * hpet period is in femto seconds per cycle | ||
302 | * so we need to convert this to ns/cyc units | ||
303 | * aproximated by mult/2^shift | ||
304 | * | ||
305 | * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift | ||
306 | * fsec/cyc * 1ns/1000000fsec * 2^shift = mult | ||
307 | * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult | ||
308 | * (fsec/cyc << shift)/1000000 = mult | ||
309 | * (hpet_period << shift)/FSEC_PER_NSEC = mult | ||
310 | */ | ||
311 | tmp = (u64)hpet_period << HPET_SHIFT; | ||
312 | do_div(tmp, FSEC_PER_NSEC); | ||
313 | clocksource_hpet.mult = (u32)tmp; | ||
314 | |||
315 | return clocksource_register(&clocksource_hpet); | ||
316 | } | ||
317 | |||
318 | module_init(init_hpet_clocksource); | ||
319 | 313 | ||
320 | #ifdef CONFIG_HPET_EMULATE_RTC | 314 | #ifdef CONFIG_HPET_EMULATE_RTC |
321 | 315 | ||