1 #include <linux/clocksource.h>
2 #include <linux/errno.h>
3 #include <linux/hpet.h>
4 #include <linux/init.h>
9 #define HPET_MASK CLOCKSOURCE_MASK(32)
12 /* FSEC = 10^-15 NSEC = 10^-9 */
13 #define FSEC_PER_NSEC 1000000
15 static void *hpet_ptr
;
17 static cycle_t
read_hpet(void)
19 return (cycle_t
)readl(hpet_ptr
);
22 static struct clocksource clocksource_hpet
= {
27 .mult
= 0, /* set below */
32 static int __init
init_hpet_clocksource(void)
34 unsigned long hpet_period
;
35 void __iomem
* hpet_base
;
38 if (!is_hpet_enabled())
41 /* calculate the hpet address: */
43 (void __iomem
*)ioremap_nocache(hpet_address
, HPET_MMAP_SIZE
);
44 hpet_ptr
= hpet_base
+ HPET_COUNTER
;
46 /* calculate the frequency: */
47 hpet_period
= readl(hpet_base
+ HPET_PERIOD
);
50 * hpet period is in femto seconds per cycle
51 * so we need to convert this to ns/cyc units
52 * aproximated by mult/2^shift
54 * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
55 * fsec/cyc * 1ns/1000000fsec * 2^shift = mult
56 * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
57 * (fsec/cyc << shift)/1000000 = mult
58 * (hpet_period << shift)/FSEC_PER_NSEC = mult
60 tmp
= (u64
)hpet_period
<< HPET_SHIFT
;
61 do_div(tmp
, FSEC_PER_NSEC
);
62 clocksource_hpet
.mult
= (u32
)tmp
;
64 return clocksource_register(&clocksource_hpet
);
67 module_init(init_hpet_clocksource
);