32 #include <linux/errno.h>
34 #include <linux/slab.h>
41 #include <asm/fixmap.h>
46 #define APBT_CLOCKEVENT_RATING 110
47 #define APBT_CLOCKSOURCE_RATING 250
49 #define APBT_CLOCKEVENT0_NUM (0)
50 #define APBT_CLOCKSOURCE_NUM (2)
53 static int apb_timer_block_enabled;
54 static void __iomem *apbt_virt_address;
59 static unsigned long apbt_freq;
79 static unsigned int apbt_num_timers_used;
82 static inline void apbt_set_mapping(
void)
85 int phy_cs_timer_id = 0;
87 if (apbt_virt_address) {
88 pr_debug(
"APBT base already mapped\n");
100 apbt_address = APBT_DEFAULT_BASE;
103 if (!apbt_virt_address) {
104 pr_debug(
"Failed mapping APBT phy address at %lu\n",\
105 (
unsigned long)apbt_address);
117 pr_debug(
"Use timer %d for clocksource\n",
119 phy_cs_timer_id = (
unsigned int)(mtmr->
phys_addr & 0xff) /
123 "apbt0", apbt_virt_address + phy_cs_timer_id *
128 panic(
"Failed to setup APB system timer\n");
132 static inline void apbt_clear_mapping(
void)
135 apbt_virt_address =
NULL;
141 static inline int is_apbt_capable(
void)
143 return apbt_virt_address ? 1 : 0;
146 static int __init apbt_clockevent_register(
void)
162 adev_virt_addr(adev), 0, apbt_freq);
180 static void apbt_setup_irq(
struct apbt_dev *adev)
207 adev->
irq, apbt_freq);
213 printk(
KERN_INFO "Registering CPU %d clockevent device %s, cpu %08x\n",
216 apbt_setup_irq(adev);
233 unsigned long action,
void *hcpu)
235 unsigned long cpu = (
unsigned long)hcpu;
238 switch (action & 0xf) {
242 pr_debug(
"skipping APBT CPU %lu offline\n", cpu);
244 pr_debug(
"APBT clockevent for cpu %lu offline\n", cpu);
249 pr_debug(
"APBT notified %lu, no action\n", action);
254 static __init int apbt_late_init(
void)
257 !apb_timer_block_enabled)
270 static int apbt_clocksource_register(
void)
291 }
while ((now - start) < 200000
UL);
295 panic(
"APBT counter not counting. APBT disabled\n");
314 unsigned int percpu_timer;
318 if (apb_timer_block_enabled)
321 if (!apbt_virt_address)
328 if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
329 pr_debug(
"APBT has invalid freq 0x%lx\n", apbt_freq);
332 if (apbt_clocksource_register()) {
333 pr_debug(
"APBT has failed to register clocksource\n");
336 if (!apbt_clockevent_register())
337 apb_timer_block_enabled = 1;
339 pr_debug(
"APBT has failed to register clockevent\n");
354 apbt_num_timers_used = 1;
356 pr_debug(
"%s: %d APB timers used\n", __func__, apbt_num_timers_used);
359 for (i = 0; i < apbt_num_timers_used; i++) {
360 adev = &
per_cpu(cpu_apbt_dev, i);
375 apbt_clear_mapping();
376 apb_timer_block_enabled = 0;
377 panic(
"failed to enable APB timer\n");
386 unsigned long khz = 0;
403 loop = (apbt_freq / 1000) << 4;
411 t1 = __native_read_tsc();
417 t2 = __native_read_tsc();
422 "APBT TSC calibration failed, not enough resolution\n");
425 scale = (
int)div_u64((t2 - t1), loop >> shift);
426 khz = (scale * (apbt_freq / 1000)) >> shift;
427 printk(
KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz);