/*
 * apb_timer.c: Driver for Langwell APB timers
 *
 * (C) Copyright 2009 Intel Corporation
 * Author: Jacob Pan (jacob.jun.pan@intel.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 *
 * Note:
 * Langwell is the south complex of Intel Moorestown MID platform. There are
 * eight external timers in total that can be used by the operating system.
 * The timer information, such as frequency and addresses, is provided to the
 * OS via SFI tables.
 * Timer interrupts are routed via FW/HW emulated IOAPIC independently via
 * individual redirection table entries (RTE).
 * Unlike HPET, there is no master counter, therefore one of the timers are
 * used as clocksource. The overall allocation looks like:
 *  - timer 0 - NR_CPUs for per cpu timer
 *  - one timer for clocksource
 *  - one timer for watchdog driver.
 * It is also worth notice that APB timer does not support true one-shot mode,
 * free-running mode will be used here to emulate one-shot mode.
 * APB timer can also be used as broadcast timer along with per cpu local APIC
 * timer, but by default APB timer has higher rating than local APIC timers.
 */

#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/sfi.h>
#include <linux/interrupt.h>
#include <linux/cpu.h>
#include <linux/irq.h>

#include <asm/fixmap.h>
#include <asm/apb_timer.h>

#define APBT_MASK			CLOCKSOURCE_MASK(32)
#define APBT_SHIFT			22
#define APBT_CLOCKEVENT_RATING		150
#define APBT_CLOCKSOURCE_RATING		250
#define APBT_MIN_DELTA_USEC		200

#define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt)
#define APBT_CLOCKEVENT0_NUM   (0)
#define APBT_CLOCKEVENT1_NUM   (1)
#define APBT_CLOCKSOURCE_NUM   (2)

static unsigned long apbt_address;
static int apb_timer_block_enabled;
static void __iomem *apbt_virt_address;
static int phy_cs_timer_id;

/*
 * Common DW APB timer info
 */
static uint64_t apbt_freq;

static void apbt_set_mode(enum clock_event_mode mode,
			  struct clock_event_device *evt);
static int apbt_next_event(unsigned long delta,
			   struct clock_event_device *evt);
static cycle_t apbt_read_clocksource(struct clocksource *cs);
static void apbt_restart_clocksource(struct clocksource *cs);

struct apbt_dev {
	struct clock_event_device evt;
	unsigned int num;
	int cpu;
	unsigned int irq;
	unsigned int tick;
	unsigned int count;
	unsigned int flags;
	char name[10];
};

int disable_apbt_percpu __cpuinitdata;

static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);

#ifdef CONFIG_SMP
static unsigned int apbt_num_timers_used;
static struct apbt_dev *apbt_devs;
#endif

static	inline unsigned long apbt_readl_reg(unsigned long a)
{
	return readl(apbt_virt_address + a);
}

static inline void apbt_writel_reg(unsigned long d, unsigned long a)
{
	writel(d, apbt_virt_address + a);
}

static inline unsigned long apbt_readl(int n, unsigned long a)
{
	return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE);
}

static inline void apbt_writel(int n, unsigned long d, unsigned long a)
{
	writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE);
}

static inline void apbt_set_mapping(void)
{
	struct sfi_timer_table_entry *mtmr;

	if (apbt_virt_address) {
		pr_debug("APBT base already mapped\n");
		return;
	}
	mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
	if (mtmr == NULL) {
		printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
		       APBT_CLOCKEVENT0_NUM);
		return;
	}
	apbt_address = (unsigned long)mtmr->phys_addr;
	if (!apbt_address) {
		printk(KERN_WARNING "No timer base from SFI, use default\n");
		apbt_address = APBT_DEFAULT_BASE;
	}
	apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE);
	if (apbt_virt_address) {
		pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\
			 (void *)apbt_address, (void *)apbt_virt_address);
	} else {
		pr_debug("Failed mapping APBT phy address at %p\n",\
			 (void *)apbt_address);
		goto panic_noapbt;
	}
	apbt_freq = mtmr->freq_hz / USEC_PER_SEC;
	sfi_free_mtmr(mtmr);

	/* Now figure out the physical timer id for clocksource device */
	mtmr = sfi_get_mtmr(APBT_CLOCKSOURCE_NUM);
	if (mtmr == NULL)
		goto panic_noapbt;

	/* Now figure out the physical timer id */
	phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff)
		/ APBTMRS_REG_SIZE;
	pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id);
	return;

