Commit 80e77644 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 apic update from Ingo Molnar:
 "A single commit which unifies the unnecessarily diverged
  implementations of APIC timer initialization. As a result the
  max_delta parameter is now consistently taken into account"

* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/apic: Unify duplicated local apic timer clockevent initialization
parents a0e928ed 6eb4f082
Loading
Loading
Loading
Loading
+31 −26
Original line number Diff line number Diff line
@@ -802,6 +802,24 @@ calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
	return 0;
}

static int __init lapic_init_clockevent(void)
{
	if (!lapic_timer_frequency)
		return -1;

	/* Calculate the scaled math multiplication factor */
	lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
					TICK_NSEC, lapic_clockevent.shift);
	lapic_clockevent.max_delta_ns =
		clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
	lapic_clockevent.max_delta_ticks = 0x7FFFFFFF;
	lapic_clockevent.min_delta_ns =
		clockevent_delta2ns(0xF, &lapic_clockevent);
	lapic_clockevent.min_delta_ticks = 0xF;

	return 0;
}

static int __init calibrate_APIC_clock(void)
{
	struct clock_event_device *levt = this_cpu_ptr(&lapic_events);
@@ -810,25 +828,21 @@ static int __init calibrate_APIC_clock(void)
	long delta, deltatsc;
	int pm_referenced = 0;

	/**
	 * check if lapic timer has already been calibrated by platform
	 * specific routine, such as tsc calibration code. if so, we just fill
	if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
		return 0;

	/*
	 * Check if lapic timer has already been calibrated by platform
	 * specific routine, such as tsc calibration code. If so just fill
	 * in the clockevent structure and return.
	 */

	if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
		return 0;
	} else if (lapic_timer_frequency) {
	if (!lapic_init_clockevent()) {
		apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
			    lapic_timer_frequency);
		lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
					TICK_NSEC, lapic_clockevent.shift);
		lapic_clockevent.max_delta_ns =
			clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
		lapic_clockevent.max_delta_ticks = 0x7FFFFF;
		lapic_clockevent.min_delta_ns =
			clockevent_delta2ns(0xF, &lapic_clockevent);
		lapic_clockevent.min_delta_ticks = 0xF;
		/*
		 * Direct calibration methods must have an always running
		 * local APIC timer, no need for broadcast timer.
		 */
		lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
		return 0;
	}
@@ -869,17 +883,8 @@ static int __init calibrate_APIC_clock(void)
	pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
					&delta, &deltatsc);

	/* Calculate the scaled math multiplication factor */
	lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
				       lapic_clockevent.shift);
	lapic_clockevent.max_delta_ns =
		clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
	lapic_clockevent.max_delta_ticks = 0x7FFFFFFF;
	lapic_clockevent.min_delta_ns =
		clockevent_delta2ns(0xF, &lapic_clockevent);
	lapic_clockevent.min_delta_ticks = 0xF;

	lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
	lapic_init_clockevent();

	apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
	apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);