forked from Minki/linux
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
This commit is contained in:
commit
80e77644ef
@ -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;
|
||||
lapic_timer_frequency);
|
||||
/*
|
||||
* 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);
|
||||
|
Loading…
Reference in New Issue
Block a user