panic_noapbt:
	panic("Failed to setup APB system timer\n");

}

static inline void apbt_clear_mapping(void)
{
	iounmap(apbt_virt_address);
	apbt_virt_address = NULL;
}

/*
 * APBT timer interrupt enable / disable
 */
static inline int is_apbt_capable(void)
{
	return apbt_virt_address ? 1 : 0;
}

static struct clocksource clocksource_apbt = {
	.name		= "apbt",
	.rating		= APBT_CLOCKSOURCE_RATING,
	.read		= apbt_read_clocksource,
	.mask		= APBT_MASK,
	.shift		= APBT_SHIFT,
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
	.resume		= apbt_restart_clocksource,
};

/* boot APB clock event device */
static struct clock_event_device apbt_clockevent = {
	.name		= "apbt0",
	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
	.set_mode	= apbt_set_mode,
	.set_next_event = apbt_next_event,
	.shift		= APBT_SHIFT,
	.irq		= 0,
	.rating		= APBT_CLOCKEVENT_RATING,
};

/*
 * if user does not want to use per CPU apb timer, just give it a lower rating
 * than local apic timer and skip the late per cpu timer init.
 */
static inline int __init setup_x86_mrst_timer(char *arg)
{
	if (!arg)
		return -EINVAL;

	if (strcmp("apbt_only", arg) == 0)
		disable_apbt_percpu = 0;
	else if (strcmp("lapic_and_apbt", arg) == 0)
		disable_apbt_percpu = 1;
	else {
		pr_warning("X86 MRST timer option %s not recognised"
			   " use x86_mrst_timer=apbt_only or lapic_and_apbt\n",
			   arg);
		return -EINVAL;
	}
	return 0;
}
__setup("x86_mrst_timer=", setup_x86_mrst_timer);

/*
 * start count down from 0xffff_ffff. this is done by toggling the enable bit
 * then load initial load count to ~0.
 */
static void apbt_start_counter(int n)
{
	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);

	ctrl &= ~APBTMR_CONTROL_ENABLE;
	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
	apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT);
	/* enable, mask interrupt */
	ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
	ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
	/* read it once to get cached counter value initialized */
	apbt_read_clocksource(&clocksource_apbt);
}

static irqreturn_t apbt_interrupt_handler(int irq, void *data)
{
	struct apbt_dev *dev = (struct apbt_dev *)data;
	struct clock_event_device *aevt = &dev->evt;

	if (!aevt->event_handler) {
		printk(KERN_INFO "Spurious APBT timer interrupt on %d\n",
		       dev->num);
		return IRQ_NONE;
	}
	aevt->event_handler(aevt);
	return IRQ_HANDLED;
}

static void apbt_restart_clocksource(struct clocksource *cs)
{
	apbt_start_counter(phy_cs_timer_id);
}

/* Setup IRQ routing via IOAPIC */
#ifdef CONFIG_SMP
static void apbt_setup_irq(struct apbt_dev *adev)
{
	struct irq_chip *chip;
	struct irq_desc *desc;

	/* timer0 irq has been setup early */
	if (adev->irq == 0)
		return;
	desc = irq_to_desc(adev->irq);
	chip = get_irq_chip(adev->irq);
	disable_irq(adev->irq);
	desc->status |= IRQ_MOVE_PCNTXT;
	irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
	/* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
	set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
	enable_irq(adev->irq);
	if (system_state == SYSTEM_BOOTING)
		if (request_irq(adev->irq, apbt_interrupt_handler,
				IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
				adev->name, adev)) {
			printk(KERN_ERR "Failed request IRQ for APBT%d\n",
			       adev->num);
		}
}
#endif

static void apbt_enable_int(int n)
{
	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
	/* clear pending intr */
	apbt_readl(n, APBTMR_N_EOI);
	ctrl &= ~APBTMR_CONTROL_INT;
	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
}

