Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 610bf2f1 authored by Venki Pallipadi's avatar Venki Pallipadi Committed by Thomas Gleixner
Browse files

x86: HPET restructure hpet code for hpet force enable



Restructure and rename legacy replacement mode HPET timer support.  Just the
code structural changes and should be zero functionality change.

Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Andi Kleen <ak@suse.de>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarArjan van de Ven <arjan@linux.intel.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 4a93232d
Loading
Loading
Loading
Loading
+83 −65
Original line number Diff line number Diff line
@@ -149,9 +149,9 @@ static void hpet_reserve_platform_timers(unsigned long id) { }
 */
static unsigned long hpet_period;

static void hpet_set_mode(enum clock_event_mode mode,
static void hpet_legacy_set_mode(enum clock_event_mode mode,
			  struct clock_event_device *evt);
static int hpet_next_event(unsigned long delta,
static int hpet_legacy_next_event(unsigned long delta,
			   struct clock_event_device *evt);

/*
@@ -160,8 +160,8 @@ static int hpet_next_event(unsigned long delta,
static struct clock_event_device hpet_clockevent = {
	.name		= "hpet",
	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
	.set_mode	= hpet_set_mode,
	.set_next_event = hpet_next_event,
	.set_mode	= hpet_legacy_set_mode,
	.set_next_event = hpet_legacy_next_event,
	.shift		= 32,
	.irq		= 0,
};
@@ -178,7 +178,7 @@ static void hpet_start_counter(void)
	hpet_writel(cfg, HPET_CFG);
}

static void hpet_enable_int(void)
static void hpet_enable_legacy_int(void)
{
	unsigned long cfg = hpet_readl(HPET_CFG);

@@ -187,7 +187,39 @@ static void hpet_enable_int(void)
	hpet_legacy_int_enabled = 1;
}

static void hpet_set_mode(enum clock_event_mode mode,
static void hpet_legacy_clockevent_register(void)
{
	uint64_t hpet_freq;

	/* Start HPET legacy interrupts */
	hpet_enable_legacy_int();

	/*
	 * The period is a femto seconds value. We need to calculate the
	 * scaled math multiplication factor for nanosecond to hpet tick
	 * conversion.
	 */
	hpet_freq = 1000000000000000ULL;
	do_div(hpet_freq, hpet_period);
	hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
				      NSEC_PER_SEC, 32);
	/* Calculate the min / max delta */
	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
							   &hpet_clockevent);
	hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
							   &hpet_clockevent);

	/*
	 * Start hpet with the boot cpu mask and make it
	 * global after the IO_APIC has been initialized.
	 */
	hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
	clockevents_register_device(&hpet_clockevent);
	global_clock_event = &hpet_clockevent;
	printk(KERN_DEBUG "hpet clockevent registered\n");
}

static void hpet_legacy_set_mode(enum clock_event_mode mode,
			  struct clock_event_device *evt)
{
	unsigned long cfg, cmp, now;
@@ -228,12 +260,12 @@ static void hpet_set_mode(enum clock_event_mode mode,
		break;

	case CLOCK_EVT_MODE_RESUME:
		hpet_enable_int();
		hpet_enable_legacy_int();
		break;
	}
}

static int hpet_next_event(unsigned long delta,
static int hpet_legacy_next_event(unsigned long delta,
			   struct clock_event_device *evt)
{
	unsigned long cnt;
@@ -273,58 +305,11 @@ static struct clocksource clocksource_hpet = {
#endif
};

/*
 * Try to setup the HPET timer
 */
int __init hpet_enable(void)
static int hpet_clocksource_register(void)
{
	unsigned long id;
	uint64_t hpet_freq;
	u64 tmp, start, now;
	cycle_t t1;

	if (!is_hpet_capable())
		return 0;

	hpet_set_mapping();

	/*
	 * Read the period and check for a sane value:
	 */
	hpet_period = hpet_readl(HPET_PERIOD);
	if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
		goto out_nohpet;

	/*
	 * The period is a femto seconds value. We need to calculate the
	 * scaled math multiplication factor for nanosecond to hpet tick
	 * conversion.
	 */
	hpet_freq = 1000000000000000ULL;
	do_div(hpet_freq, hpet_period);
	hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
				      NSEC_PER_SEC, 32);
	/* Calculate the min / max delta */
	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
							   &hpet_clockevent);
	hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
							   &hpet_clockevent);

	/*
	 * Read the HPET ID register to retrieve the IRQ routing
	 * information and the number of channels
	 */
	id = hpet_readl(HPET_ID);

#ifdef CONFIG_HPET_EMULATE_RTC
	/*
	 * The legacy routing mode needs at least two channels, tick timer
	 * and the rtc emulation channel.
	 */
	if (!(id & HPET_ID_NUMBER))
		goto out_nohpet;
#endif

	/* Start the counter */
	hpet_start_counter();

@@ -346,7 +331,7 @@ int __init hpet_enable(void)
	if (t1 == read_hpet()) {
		printk(KERN_WARNING
		       "HPET counter not counting. HPET disabled\n");
		goto out_nohpet;
		return -ENODEV;
	}

	/* Initialize and register HPET clocksource
@@ -367,15 +352,48 @@ int __init hpet_enable(void)

	clocksource_register(&clocksource_hpet);

	if (id & HPET_ID_LEGSUP) {
		hpet_enable_int();
	return 0;
}

/*
		 * Start hpet with the boot cpu mask and make it
		 * global after the IO_APIC has been initialized.
 * Try to setup the HPET timer
 */
		hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
		clockevents_register_device(&hpet_clockevent);
		global_clock_event = &hpet_clockevent;
int __init hpet_enable(void)
{
	unsigned long id;

	if (!is_hpet_capable())
		return 0;

	hpet_set_mapping();

	/*
	 * Read the period and check for a sane value:
	 */
	hpet_period = hpet_readl(HPET_PERIOD);
	if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
		goto out_nohpet;

	/*
	 * Read the HPET ID register to retrieve the IRQ routing
	 * information and the number of channels
	 */
	id = hpet_readl(HPET_ID);

#ifdef CONFIG_HPET_EMULATE_RTC
	/*
	 * The legacy routing mode needs at least two channels, tick timer
	 * and the rtc emulation channel.
	 */
	if (!(id & HPET_ID_NUMBER))
		goto out_nohpet;
#endif

	if (hpet_clocksource_register())
		goto out_nohpet;

	if (id & HPET_ID_LEGSUP) {
		hpet_legacy_clockevent_register();
		return 1;
	}
	return 0;