Skip to content

Commit

Permalink
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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
  • Loading branch information
torvalds committed May 6, 2019
2 parents a0e928e + 6eb4f08 commit 80e7764
Showing 1 changed file with 31 additions and 26 deletions.
57 changes: 31 additions & 26 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 80e7764

Please sign in to comment.