static void apbt_disable_int(int n)
{
	unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);

	ctrl |= APBTMR_CONTROL_INT;
	apbt_writel(n, ctrl, APBTMR_N_CONTROL);
}


static int __init apbt_clockevent_register(void)
{
	struct sfi_timer_table_entry *mtmr;
	struct apbt_dev *adev = &__get_cpu_var(cpu_apbt_dev);

	mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
	if (mtmr == NULL) {
		printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
		       APBT_CLOCKEVENT0_NUM);
		return -ENODEV;
	}

	/*
	 * We need to calculate the scaled math multiplication factor for
	 * nanosecond to apbt tick conversion.
	 * mult = (nsec/cycle)*2^APBT_SHIFT
	 */
	apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq_hz
				      , NSEC_PER_SEC, APBT_SHIFT);

	/* Calculate the min / max delta */
	apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
							   &apbt_clockevent);
	apbt_clockevent.min_delta_ns = clockevent_delta2ns(
		APBT_MIN_DELTA_USEC*apbt_freq,
		&apbt_clockevent);
	/*
	 * Start apbt with the boot cpu mask and make it
	 * global if not used for per cpu timer.
	 */
	apbt_clockevent.cpumask = cpumask_of(smp_processor_id());
	adev->num = smp_processor_id();
	memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device));

	if (disable_apbt_percpu) {
		apbt_clockevent.rating = APBT_CLOCKEVENT_RATING - 100;
		global_clock_event = &adev->evt;
		printk(KERN_DEBUG "%s clockevent registered as global\n",
		       global_clock_event->name);
	}

	if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler,
			IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
			apbt_clockevent.name, adev)) {
		printk(KERN_ERR "Failed request IRQ for APBT%d\n",
		       apbt_clockevent.irq);
	}

	clockevents_register_device(&adev->evt);
	/* Start APBT 0 interrupts */
	apbt_enable_int(APBT_CLOCKEVENT0_NUM);

	sfi_free_mtmr(mtmr);
	return 0;
}

#ifdef CONFIG_SMP
/* Should be called with per cpu */
void apbt_setup_secondary_clock(void)
{
	struct apbt_dev *adev;
	struct clock_event_device *aevt;
	int cpu;

	/* Don't register boot CPU clockevent */
	cpu = smp_processor_id();
	if (cpu == boot_cpu_id)
		return;
	/*
	 * We need to calculate the scaled math multiplication factor for
	 * nanosecond to apbt tick conversion.
	 * mult = (nsec/cycle)*2^APBT_SHIFT
	 */
	printk(KERN_INFO "Init per CPU clockevent %d\n", cpu);
	adev = &per_cpu(cpu_apbt_dev, cpu);
	aevt = &adev->evt;

	memcpy(aevt, &apbt_clockevent, sizeof(*aevt));
	aevt->cpumask = cpumask_of(cpu);
	aevt->name = adev->name;
	aevt->mode = CLOCK_EVT_MODE_UNUSED;

	printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n",
	       cpu, aevt->name, *(u32 *)aevt->cpumask);

	apbt_setup_irq(adev);

	clockevents_register_device(aevt);

	apbt_enable_int(cpu);

	return;
}

/*
 * this notify handler process CPU hotplug events. in case of S0i3, nonboot
 * cpus are disabled/enabled frequently, for performance reasons, we keep the
 * per cpu timer irq registered so that we do need to do free_irq/request_irq.
 *
 * TODO: it might be more reliable to directly disable percpu clockevent device
 * without the notifier chain. currently, cpu 0 may get interrupts from other
 * cpu timers during the offline process due to the ordering of notification.
 * the extra interrupt is harmless.
 */
static int apbt_cpuhp_notify(struct notifier_block *n,
			     unsigned long action, void *hcpu)
{
	unsigned long cpu = (unsigned long)hcpu;
	struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);

	switch (action & 0xf) {
	case CPU_DEAD:
		apbt_disable_int(cpu);
		if (system_state == SYSTEM_RUNNING)
			pr_debug("skipping APBT CPU %lu offline\n", cpu);
		else if (adev) {
			pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
			free_irq(adev->irq, adev);
		}
		break;
	default:
		pr_debug(KERN_INFO "APBT notified %lu, no action\n", action);
	}
	return NOTIFY_OK;
}

static __init int apbt_late_init(void)
{
	if (disable_apbt_percpu || !apb_timer_block_enabled)
		return 0;
	/* This notifier should be called after workqueue is ready */
	hotcpu_notifier(apbt_cpuhp_notify, -20);
	return 0;
}
fs_initcall(apbt_late_init);
#else

void apbt_setup_secondary_clock(void) {}

#endif /* CONFIG_SMP */

static void apbt_set_mode(enum clock_event_mode mode,
			  struct clock_event_device *evt)
{
	unsigned long ctrl;
	uint64_t delta;
	int timer_num;
	struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);

	timer_num = adev->num;
	pr_debug("%s CPU %d timer %d mode=%d\n",
		 __func__, first_cpu(*evt->cpumask), timer_num, mode);

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult;
		delta >>= apbt_clockevent.shift;
		ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
		ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
		/*
		 * DW APB p. 46, have to disable timer before load counter,
		 * may cause sync problem.
		 */
		ctrl &= ~APBTMR_CONTROL_ENABLE;
		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
		udelay(1);
		pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ);
		apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
		ctrl |= APBTMR_CONTROL_ENABLE;
		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
		break;
		/* APB timer does not have one-shot mode, use free running mode */
	case CLOCK_EVT_MODE_ONESHOT:
		ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
		/*
		 * set free running mode, this mode will let timer reload max
		 * timeout which will give time (3min on 25MHz clock) to rearm
		 * the next event, therefore emulate the one-shot mode.
		 */
		ctrl &= ~APBTMR_CONTROL_ENABLE;
		ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;

		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
		/* write again to set free running mode */
		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);

		/*
		 * DW APB p. 46, load counter with all 1s before starting free
		 * running mode.
		 */
		apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT);
		ctrl &= ~APBTMR_CONTROL_INT;
		ctrl |= APBTMR_CONTROL_ENABLE;
		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
		break;

	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_SHUTDOWN:
		apbt_disable_int(timer_num);
		ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
		ctrl &= ~APBTMR_CONTROL_ENABLE;
		apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
		break;

	case CLOCK_EVT_MODE_RESUME:
		apbt_enable_int(timer_num);
		break;
	}
}

static int apbt_next_event(unsigned long delta,
			   struct clock_event_device *evt)
{
	unsigned long ctrl;
	int timer_num;

	struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);

	timer_num = adev->num;
	/* Disable timer */
	ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
	ctrl &= ~APBTMR_CONTROL_ENABLE;
	apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
	/* write new count */
	apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
	ctrl |= APBTMR_CONTROL_ENABLE;
	apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
	return 0;
}

/*
 * APB timer clock is not in sync with pclk on Langwell, which translates to
 * unreliable read value caused by sampling error. the error does not add up
 * overtime and only happens when sampling a 0 as a 1 by mistake. so the time
 * would go backwards. the following code is trying to prevent time traveling
 * backwards. little bit paranoid.
 */
static cycle_t apbt_read_clocksource(struct clocksource *cs)
{
	unsigned long t0, t1, t2;
	static unsigned long last_read;

bad_count:
	t1 = apbt_readl(phy_cs_timer_id,
			APBTMR_N_CURRENT_VALUE);
	t2 = apbt_readl(phy_cs_timer_id,
			APBTMR_N_CURRENT_VALUE);
	if (unlikely(t1 < t2)) {
		pr_debug("APBT: read current count error %lx:%lx:%lx\n",
			 t1, t2, t2 - t1);
		goto bad_count;
	}
	/*
	 * check against cached last read, makes sure time does not go back.
	 * it could be a normal rollover but we will do tripple check anyway
	 */
	if (unlikely(t2 > last_read)) {
		/* check if we have a normal rollover */
		unsigned long raw_intr_status =
			apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
		/*
		 * cs timer interrupt is masked but raw intr bit is set if
		 * rollover occurs. then we read EOI reg to clear it.
		 */
		if (raw_intr_status & (1 << phy_cs_timer_id)) {
			apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
			goto out;
		}
		pr_debug("APB CS going back %lx:%lx:%lx ",
			 t2, last_read, t2 - last_read);
bad_count_x3:
		pr_debug(KERN_INFO "tripple check enforced\n");
		t0 = apbt_readl(phy_cs_timer_id,
				APBTMR_N_CURRENT_VALUE);
		udelay(1);
		t1 = apbt_readl(phy_cs_timer_id,
				APBTMR_N_CURRENT_VALUE);
		udelay(1);
		t2 = apbt_readl(phy_cs_timer_id,
				APBTMR_N_CURRENT_VALUE);
		if ((t2 > t1) || (t1 > t0)) {
			printk(KERN_ERR "Error: APB CS tripple check failed\n");
			goto bad_count_x3;
		}
	}
out:
	last_read = t2;
	return (cycle_t)~t2;
}

static int apbt_clocksource_register(void)
{
	u64 start, now;
	cycle_t t1;

	/* Start the counter, use timer 2 as source, timer 0/1 for event */
	apbt_start_counter(phy_cs_timer_id);

	/* Verify whether apbt counter works */
	t1 = apbt_read_clocksource(&clocksource_apbt);
	rdtscll(start);

	/*
	 * We don't know the TSC frequency yet, but waiting for
	 * 200000 TSC cycles is safe:
	 * 4 GHz == 50us
	 * 1 GHz == 200us
	 */
	do {
		rep_nop();
		rdtscll(now);
	} while ((now - start) < 200000UL);

	/* APBT is the only always on clocksource, it has to work! */
	if (t1 == apbt_read_clocksource(&clocksource_apbt))
		panic("APBT counter not counting. APBT disabled\n");

	/*
	 * initialize and register APBT clocksource
	 * convert that to ns/clock cycle
	 * mult = (ns/c) * 2^APBT_SHIFT
	 */
	clocksource_apbt.mult = div_sc(MSEC_PER_SEC,
				       (unsigned long) apbt_freq, APBT_SHIFT);
	clocksource_register(&clocksource_apbt);

	return 0;
}

/*
 * Early setup the APBT timer, only use timer 0 for booting then switch to
 * per CPU timer if possible.
 * returns 1 if per cpu apbt is setup
 * returns 0 if no per cpu apbt is chosen
 * panic if set up failed, this is the only platform timer on Moorestown.
 */
void __init apbt_time_init(void)
{
#ifdef CONFIG_SMP
	int i;
	struct sfi_timer_table_entry *p_mtmr;
	unsigned int percpu_timer;
	struct apbt_dev *adev;
#endif

	if (apb_timer_block_enabled)
		return;
	apbt_set_mapping();
	if (apbt_virt_address) {
		pr_debug("Found APBT version 0x%lx\n",\
			 apbt_readl_reg(APBTMRS_COMP_VERSION));
	} else
		goto out_noapbt;
	/*
	 * Read the frequency and check for a sane value, for ESL model
	 * we extend the possible clock range to allow time scaling.
	 */

	if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
		pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq);
		goto out_noapbt;
	}
	if (apbt_clocksource_register()) {
		pr_debug("APBT has failed to register clocksource\n");
		goto out_noapbt;
	}
	if (!apbt_clockevent_register())
		apb_timer_block_enabled = 1;
	else {
		pr_debug("APBT has failed to register clockevent\n");
		goto out_noapbt;
	}
#ifdef CONFIG_SMP
	/* kernel cmdline disable apb timer, so we will use lapic timers */
	if (disable_apbt_percpu) {
		printk(KERN_INFO "apbt: disabled per cpu timer\n");
		return;
	}
	pr_debug("%s: %d CPUs online\n", __func__, num_online_cpus());
	if (num_possible_cpus() <= sfi_mtimer_num) {
		percpu_timer = 1;
		apbt_num_timers_used = num_possible_cpus();
	} else {
		percpu_timer = 0;
		apbt_num_timers_used = 1;
		adev = &per_cpu(cpu_apbt_dev, 0);
		adev->flags &= ~APBT_DEV_USED;
	}
	pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used);

	/* here we set up per CPU timer data structure */
	apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used,
			    GFP_KERNEL);
	if (!apbt_devs) {
		printk(KERN_ERR "Failed to allocate APB timer devices\n");
		return;
	}
	for (i = 0; i < apbt_num_timers_used; i++) {
		adev = &per_cpu(cpu_apbt_dev, i);
		adev->num = i;
		adev->cpu = i;
		p_mtmr = sfi_get_mtmr(i);
		if (p_mtmr) {
			adev->tick = p_mtmr->freq_hz;
			adev->irq = p_mtmr->irq;
		} else
			printk(KERN_ERR "Failed to get timer for cpu %d\n", i);
		adev->count = 0;
		sprintf(adev->name, "apbt%d", i);
	}
#endif

	return;

out_noapbt:
	apbt_clear_mapping();
	apb_timer_block_enabled = 0;
	panic("failed to enable APB timer\n");
}

static inline void apbt_disable(int n)
{
	if (is_apbt_capable()) {
		unsigned long ctrl =  apbt_readl(n, APBTMR_N_CONTROL);
		ctrl &= ~APBTMR_CONTROL_ENABLE;
		apbt_writel(n, ctrl, APBTMR_N_CONTROL);
	}
}

/* called before apb_timer_enable, use early map */
unsigned long apbt_quick_calibrate()
{
	int i, scale;
	u64 old, new;
	cycle_t t1, t2;
	unsigned long khz = 0;
	u32 loop, shift;

	apbt_set_mapping();
	apbt_start_counter(phy_cs_timer_id);

	/* check if the timer can count down, otherwise return */
	old = apbt_read_clocksource(&clocksource_apbt);
	i = 10000;
	while (--i) {
		if (old != apbt_read_clocksource(&clocksource_apbt))
			break;
	}
	if (!i)
		goto failed;

	/* count 16 ms */
	loop = (apbt_freq * 1000) << 4;

	/* restart the timer to ensure it won't get to 0 in the calibration */
	apbt_start_counter(phy_cs_timer_id);

	old = apbt_read_clocksource(&clocksource_apbt);
	old += loop;

	t1 = __native_read_tsc();

	do {
		new = apbt_read_clocksource(&clocksource_apbt);
	} while (new < old);

	t2 = __native_read_tsc();

	shift = 5;
	if (unlikely(loop >> shift == 0)) {
		printk(KERN_INFO
		       "APBT TSC calibration failed, not enough resolution\n");
		return 0;
	}
	scale = (int)div_u64((t2 - t1), loop >> shift);
	khz = (scale * apbt_freq * 1000) >> shift;
	printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz);
	return khz;
failed:
	return 0;
}
